๐Ÿš€ 93K RPM์œผ๋กœ ํ™•์žฅ: SQL์—์„œ Redis๋กœ ์ฟผํ„ฐ ๊ด€๋ฆฌ ์ด๋™

๋ฐœํ–‰: (2026๋…„ 1์›” 15์ผ ์˜คํ›„ 01:41 GMT+9)
4 min read
์›๋ฌธ: Dev.to

Source: Dev.to

๋ฌด์Šจ ์ผ์ด ์žˆ์—ˆ๋‚˜์š”?

๋‹น์‹ ์ด ์ข‹์•„ํ•˜๋Š” ์•„ํ‹ฐ์ŠคํŠธ๊ฐ€ ๊ณง ์ฝ˜์„œํŠธ๋ฅผ ์—ฐ๋‹ค๊ณ  ๋ฐœํ‘œํ–ˆ๊ณ , ๊ณ ๊ฐ๋“ค์€ ํ‹ฐ์ผ“์„ ์‚ฌ๊ธฐ ์œ„ํ•ด ๋ชฐ๋ ค๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. ์ „์ž ํ‹ฐ์ผ“ํŒ… ํ”Œ๋žซํผ์€ ์˜ค๋ฅ˜๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ธฐ ์‹œ์ž‘ํ–ˆ๊ณ , ์†๋„๊ฐ€ ์‹ฌํ•˜๊ฒŒ ๋А๋ ค์กŒ์Šต๋‹ˆ๋‹ค.

๊ทผ๋ณธ ์›์ธ์€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค CPU ์‚ฌ์šฉ๋Ÿ‰์ด 100โ€ฏ%๊นŒ์ง€ ๊ธ‰๋“ฑํ•œ ๊ฒƒ์ด์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์ด๋ฒคํŠธ์˜ ํ• ๋‹น๋Ÿ‰์„ ๊ณ„์‚ฐํ•˜๋Š” ๋‹จ์ผ โ€œํ•ซโ€ ํ–‰์ด ์ง€์†์ ์œผ๋กœ ์กฐํšŒ๋˜๊ณ  ์—…๋ฐ์ดํŠธ๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ํ…Œ์ด๋ธ”์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค:

eventIdshowtimeIdquotareserved
1115,00010,000

๊ฐ ์š”์ฒญ์ด ์ด ํ–‰์„ ์ฝ๊ณ  ์“ฐ๋ฉด์„œ ๋ฝ ๊ฒฝํ•ฉ์ด ๋ฐœ์ƒํ•˜๊ณ  CPU ์ž์›์ด ๊ณ ๊ฐˆ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

ํ•ด๊ฒฐ์ฑ…

ํ• ๋‹น๋Ÿ‰ ์นด์šดํ„ฐ๋ฅผ Redis๋กœ ์ด๋™

Redis๋Š” ๋ฐ์ดํ„ฐ๋ฅผ RAM์— ์ €์žฅํ•˜๋ฏ€๋กœ ๋””์Šคํฌ ๊ธฐ๋ฐ˜ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ณด๋‹ค ํ›จ์”ฌ ๋‚ฎ์€ ์ง€์—ฐ ์‹œ๊ฐ„์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๊ฐ€์žฅ ๋‹จ์ˆœํ•œ ๊ตฌํ˜„์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ณด์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

function reserveTicket(showtimeId, amount) {
    const reserved = parseInt(redis.get('{key}'));
    if (reserved  {
        // โ€ฆorder creation logicโ€ฆ
        const result = await redis.eval(reserveLuaScript, {
            keys: ['{key}'],
            arguments: [String(amount), String(quota)],
        });
        if (result !== 1) {
            throw error('reservation failed');
        }
    });
    // โ€ฆother logicโ€ฆ
}

์นด์šดํŠธ๋ฅผ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๋‹ค์‹œ ์ €์žฅ

Redis๋Š” ์บ์‹œ์ด๋ฏ€๋กœ ๊ถŒ์œ„ ์žˆ๋Š” ์ง„์‹ค ์†Œ์Šค๋Š” ์—ฌ์ „ํžˆ ๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์›Œ์ปค๊ฐ€ Redis๋ฅผ 5์ดˆ๋งˆ๋‹ค ํด๋งํ•˜๊ณ  ํ˜„์žฌ ์นด์šดํŠธ๋ฅผ DB์— ๊ธฐ๋กํ•จ์œผ๋กœ์จ ์„ฑ๋Šฅ์„ ํฌ์ƒํ•˜์ง€ ์•Š์œผ๋ฉด์„œ ์ตœ์ข… ์ผ๊ด€์„ฑ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

