30 ๋ฃจ๋ธ”์˜ ๋‘๋‡Œ + VPS =?

์ข‹์€ ํŽœ๊ณผ ๋ฉ”๋ชจ์žฅ, ๋พฐ์กฑํ•œ ์—ฐํ•„, ํŽธ์•ˆํ•œ ๋งˆ์šฐ์Šค, ์—ฌ๋ถ„์˜ ์ „์„  ๋ช‡ ๊ฐœ ๋“ฑ ํ•„์š”ํ•œ ์ž‘์€ ๊ฒƒ๋“ค์ด ๋ชจ๋‘ ์ค€๋น„๋˜์–ด ์žˆ์œผ๋ฉด ์ •๋ง ์ข‹์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ˆˆ์— ๋„์ง€ ์•Š๋Š” ๊ฒƒ๋“ค์€ ๊ด€์‹ฌ์„ ๋Œ์ง€ ๋ชปํ•˜์ง€๋งŒ ์‚ถ์— ํŽธ์•ˆํ•จ์„ ๋”ํ•ด์ค๋‹ˆ๋‹ค. ๊ธด ์Šคํฌ๋ฆฐ์ƒท, ์‚ฌ์ง„ ํฌ๊ธฐ ์ถ•์†Œ, ๊ฐœ์ธ ์žฌ์ • ๊ณ„์‚ฐ, ์‚ฌ์ „, ๋ฒˆ์—ญ๊ธฐ, ๋ณ€ํ™˜๊ธฐ ๋“ฑ ๋‹ค์–‘ํ•œ ๋ชจ๋ฐ”์ผ ๋ฐ ๋ฐ์Šคํฌํ†ฑ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์ž…๋‹ˆ๋‹ค. ํ˜น์‹œ ๊ฐ–๊ณ  ๊ณ„์‹œ๋‚˜์š”? VPS - ์ €๋ ดํ•˜๊ณ  ํ•ญ์ƒ ์†์— ๋“ค๊ณ  ๋งŽ์€ ์ด์ ์„ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ์•„๋‹ˆ์š”, ํšŒ์‚ฌ์— ์žˆ๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์ž์‹ ๋งŒ์˜ "์ฃผ๋จธ๋‹ˆ"๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. 2019๋…„์—๋Š” ์ž‘์€ VPS๊ฐ€ ์—†์œผ๋ฉด ๊ฐ•์˜ํ•  ๋•Œ ํ‰์†Œ ๋งŒ๋…„ํ•„์ด ์—†๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ์™ ์ง€ ์Šฌํ”„๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค. ์™œ ์Šฌํผํ•ฉ๋‹ˆ๊นŒ? ์—ฌ๋ฆ„์ด๋‹ค. ์—ฌ๋ฆ„์€ ์–ด๋•Œ์š”? IT ์ „๋ฌธ๊ฐ€๋ฅผ ์œ„ํ•œ ์—ฌ๋ฆ„: ์ง‘์— ์•‰์•„ ํ›„ํšŒ ์—†์ด ์ข‹์•„ํ•˜๋Š” ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•˜์„ธ์š”. ์ผ๋ฐ˜์ ์œผ๋กœ ์šฐ๋ฆฌ๋Š” ๊ทธ๊ฒƒ์„ ์ƒ๊ฐํ•˜๊ณ  ํ•ด๋ƒˆ์Šต๋‹ˆ๋‹ค.

30 ๋ฃจ๋ธ”์˜ ๋‘๋‡Œ + VPS =?
๊ณต์‚ฐ์ฃผ์˜๊ฐ€ ๋„๋ž˜ํ–ˆ์Šต๋‹ˆ๋‹ค, ๋™์ง€๋“ค.

๊ทธ๋Š” ๊ทธ๋Ÿฐ ์‚ฌ๋žŒ์ž…๋‹ˆ๋‹ค. XNUMX ๋Œ€์šฉ VPS