๊ฒฐ๊ณผ

  • ๋ถ„๋‹น ์ฃผ๋ฌธ ์ˆ˜๊ฐ€ 5,000์—์„œ 93,240์œผ๋กœ ์ฆ๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค.
  • ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ถ€ํ•˜๊ฐ€ ํฌ๊ฒŒ ๊ฐ์†Œํ•˜์—ฌ CPU ๋ณ‘๋ชฉ ํ˜„์ƒ์ด ์‚ฌ๋ผ์กŒ์Šต๋‹ˆ๋‹ค.
  • ์‹œ์Šคํ…œ์ด ํ”ผํฌ ํ‹ฐ์ผ“ ํŒ๋งค ํŠธ๋ž˜ํ”ฝ์„ ์•ˆ์ •์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์ฃผ์š” ๊ตํ›ˆ

  • ์„ฑ๋Šฅ ๋ฌธ์ œ์˜ ์‹ค์ œ ์›์ธ์„ ์ง„๋‹จํ•˜์„ธ์š”; ์—ฌ๊ธฐ์„œ๋Š” ํ•ซ ํ–‰์ด DB ๋ฝ ๊ฒฝํ•ฉ์„ ์ผ์œผ์ผฐ์Šต๋‹ˆ๋‹ค.
  • ์‹ค์ œ ์‚ฌ์šฉ ํŒจํ„ด์— ๋งž๊ฒŒ ์‹œ์Šคํ…œ ์„ค๊ณ„๋ฅผ ์กฐ์ •ํ•˜์„ธ์š”โ€”๊ณ ์ฒ˜๋ฆฌ๋Ÿ‰ ์‹œ๋‚˜๋ฆฌ์˜ค์—์„œ๋Š” ํ•ซ ํ–‰์„ ๋ณ„๋„๋กœ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • ์นด์šดํ„ฐ๋ฅผ ์•ˆ์ „ํ•˜๊ฒŒ ๊ด€๋ฆฌํ•˜๋ ค๋ฉด ์›์ž์ ์ธ Lua ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•œ Redis(๋˜๋Š” ๋‹ค๋ฅธ ์ธโ€‘๋ฉ”๋ชจ๋ฆฌ ์Šคํ† ์–ด)๋ฅผ ํ™œ์šฉํ•˜์„ธ์š”.
  • ๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์ง„์‹ค์˜ ์›์ฒœ์œผ๋กœ ์œ ์ง€ํ•˜๊ณ , ๋‚ด๊ตฌ์„ฑ์„ ์œ„ํ•ด ๋น„๋™๊ธฐ์ ์œผ๋กœ ๋™๊ธฐํ™”ํ•˜์„ธ์š”.
Back to Blog

๊ด€๋ จ ๊ธ€

๋” ๋ณด๊ธฐ ยป

๊ธฐ์ˆ ์€ ๊ตฌ์›์ž๊ฐ€ ์•„๋‹ˆ๋ผ ์ด‰์ง„์ž๋‹ค

์™œ ์‚ฌ๊ณ ์˜ ๋ช…ํ™•์„ฑ์ด ์‚ฌ์šฉํ•˜๋Š” ๋„๊ตฌ๋ณด๋‹ค ๋” ์ค‘์š”ํ•œ๊ฐ€? Technology๋Š” ์ข…์ข… ๋งˆ๋ฒ• ์Šค์œ„์น˜์ฒ˜๋Ÿผ ์ทจ๊ธ‰๋œ๋‹คโ€”์ผœ๊ธฐ๋งŒ ํ•˜๋ฉด ๋ชจ๋“  ๊ฒƒ์ด ๊ฐœ์„ ๋œ๋‹ค. ์ƒˆ๋กœ์šด software, ...

์—…๊ณ„ ์„ค๋ฌธ์กฐ์‚ฌ: ์ฝ”๋”ฉ์€ ๋นจ๋ผ์ง€๊ณ  ๋””๋ฒ„๊น…์€ ๋А๋ ค์ง„๋‹ค

AIโ€‘์ง€์› ํ”„๋กœ๊ทธ๋ž˜๋ฐ: ๊ฐœ๋ฐœ ๋ฐ ๋””๋ฒ„๊น… ์‹œ๊ฐ„์˜ ๋ณ€ํ™” ์ธ๊ณต์ง€๋Šฅ์˜ ๊ธ‰์†ํ•œ ๋ฐœ์ „๊ณผ ํ•จ๊ป˜, GitHub์™€ ๊ฐ™์€ AIโ€‘์ง€์› ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋„๊ตฌ๊ฐ€โ€ฆ

์—์ด์ „ํ‹ฑ ์ฝ”๋”ฉ์— ์ž…๋ฌธํ•˜๊ธฐ

Copilot Agent์™€์˜ ๊ฒฝํ—˜ ๋‚˜๋Š” ์ฃผ๋กœ GitHub Copilot์„ ์‚ฌ์šฉํ•ด ์ธ๋ผ์ธ ํŽธ์ง‘๊ณผ PR ๋ฆฌ๋ทฐ๋ฅผ ์ˆ˜ํ–‰ํ–ˆ์œผ๋ฉฐ, ๋Œ€๋ถ€๋ถ„์˜ ์‚ฌ๊ณ ๋Š” ๋‚ด ๋จธ๋ฆฌ๋กœ ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ตœ๊ทผ ๋‚˜๋Š” t...

npm Classic Tokens ์‚ฌ๋ผ์ง: ๋ฐฐํฌ๋ฅผ ์ง€์†ํ•˜๋Š” ๋‘ ๊ฐ€์ง€ ์ € ์œ ์ง€๋ณด์ˆ˜ ๋ฐฉ๋ฒ•

๋ฐฐ๊ฒฝ: npm์ด ์ตœ๊ทผ ํด๋ž˜์‹ npm ํ† ํฐ์ด deprecated(์‚ฌ์šฉ ์ค‘๋‹จ)๋˜๊ณ  revoked(ํ๊ธฐ)๋œ๋‹ค๊ณ  ๋ฐœํ‘œํ–ˆ์Šต๋‹ˆ๋‹ค. ๋ชจ๋“  ์‚ฌ์šฉ์ž๋Š” expiration์ด ํฌํ•จ๋œ granular tokens๋กœ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.