์šฐ๋ฆฌ๋Š” ์ €๋ ดํ•œ VPS๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š์€ ์ด์œ ์— ๋Œ€ํ•ด 3~4๋…„ ์ „์— ์“ด ๊ฒฝ์Ÿ์‚ฌ์™€ ์‚ฌ์šฉ์ž์˜ ๋งŽ์€ ๊ธฐ์‚ฌ๋ฅผ ์ฝ์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡๋‹ค๋ฉด "30ํŽ˜๋‹ˆ์šฉ" VPS๋Š” ์ˆœ์ˆ˜ํ•œ ๋งˆ์ผ€ํŒ…์ด์—ˆ๊ณ  ์ •์ƒ์ ์ธ ์—…๋ฌด ๊ธฐํšŒ๋ฅผ ์ œ๊ณตํ•  ์ˆ˜ ์—†์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์‹œ๋Œ€๊ฐ€ ๋ณ€ํ•˜๊ณ  ๊ฐ€์ƒ ๋ฆฌ์†Œ์Šค ๋น„์šฉ์ด ์ ์  ๋‚ฎ์•„์ง€๊ณ  ์žˆ์œผ๋ฉฐ ํ•œ ๋‹ฌ์— XNUMX๋ฃจ๋ธ”์˜ ๋น„์šฉ์œผ๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์„œ๋น„์Šค๋ฅผ ์ œ๊ณตํ•  ์ค€๋น„๊ฐ€ ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

  • ํ”„๋กœ์„ธ์„œ: Intel Xeon 2GHz(1์ฝ”์–ด)
  • Linux ์‹œ์Šคํ…œ(Debian, Ubuntu, CentOS ์ค‘์—์„œ ์„ ํƒ ๊ฐ€๋Šฅ)
  • ์ „์šฉ IPv1 ์ฃผ์†Œ 4๊ฐœ
  • ๋น ๋ฅธ ์—”ํ„ฐํ”„๋ผ์ด์ฆˆ๊ธ‰ SSD ๋“œ๋ผ์ด๋ธŒ์— 10GB์˜ ๋ฐ์ดํ„ฐ ์ €์žฅ ๊ณต๊ฐ„ ์ œ๊ณต
  • ๋žจ: 512MB
  • ์ดˆ๋‹น ์ฒญ๊ตฌ
  • ๋ฌด์ œํ•œ ํŠธ๋ž˜ํ”ฝ

๊ด€์„ธ์—๋Š” ์ถ”๊ฐ€ ๊ธฐ์ˆ  ์ œํ•œ ์‚ฌํ•ญ์ด ์ ์šฉ๋ฉ๋‹ˆ๋‹ค. ํŽ˜์ด์ง€ ์šฐ๋ฆฌ์˜ ๋ฉ‹์ง„ ์ œ์•ˆ - 30 ๋ฃจ๋ธ”์˜ VPS. 

์ด ๊ฐ€์ƒ ์„œ๋ฒ„๋Š” ๋ˆ„๊ตฌ์—๊ฒŒ ์ ํ•ฉํ•ฉ๋‹ˆ๊นŒ? ์ดˆ๋ณด์ž, ์—ด์„ฑ ํŒฌ, ์ˆ™๋ จ๋œ ๊ฐœ๋ฐœ์ž, DIY ํŒฌ, ์‹ฌ์ง€์–ด ์ผ๋ถ€ ํšŒ์‚ฌ๊นŒ์ง€ ๊ฑฐ์˜ ๋ชจ๋“  ์‚ฌ๋žŒ์ด ๊ทธ๋ ‡์Šต๋‹ˆ๋‹ค.

์ด VPS๋Š” ์–ด๋””์— ์ ํ•ฉํ•ฉ๋‹ˆ๊นŒ?

์šฐ๋ฆฌ๋Š” Habr์˜ ๋…์ž๋“ค์ด ์ด ๊ตฌ์„ฑ์„ ์‚ฌ์šฉํ•˜๋Š” ์ž์‹ ๋งŒ์˜ ๋ฐฉ๋ฒ•์„ ํ™•์‹คํžˆ ์ฐพ์„ ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜์ง€๋งŒ, ์šฐ๋ฆฌ๋Š” ์šฐ๋ฆฌ๊ฐ€ ์„ ํƒํ•œ ์•„์ด๋””์–ด๋ฅผ ์ˆ˜์ง‘ํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ ํ•„์š”ํ•˜์ง€๋งŒ ๋‚จ์ž๋“ค์ด ๋ชจ๋ฅธ๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ์š”?

  • ๊ฐ„๋‹จํ•œ ์›น์‚ฌ์ดํŠธ, ํฌํŠธํด๋ฆฌ์˜ค, ์ด๋ ฅ์„œ ๋“ฑ์„ ์ฝ”๋“œ๋กœ ๋ฐฐ์น˜ํ•˜์„ธ์š”. ๋ฌผ๋ก  ๊ท€ํ•˜๊ฐ€ ์ง์ ‘ ๋””์ž์ธํ•œ ์›น์‚ฌ์ดํŠธ๋Š” ๊ณ ์šฉ์ฃผ์—๊ฒŒ ๊ธ์ •์ ์ธ ์ธ์ƒ์„ ์ค๋‹ˆ๋‹ค. VPS์— ๋ฐฐ์น˜ํ•˜๊ณ  ์ผ๋ฐ˜ ํ˜ธ์ŠคํŒ… ์ œ๊ณต์—…์ฒด์˜ ์ง์›์ด ์•„๋‹Œ ์‚ฌ์ดํŠธ์˜ ๋ณด์•ˆ๊ณผ ์•ˆ์ •์„ฑ์„ ์ง์ ‘ ์ฑ…์ž„์ ธ์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • ๊ต์œก ๋ชฉ์ ์œผ๋กœ VPS๋ฅผ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค. ํ”„๋กœ์ ํŠธ๋ฅผ ํ˜ธ์ŠคํŒ…ํ•˜๊ณ , ์„œ๋ฒ„ ๋ฐ ์„œ๋ฒ„ ์šด์˜ ์ฒด์ œ์˜ ๊ธฐ๋Šฅ์„ ์—ฐ๊ตฌํ•˜๊ณ , DNS๋ฅผ ์‹คํ—˜ํ•˜๊ณ , ์†Œ๊ทœ๋ชจ ๊ต์œก ์‚ฌ์ดํŠธ๋ฅผ ์ˆ˜์ •ํ•˜์‹ญ์‹œ์˜ค.
  • ์ „ํ™” ํ†ต์‹ ์šฉ. ๋•Œ๋กœ๋Š” ๊ฐœ์ธ ๊ธฐ์—…๊ฐ€, ํ”„๋ฆฌ๋žœ์„œ ๋˜๋Š” ์•„์ฃผ ์ž‘์€ ํšŒ์‚ฌ๊ฐ€ IP ํ…”๋ ˆํฌ๋‹ˆ๋ฅผ ์ ˆ์‹คํžˆ ํ•„์š”๋กœ ํ•˜๋Š”๋ฐ ๋ฐ”๋กœ ์ด ํ…”๋ ˆํฌ๋‹ˆ ์šด์˜์ž๋Š” ๋งค์šฐ ํƒ์š•์Šค๋Ÿฝ์Šต๋‹ˆ๋‹ค. ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค. ์„œ๋ฒ„๋ฅผ ๊ฐ€์ ธ์˜ค๊ณ , IP โ€‹โ€‹์ „ํ™” ํ†ต์‹  ์‚ฌ์—…์ž๋กœ๋ถ€ํ„ฐ ๋ฒˆํ˜ธ๋ฅผ ๊ตฌ๋งคํ•˜๊ณ , ๊ฐ€์ƒ PBX๋ฅผ ์„ค์ •ํ•˜๊ณ  (ํ•„์š”ํ•œ ๊ฒฝ์šฐ) ๋‚ด๋ถ€ ๋ฒˆํ˜ธ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์ ˆ๊ฐ ํšจ๊ณผ๋Š” ์—„์ฒญ๋‚ฉ๋‹ˆ๋‹ค.
  • ์„œ๋ฒ„๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ํ…Œ์ŠคํŠธํ•˜์„ธ์š”.
  • ์Šค๋งˆํŠธ ํ™ˆ ์‹œ์Šคํ…œ ์„ผ์„œ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ œ์–ดํ•˜๊ณ  ์ˆ˜์ง‘ํ•˜๋Š” ๋“ฑ DIY ์‹คํ—˜์— ์„œ๋ฒ„๋ฅผ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค.
  • ์ด๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ํŠน์ดํ•œ ๋ฐฉ๋ฒ•์€ ๊ฐ€์ƒ ๊ฑฐ๋ž˜์†Œ ๊ฑฐ๋ž˜ ๋ณด์กฐ์›์ธ ๊ฑฐ๋ž˜ ๋กœ๋ด‡์„ ์„œ๋ฒ„์— ๋ฐฐ์น˜ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ท€ํ•˜๋Š” ์„œ๋ฒ„์˜ ์•ˆ์ •์„ฑ๊ณผ ๋ณด์•ˆ์— ๋Œ€ํ•ด ์ „์ ์œผ๋กœ ์ฑ…์ž„์„ ์ง€๊ฒŒ ๋˜๋ฉฐ, ์ด๋Š” ๊ท€ํ•˜๊ฐ€ ์ฃผ์‹ ์‹œ์žฅ ๊ฑฐ๋ž˜๋ฅผ ์œ„ํ•œ ํ†ต์ œ๋œ ๋„๊ตฌ๋ฅผ ๋ฐ›๊ฒŒ ๋œ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ๊ธ€์Ž„์š”, ํ˜น์‹œ ๊ด€์‹ฌ์žˆ๊ฑฐ๋‚˜ ๊ณ„ํšํ•˜๊ณ  ๊ณ„์‹œ๋‹ค๋ฉด :)

๊ธฐ์—… ์˜์—ญ์—๋Š” ์ด๋Ÿฌํ•œ VPS์— ๋Œ€ํ•œ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฏธ ์–ธ๊ธ‰ํ•œ ์ „ํ™” ์„œ๋น„์Šค ์™ธ์—๋„ ๋ช‡ ๊ฐ€์ง€ ํฅ๋ฏธ๋กœ์šด ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด:

  • ์˜ˆ๋ฅผ ๋“ค์–ด FTP๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฉ€๋ฆฌ ๋–จ์–ด์ ธ ์žˆ๋Š” ์ง์›์ด ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ๋Š” ์†Œ๊ทœ๋ชจ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€ ์ •๋ณด๋ฅผ ๋ฐฐ์น˜ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์ƒˆ๋กœ์šด ๋ถ„์„, ์˜์—… ์‚ฌ์›์„ ์œ„ํ•œ ์—…๋ฐ์ดํŠธ๋œ ๊ตฌ์„ฑ, ํ”„๋ ˆ์  ํ…Œ์ด์…˜ ๋“ฑ์„ ๋งค์šฐ ๋น ๋ฅด๊ฒŒ ๊ตํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์†Œํ”„ํŠธ์›จ์–ด๋‚˜ ๋ฏธ๋””์–ด๋ฅผ ์‹œ์—ฐํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ์ž๋‚˜ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์ž„์‹œ ์•ก์„ธ์Šค ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•ฉ๋‹ˆ๋‹ค.

30๋ฃจ๋ธ”์˜ VPS ํ…Œ์ŠคํŠธ ๋“œ๋ผ์ด๋ธŒ - ์™„๋ฃŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค

30 ๋ฃจ๋ธ”์€ ๋„ˆ๋ฌด ์ ๊ธฐ ๋•Œ๋ฌธ์— ์ง€๋ถˆํ•˜๊ณ  ํ…Œ์ŠคํŠธํ•˜๊ธฐ ์œ„ํ•ด ์นด๋“œ๋ฅผ ๊บผ๋‚ด๊ณ  ์‹ถ์ง€๋„ ์•Š์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋„ ๋•Œ๋กœ๋Š” ๋„ˆ๋ฌด ๊ฒŒ์œผ๋ฅด์ง€๋งŒ ์ด๋ฒˆ์—๋Š” ๋‹น์‹ ์„ ์œ„ํ•ด ๋ชจ๋“  ๊ฒƒ์„ ํ•ด๋ƒˆ์Šต๋‹ˆ๋‹ค. ์„œ๋ฒ„๋ฅผ ์ „ํˆฌ์— ํˆฌ์ž…ํ•˜๊ธฐ ์ „์— ์šฐ๋ฆฌ๋Š” ๋ชจ๋“  ์„ธ๋ถ€ ์‚ฌํ•ญ์„ ํ™•์ธํ•˜๊ณ  ์ด ๊ฐ€๊ฒฉ์œผ๋กœ ์„œ๋ฒ„๊ฐ€ ๋ฌด์—‡์„ ํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ์•Œ์•„๋ณด๊ธฐ ์œ„ํ•ด ํ…Œ์ŠคํŠธ๋ฅผ ์‹ค์‹œํ–ˆ์Šต๋‹ˆ๋‹ค. ๋” ํฅ๋ฏธ๋กญ๊ฒŒ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ๊ทน๋‹จ์ ์ธ ์š”์†Œ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  ๋ฐ€๋„์™€ ๋ถ€ํ•˜๊ฐ€ ์šฐ๋ฆฌ๊ฐ€ ์„ค์ •ํ•œ ๊ฐ’์„ ์ดˆ๊ณผํ•˜๋Š” ๊ฒฝ์šฐ ์ด ๊ตฌ์„ฑ์ด ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•˜๋Š”์ง€ ํ™•์ธํ–ˆ์Šต๋‹ˆ๋‹ค. 

ํ˜ธ์ŠคํŠธ๋Š” ํ”„๋กœ์„ธ์„œ์—์„œ ๋‹ค์–‘ํ•œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๊ณ  ๋””์Šคํฌ ํ•˜์œ„ ์‹œ์Šคํ…œ์„ ์ ๊ทน์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ์—ฌ๋Ÿฌ ๊ฐ€์ƒ ๋จธ์‹ ์˜ ๋ถ€ํ•˜๋ฅผ ๋ฐ›๊ณ  ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ๋ชฉํ‘œ๋Š” ๋†’์€ ๋ฐ€๋„์˜ ๋ฐฐ์น˜์™€ ์ „ํˆฌ์™€ ๋น„์Šทํ•˜๊ฑฐ๋‚˜ ๋” ํฐ ๋ถ€ํ•˜๋ฅผ ์‹œ๋ฎฌ๋ ˆ์ด์…˜ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ง€์†์ ์ธ ๋กœ๋“œ ์™ธ์—๋„ sysbench๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•ฉ์„ฑ ๋ฉ”ํŠธ๋ฆญ์„ ์ˆ˜์ง‘ํ•˜๋Š” ๊ฐ€์ƒ ๋จธ์‹  3๋Œ€(ํ‰๊ท  ๊ฒฐ๊ณผ๋Š” ์•„๋ž˜์— ๋‚˜์™€ ์žˆ์Œ)์™€ ์ถ”๊ฐ€ ๋กœ๋“œ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฐ€์ƒ ๋จธ์‹  50๋Œ€๋ฅผ ์„ค์น˜ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋ชจ๋“  ํ…Œ์ŠคํŠธ ๊ฐ€์ƒ ๋จธ์‹ ์€ ๋™์ผํ•œ ๊ตฌ์„ฑ(์ฝ”์–ด 1๊ฐœ, RAM 512GB, SSD 10GB)์„ ๊ฐ€์กŒ๊ณ  ํ‘œ์ค€ debian 9.6 ์ด๋ฏธ์ง€๊ฐ€ RUVDS ์‚ฌ์šฉ์ž์—๊ฒŒ ์ œ๊ณต๋˜๋Š” ์šด์˜ ์ฒด์ œ๋กœ ์„ ํƒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

ํ•˜์ค‘์€ ์ „ํˆฌ์™€ ๋น„์Šทํ•œ ์„ฑ๊ฒฉ๊ณผ ๊ทœ๋ชจ๋กœ ์‹œ๋ฎฌ๋ ˆ์ด์…˜๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

  • ์ผ๋ถ€ ๊ฐ€์ƒ ๋จธ์‹ ์ด ๋‚ฎ์€ ๋กœ๋“œ๋กœ ์‹œ์ž‘๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
  • ์ผ๋ถ€ ์‹œ์Šคํ…œ์€ ํ”„๋กœ์„ธ์„œ์˜ ๋กœ๋“œ๋ฅผ ์‹œ๋ฎฌ๋ ˆ์ด์…˜ํ•˜๋Š” ํ…Œ์ŠคํŠธ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‹คํ–‰ํ–ˆ์Šต๋‹ˆ๋‹ค(์œ ํ‹ธ๋ฆฌํ‹ฐ ์‚ฌ์šฉ). ์ŠคํŠธ๋ ˆ์Šค)
  • ๊ฐ€์ƒ ๋จธ์‹ ์˜ ๋‚˜๋จธ์ง€ ๋ถ€๋ถ„์—์„œ๋Š” pv๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฏธ๋ฆฌ ์ค€๋น„๋œ ๋ฐ์ดํ„ฐ์—์„œ ์ œํ•œ์ด ์„ค์ •๋œ ๋””์Šคํฌ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณต์‚ฌํ•˜๊ธฐ ์œ„ํ•ด dd๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‹คํ–‰ํ–ˆ์Šต๋‹ˆ๋‹ค(์˜ˆ์ œ๋Š” ๋ณผ ์ˆ˜ ์žˆ์Œ). ์—ฌ๊ธฐ์— ะธ ์—ฌ๊ธฐ์—).

๋˜ํ•œ ๊ธฐ์–ตํ•˜์‹œ๊ฒ ์ง€๋งŒ ์šฐ๋ฆฌ์—๊ฒŒ๋Š” ์ข…ํ•ฉ ์ง€ํ‘œ๋ฅผ ์ˆ˜์ง‘ํ•˜๋Š” ์„ธ ๋Œ€์˜ ๊ธฐ๊ณ„๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

๊ฐ ์‹œ์Šคํ…œ์—์„œ ์Šคํฌ๋ฆฝํŠธ๋Š” 15๋ถ„๋งˆ๋‹ค ์ฃผ๊ธฐ์ ์œผ๋กœ ์‹คํ–‰๋˜์–ด ํ”„๋กœ์„ธ์„œ, ๋ฉ”๋ชจ๋ฆฌ ๋ฐ ๋””์Šคํฌ์— ๋Œ€ํ•œ ํ‘œ์ค€ sysbench ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ–ˆ์Šต๋‹ˆ๋‹ค.

sysbench.sh ์Šคํฌ๋ฆฝํŠธ

#!/bin/bash
date +"%Y-%m-%d %H:%M:%S" >> /root/sysbench/results.txt
sysbench --test=cpu run >> /root/sysbench/results.txt
sysbench --test=memory run >> /root/sysbench/results.txt
sysbench --test=fileio --file-test-mode=seqwr run >> /root/sysbench/results.txt
sysbench --test=fileio --file-test-mode=seqrd run >> /root/sysbench/results.txt
sysbench --test=fileio --file-test-mode=rndrw run >> /root/sysbench/results.txt

๊ฒฐ๊ณผ๋Š” ํŽธ์˜๋ฅผ ์œ„ํ•ด sysbench ํ˜•์‹์œผ๋กœ ํ‘œ์‹œ๋˜์ง€๋งŒ ์ „์ฒด ํ…Œ์ŠคํŠธ ๊ธฐ๊ฐ„์˜ ํ‰๊ท ๊ฐ’์€ ๋ชจ๋“  ์‹œ์Šคํ…œ์—์„œ ๊ฐ€์ ธ์˜จ ๊ฒƒ์ด๋ฏ€๋กœ ๊ฒฐ๊ณผ๋Š” ์—ฌ๊ธฐ์—์„œ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Sysbanch-avg.txtsysbench 0.4.12: multi-threaded system evaluation benchmark

Running the test with following options:
Number of threads: 1

Doing CPU performance benchmark

Threads started!
Done.

Maximum prime number checked in CPU test: 10000

Test execution summary:
total time: 19.2244s
total number of events: 10000
total time taken by event execution: 19.2104
per-request statistics:
min: 1.43ms
avg: 1.92ms
max: 47.00ms
approx. 95 percentile: 3.02ms

Threads fairness:
events (avg/stddev): 10000.0000/0.00
execution time (avg/stddev): 19.2104/0.00

sysbench 0.4.12: multi-threaded system evaluation benchmark

Running the test with following options:
Number of threads: 1

Doing memory operations speed test
Memory block size: 1K

Memory transfer size: 102400M

Memory operations type: write
Memory scope type: global
Threads started!
Done.

Operations performed: 104857600 (328001.79 ops/sec)

102400.00 MB transferred (320.32 MB/sec)

Test execution summary:
total time: 320.9155s
total number of events: 104857600
total time taken by event execution: 244.8399
per-request statistics:
min: 0.00ms
avg: 0.00ms
max: 139.41ms
approx. 95 percentile: 0.00ms

Threads fairness:
events (avg/stddev): 104857600.0000/0.00
execution time (avg/stddev): 244.8399/0.00

sysbench 0.4.12: multi-threaded system evaluation benchmark

Running the test with following options:
Number of threads: 1

Extra file open flags: 0
128 files, 16Mb each
2Gb total file size
Block size 16Kb
Periodic FSYNC enabled, calling fsync() each 100 requests.
Calling fsync() at the end of test, Enabled.
Using synchronous I/O mode
Doing sequential write (creation) test
Threads started!
Done.

Operations performed: 0 Read, 131072 Write, 128 Other = 131200 Total
Read 0b Written 2Gb Total transferred 2Gb (320.1Mb/sec)
20251.32 Requests/sec executed

Test execution summary:
total time: 6.9972s
total number of events: 131072
total time taken by event execution: 5.2246
per-request statistics:
min: 0.01ms
avg: 0.04ms
max: 96.76ms
approx. 95 percentile: 0.03ms

Threads fairness:
events (avg/stddev): 131072.0000/0.00
execution time (avg/stddev): 5.2246/0.00

sysbench 0.4.12: multi-threaded system evaluation benchmark

Running the test with following options:
Number of threads: 1

Extra file open flags: 0
128 files, 16Mb each
2Gb total file size
Block size 16Kb
Periodic FSYNC enabled, calling fsync() each 100 requests.
Calling fsync() at the end of test, Enabled.
Using synchronous I/O mode
Doing sequential read test
Threads started!
Done.

Operations performed: 131072 Read, 0 Write, 0 Other = 131072 Total
Read 2Gb Written 0b Total transferred 2Gb (91.32Mb/sec)
5844.8 Requests/sec executed

Test execution summary:
total time: 23.1054s
total number of events: 131072
total time taken by event execution: 22.9933
per-request statistics:
min: 0.00ms
avg: 0.18ms
max: 295.75ms
approx. 95 percentile: 0.77ms

Threads fairness:
events (avg/stddev): 131072.0000/0.00
execution time (avg/stddev): 22.9933/0.00

sysbench 0.4.12: multi-threaded system evaluation benchmark

Running the test with following options:
Number of threads: 1

Extra file open flags: 0
128 files, 16Mb each
2Gb total file size
Block size 16Kb
Number of random requests for random IO: 10000
Read/Write ratio for combined random IO test: 1.50
Periodic FSYNC enabled, calling fsync() each 100 requests.
Calling fsync() at the end of test, Enabled.
Using synchronous I/O mode
Doing random r/w test
Threads started!
Done.

Operations performed: 6000 Read, 4000 Write, 12800 Other = 22800 Total
Read 93.75Mb Written 62.5Mb Total transferred 156.25Mb (1341.5Kb/sec)
85.61 Requests/sec executed

Test execution summary:
total time: 152.9786s
total number of events: 10000
total time taken by event execution: 14.1879
per-request statistics:
min: 0.01ms
avg: 1.41ms
max: 210.22ms
approx. 95 percentile: 4.95ms

Threads fairness:
events (avg/stddev): 10000.0000/0.00
execution time (avg/stddev): 14.1879/0.00

๊ฒฐ๊ณผ๋Š” ์•”์‹œ์ ์ด์ง€๋งŒ ์—ฌ์ „ํžˆ QoS๋กœ ๊ฐ„์ฃผ๋˜์–ด์„œ๋Š” ์•ˆ ๋ฉ๋‹ˆ๋‹ค. 

์ถ”๊ฐ€ ๋ถ€ํ•˜๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ธฐ๊ณ„

์†Œํ”„ํŠธ์›จ์–ด:

  • apt-get์€ ์—…๋ฐ์ดํŠธ
  • apt-get ์—…๊ทธ๋ ˆ์ด๋“œ
  • apt-get python-pip ์„ค์น˜
  • pip๋Š” mysql-connector-python-rf๋ฅผ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

MariaDB ์„ค์น˜ ๋ฐฉ๋ฒ• ์—ฌ๊ธฐ์—:

apt-get install libmariadbclient-dev
mysql -e "INSTALL PLUGIN blackhole SONAME 'ha_blackhole.so';" -- ะฝัƒะถะฝะพ ะดะปั test_employees_sha

ํ…Œ์ŠคํŠธ ๊ธฐ๋ฐ˜ ํ™•๋ณด ๋”ฐ๋ผ์„œ:

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๊ฐ€ ์ง€์ •๋œ ๋Œ€๋กœ ๋ฐฐํฌ๋ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—:

mysql -t < employees.sql
mysql -t < test_employees_sha.sql

์†Œ๊ทœ๋ชจ ํ…Œ์ŠคํŠธ ๊ธฐ๋ฐ˜:

์ž‘์—…๋Œ€ 

ํ–‰ ๊ฐœ์ˆ˜ 

๋ฐ์ดํ„ฐ ํฌ๊ธฐ(MB)

์ธ๋ฑ์Šค ํฌ๊ธฐ(KB)

๋ถ€์„œ 

9

0.02

16.00

๋ถ€์„œ_emp 

331143 

11.52

5648.00

๋ถ€์„œ_๊ด€๋ฆฌ์ž 

24 

0.02

16.00

์ง์› 

299379 

14.52

0.00

๊ธ‰์—ฌ 

2838426 

95.63

0.00 

์ œ๋ชฉ๋“ค 

442783 

19.56

0.00

๊ธฐ๋ณธ ํ…Œ์ŠคํŠธ ์„œ๋น„์Šค๋Š” Python์œผ๋กœ ์ฆ‰์‹œ ์ž‘์„ฑ๋˜๋ฉฐ ๋‹ค์Œ ๋„ค ๊ฐ€์ง€ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

  1. getState: ์ƒํƒœ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
  2. getEmployee: ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ์ง์›(+๊ธ‰์—ฌ, +์งํ•จ)์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
  3. patchEmployee: ์ง์› ํ•„๋“œ ๋ณ€๊ฒฝ
  4. insertSalary: ๊ธ‰์—ฌ๋ฅผ ์‚ฝ์ž…ํ•ฉ๋‹ˆ๋‹ค.

์„œ๋น„์Šค ์†Œ์Šค(dbtest.py)

#!/usr/bin/python
import mysql.connector as mariadb
from flask import Flask, json, request, abort
from mysql.connector.constants import ClientFlag

app = Flask(__name__)

def getFields(cursor):
    results = {}
    column = 0
    for d in cursor.description:
        results[d[0]] = column
        column = column + 1
    return results

PAGE_SIZE = 30

@app.route("/")
def main():
    return "Hello!"

@app.route("/employees/<page>", methods=['GET'])
def getEmployees(page):
    offset = (int(page) - 1) * PAGE_SIZE
    connection = mariadb.connect(user='admin', password='q5XpRomdSr', database='employees')
    cursor = connection.cursor()
    cursor.execute("SELECT * FROM employees LIMIT {} OFFSET {}".format(PAGE_SIZE, offset))
    return {'employees': [i[0] for i in cursor.fetchall()]}

@app.route("/employee/<id>", methods=['GET'])
def getEmployee(id):
    id = int(id)
    connection = mariadb.connect(user='admin', password='q5XpRomdSr', database='employees')
    cursor = connection.cursor()
    cursor.execute("SELECT * FROM employees WHERE emp_no = {}".format(id))
    fields = getFields(cursor)
    employee = {}
    found = False
    for row in cursor.fetchall():
        found = True
        employee = {
            "birth_date": row[fields["birth_date"]],
            "first_name": row[fields["first_name"]],
            "last_name": row[fields["last_name"]],
            "gender": row[fields["gender"]],
            "hire_date": row[fields["hire_date"]]
        }
    if not found:
        abort(404)
    cursor.execute("SELECT * FROM salaries WHERE emp_no = {}".format(id))
    fields = getFields(cursor)
    salaries = []
    for row in cursor.fetchall():
        salary = {
            "salary": row[fields["salary"]],
            "from_date": row[fields["from_date"]],
            "to_date": row[fields["to_date"]]
        }
        salaries.append(salary)
    employee["salaries"] = salaries
    cursor.execute("SELECT * FROM titles WHERE emp_no = {}".format(id))
    fields = getFields(cursor)
    titles = []
    for row in cursor.fetchall():
        title = {
            "title": row[fields["title"]],
            "from_date": row[fields["from_date"]],
            "to_date": row[fields["to_date"]]
        }
        titles.append(title)
    employee["titles"] = titles
    return json.dumps({
        "status": "success",
        "employee": employee
    })

def isFieldValid(t, v):
    if t == "employee":
        return v in ["birdth_date", "first_name", "last_name", "hire_date"]
    else:
        return false

@app.route("/employee/<id>", methods=['PATCH'])
def setEmployee(id):
    id = int(id)
    content = request.json
    print(content)
    setList = ""
    data = []
    for k, v in content.iteritems():
        if not isFieldValid("employee", k):
            continue
        if setList != "":
            setList = setList + ", "
        setList = setList + k + "=%s"
        data.append(v)
    data.append(id)
    print(setList)
    print(data)
    connection = mariadb.connect(user='admin', password='q5XpRomdSr', database='employees', client_flags=[ClientFlag.FOUND_ROWS])
    cursor = connection.cursor()
    cursor.execute("UPDATE employees SET {} WHERE emp_no = %s".format(setList), data)
    connection.commit()
    if cursor.rowcount < 1:
        abort(404)
    return json.dumps({
        "status": "success"
    })

@app.route("/salary", methods=['PUT'])
def putSalary():
    content = request.json
    print(content)
    connection = mariadb.connect(user='admin', password='q5XpRomdSr', database='employees', client_flags=[ClientFlag.FOUND_ROWS])
    cursor = connection.cursor()
    data = [content["emp_no"], content["salary"], content["from_date"], content["to_date"]]
    cursor.execute("INSERT INTO salaries (emp_no, salary, from_date, to_date) VALUES (%s, %s, %s, %s)", data)
    connection.commit()
    return json.dumps({
        "status": "success"
    })


@app.route("/state", methods=['GET'])
def getState():
    return json.dumps({
        "status": "success",
        "state": "working"
    })

if __name__ == '__main__':
    app.run(host='0.0.0.0',port='5002')

๊ฒฝ๊ณ ! ์–ด๋– ํ•œ ๊ฒฝ์šฐ์—๋„ ์ด ์„œ๋น„์Šค๋ฅผ ์˜ˆ์‹œ๋‚˜ ์ง€์นจ์œผ๋กœ ์‚ผ์•„์„œ๋Š” ์•ˆ ๋ฉ๋‹ˆ๋‹ค!

ํ…Œ์ŠคํŠธ๋Š” ์˜ค๋ž˜๋œ JMeter๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ˆ˜ํ–‰๋ฉ๋‹ˆ๋‹ค. 15๋ถ„์—์„œ 2์‹œ๊ฐ„๊นŒ์ง€ ์ง€์†๋˜๋Š” ์ผ๋ จ์˜ ํ…Œ์ŠคํŠธ๊ฐ€ ์ค‘๋‹จ ์—†์ด ์‹œ์ž‘๋˜์—ˆ์œผ๋ฉฐ ์š”์ฒญ ๋น„์œจ์€ ๋‹ค์–‘ํ–ˆ์œผ๋ฉฐ ์ฒ˜๋ฆฌ๋Ÿ‰์€ ๋ถ„๋‹น 300~600๊ฐœ ์š”์ฒญ์œผ๋กœ ๋‹ค์–‘ํ–ˆ์Šต๋‹ˆ๋‹ค. ์Šค๋ ˆ๋“œ ์ˆ˜๋Š” 50~500๊ฐœ์ž…๋‹ˆ๋‹ค.

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๊ฐ€ ๋งค์šฐ ์ž‘๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค์Œ ๋ช…๋ น์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

mysql -e "SHOW ENGINE INNODB STATUS"

๊ฒƒ์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค:

Buffer pool hit rate 923 / 1000, young-making rate 29 / 1000 not 32 / 1000

๋‹ค์Œ์€ ์š”์ฒญ์— ๋Œ€ํ•œ ํ‰๊ท  ์‘๋‹ต ์‹œ๊ฐ„์ž…๋‹ˆ๋‹ค.

๋ผ๋ฒจ

ํ‰๊ท 

์ค‘์•™๊ฐ’

90% ๋ผ์ธ

95% ๋ผ์ธ

99% ๋ผ์ธ

Min

Max

getEmployee

37.64

12.57

62.28

128.5

497.57

5

4151.78

getState

17

7.57

30.14

58.71

193

3

2814.71

ํŒจ์น˜์ง์›

161.42

83.29

308

492.57

1845.14

5

6639.4

put๊ธ‰์—ฌ

167.21

86.93

315.34

501.07

1927.12

7

6722.44

์ด๋Ÿฌํ•œ ํ•ฉ์„ฑ ๊ฒฐ๊ณผ๋ฅผ ํ†ตํ•ด ์ด VPS๊ฐ€ ๊ท€ํ•˜์˜ ํŠน์ • ์ž‘์—…์— ์–ผ๋งˆ๋‚˜ ์ ํ•ฉํ•œ์ง€ ํŒ๋‹จํ•˜๊ธฐ ์–ด๋ ค์šธ ์ˆ˜ ์žˆ์œผ๋ฉฐ ์ผ๋ฐ˜์ ์œผ๋กœ ๋‚˜์—ด๋œ ๋ฐฉ๋ฒ•์€ ์šฐ๋ฆฌ๊ฐ€ ์–ด๋–ค ํ˜•ํƒœ๋กœ๋“  ์ฒ˜๋ฆฌํ•ด์•ผ ํ–ˆ๋˜ ์‚ฌ๋ก€๋กœ ์ œํ•œ๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋ชฉ๋ก์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋ถ„๋ช…ํžˆ ์™„์ „ํ•˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. ์—ฌ๋Ÿฌ๋ถ„์ด ์ง์ ‘ ๊ฒฐ๋ก ์„ ๋‚ด๋ฆฌ๊ณ  ์‹ค์ œ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ๊ณผ ์ž‘์—…์— ๋Œ€ํ•ด 30๋ฃจ๋ธ”์— ๋Œ€ํ•œ ์„œ๋ฒ„๋ฅผ ํ…Œ์ŠคํŠธํ•˜๊ณ  ์˜๊ฒฌ์— ์ด ๊ตฌ์„ฑ์— ๋Œ€ํ•œ ์˜ต์…˜์„ ์ œ์•ˆํ•ด ๋ณด์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค.

์ถœ์ฒ˜ : habr.com

์ฝ”๋ฉ˜ํŠธ๋ฅผ ์ถ”๊ฐ€