์ดˆ๋‹น 1.2๋งŒ JSON ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๋Š” Linux ์ตœ์ ํ™”

HTTP ์š”์ฒญ ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•œ ์ตœ๋Œ€ ์„ฑ๋Šฅ์„ ๋‹ฌ์„ฑํ•˜๊ธฐ ์œ„ํ•ด Linux ํ™˜๊ฒฝ์„ ์กฐ์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๊ฐ€์ด๋“œ๊ฐ€ ๊ฒŒ์‹œ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ œ์•ˆ๋œ ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋ฉด Amazon EC2 ํ™˜๊ฒฝ(4 vCPU)์˜ libreactor ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๊ธฐ๋ฐ˜ JSON ํ”„๋กœ์„ธ์„œ์˜ ์„ฑ๋Šฅ์„ ์ปค๋„๋‹น 224๋งŒ ์š”์ฒญ์œผ๋กœ ๊ตฌ์„ฑ๋œ Amazon Linux 2์˜ ํ‘œ์ค€ ์„ค์ •์œผ๋กœ ์ดˆ๋‹น 4.14๊ฐœ์˜ API ์š”์ฒญ์—์„œ 1.2๋งŒ ์š”์ฒญ์œผ๋กœ ํ–ฅ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ์ตœ์ ํ™” ํ›„ 436์œ„(79% ์ฆ๊ฐ€)๋ฅผ ๊ธฐ๋กํ–ˆ์œผ๋ฉฐ ์š”์ฒญ ์ฒ˜๋ฆฌ ์ง€์—ฐ๋„ XNUMX% ๊ฐ์†Œํ–ˆ์Šต๋‹ˆ๋‹ค. ์ œ์•ˆ๋œ ๋ฐฉ๋ฒ•์€ libreactor์—๋งŒ ๊ตญํ•œ๋˜์ง€ ์•Š์œผ๋ฉฐ nginx, Actix, Netty ๋ฐ Node.js๋ฅผ ํฌํ•จํ•œ ๋‹ค๋ฅธ http ์„œ๋ฒ„๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค(libreactor ๊ธฐ๋ฐ˜ ์†”๋ฃจ์…˜์ด ๋” ๋‚˜์€ ์„ฑ๋Šฅ์„ ๋ณด์—ฌ ํ…Œ์ŠคํŠธ์— ์‚ฌ์šฉ๋˜์—ˆ์Šต๋‹ˆ๋‹ค).

์ดˆ๋‹น 1.2๋งŒ JSON ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๋Š” Linux ์ตœ์ ํ™”

๊ธฐ๋ณธ ์ตœ์ ํ™”:

  • libreactor ์ฝ”๋“œ ์ตœ์ ํ™”. Techempower ํ‚คํŠธ์˜ R18 ์˜ต์…˜์ด ๊ธฐ๋ณธ์œผ๋กœ ์‚ฌ์šฉ๋˜์—ˆ์œผ๋ฉฐ, ์‚ฌ์šฉ๋œ CPU ์ฝ”์–ด ์ˆ˜๋ฅผ ์ œํ•œํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ œ๊ฑฐํ•˜๊ณ (์ตœ์ ํ™”๋ฅผ ํ†ตํ•ด ์ž‘์—… ์†๋„๋ฅผ 25~27% ํ–ฅ์ƒ) "-O3" ์˜ต์…˜์„ ์‚ฌ์šฉํ•˜์—ฌ GCC์—์„œ ์กฐ๋ฆฝํ•˜์—ฌ ๊ฐœ์„ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. (5-10% ์ฆ๊ฐ€) ๋ฐ "-march-native"(5-10%), ์ฝ๊ธฐ/์“ฐ๊ธฐ ํ˜ธ์ถœ์„ recv/send(5-10%)๋กœ ๋Œ€์ฒดํ•˜๊ณ  pthread ์‚ฌ์šฉ ์‹œ ์˜ค๋ฒ„ํ—ค๋“œ ๊ฐ์†Œ(2-3%) . ์ฝ”๋“œ ์ตœ์ ํ™” ํ›„ ์ „์ฒด ์„ฑ๋Šฅ์€ 55% ์ฆ๊ฐ€ํ–ˆ์œผ๋ฉฐ ์ฒ˜๋ฆฌ๋Ÿ‰์€ 224k req/s์—์„œ 347k req/s๋กœ ์ฆ๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค.
  • ์ถ”์ธก ์‹คํ–‰ ์ทจ์•ฝ์ ์— ๋Œ€ํ•œ ๋ณดํ˜ธ๋ฅผ ๋น„ํ™œ์„ฑํ™”ํ•ฉ๋‹ˆ๋‹ค. ์ปค๋„์„ ๋กœ๋“œํ•  ๋•Œ "nospectre_v1 nospectre_v2 pti=off mds=off tsx_async_abort=off" ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์„ฑ๋Šฅ์ด 28% ์ฆ๊ฐ€ํ•˜๊ณ  ์ฒ˜๋ฆฌ๋Ÿ‰์ด 347k req/s์—์„œ 446k req/s๋กœ ์ฆ๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด์™€ ๋ณ„๋„๋กœ "nospectre_v1"(Spectre v1 + SWAPGS ๋ณดํ˜ธ) ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ์ฆ๊ฐ€๋Š” 1-2%, "nospectre_v2"(Spectre v2๋กœ๋ถ€ํ„ฐ ๋ณดํ˜ธ) - 15-20%, "pti=off"(Spectre v3/Meltdown)์ž…๋‹ˆ๋‹ค. - 6%, "mds=off tsx_async_abort=off"(MDS/Zombieload ๋ฐ TSX ๋น„๋™๊ธฐ ์ค‘๋‹จ) - 6%. L1TF/Foreshadow(l1tf=flush), iTLB ๋‹ค์ค‘ ์ ์ค‘, Speculative Store Bypass ๋ฐ SRBDS ๊ณต๊ฒฉ์— ๋Œ€ํ•œ ๋ณดํ˜ธ ์„ค์ •์€ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์€ ์ฑ„๋กœ ์œ ์ง€๋˜์—ˆ์œผ๋ฉฐ, ์ด๋Š” ํ…Œ์ŠคํŠธ๋œ ๊ตฌ์„ฑ๊ณผ ๊ต์ฐจํ•˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ์„ฑ๋Šฅ์— ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค(์˜ˆ: KVM์— ํŠน์ •, ์ค‘์ฒฉ๋จ). ๊ฐ€์ƒํ™” ๋ฐ ๊ธฐํƒ€ CPU ๋ชจ๋ธ).
  • Docker ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์‹œ์ž‘ํ•  ๋•Œ "auditctl -a never,task" ๋ช…๋ น์„ ์‚ฌ์šฉํ•˜๊ณ  "--security-opt seccomp=unconfined" ์˜ต์…˜์„ ์ง€์ •ํ•˜์—ฌ ๊ฐ์‚ฌ ๋ฐ ์‹œ์Šคํ…œ ํ˜ธ์ถœ ์ฐจ๋‹จ ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ๋น„ํ™œ์„ฑํ™”ํ•ฉ๋‹ˆ๋‹ค. ์ „๋ฐ˜์ ์ธ ์„ฑ๋Šฅ์€ 11% ์ฆ๊ฐ€ํ–ˆ์œผ๋ฉฐ ์ฒ˜๋ฆฌ๋Ÿ‰์€ 446 req/s์—์„œ 495 req/s๋กœ ์ฆ๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค.
  • ๊ด€๋ จ ์ปค๋„ ๋ชจ๋“ˆ์„ ์–ธ๋กœ๋“œํ•˜์—ฌ iptables/netfilter๋ฅผ ๋น„ํ™œ์„ฑํ™”ํ•ฉ๋‹ˆ๋‹ค. ํŠน์ • ์„œ๋ฒ„ ์†”๋ฃจ์…˜์—์„œ๋Š” ์‚ฌ์šฉ๋˜์ง€ ์•Š์•˜๋˜ ๋ฐฉํ™”๋ฒฝ์„ ๋น„ํ™œ์„ฑํ™”ํ•˜๋ ค๋Š” ์•„์ด๋””์–ด๋Š” ํ”„๋กœํŒŒ์ผ๋ง ๊ฒฐ๊ณผ์—์„œ nf_hook_slow ํ•จ์ˆ˜ ์‹คํ–‰ ์‹œ๊ฐ„์ด 18% ์†Œ์š”๋œ ๊ฒƒ์œผ๋กœ ํŒ๋‹จ๋˜์–ด ์ด‰๋ฐœ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. nftables๋Š” iptables๋ณด๋‹ค ๋” ํšจ์œจ์ ์œผ๋กœ ์ž‘๋™ํ•˜์ง€๋งŒ Amazon Linux๋Š” ๊ณ„์†ํ•ด์„œ iptables๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. iptables๋ฅผ ๋น„ํ™œ์„ฑํ™”ํ•œ ํ›„ ์„ฑ๋Šฅ์€ 22% ์ฆ๊ฐ€ํ–ˆ๊ณ  ์ฒ˜๋ฆฌ๋Ÿ‰์€ 495k req/s์—์„œ 603k req/s๋กœ ์ฆ๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค.
  • ํ”„๋กœ์„ธ์„œ ์บ์‹œ ์‚ฌ์šฉ ํšจ์œจ์„ฑ์„ ๋†’์ด๊ธฐ ์œ„ํ•ด ์„œ๋กœ ๋‹ค๋ฅธ CPU ์ฝ”์–ด ๊ฐ„์˜ ํ•ธ๋“ค๋Ÿฌ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์„ ์ค„์˜€์Šต๋‹ˆ๋‹ค. ์ตœ์ ํ™”๋Š” libreactor ํ”„๋กœ์„ธ์Šค๋ฅผ CPU ์ฝ”์–ด์— ๋ฐ”์ธ๋”ฉํ•˜๋Š” ์ˆ˜์ค€(CPU Pinning)๊ณผ ์ปค๋„ ๋„คํŠธ์›Œํฌ ํ•ธ๋“ค๋Ÿฌ ๊ณ ์ •(Receive Side Scaling)์„ ํ†ตํ•ด ์ˆ˜ํ–‰๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, irqbalance๋Š” ๋น„ํ™œ์„ฑํ™”๋˜์—ˆ๊ณ  CPU์— ๋Œ€ํ•œ ๋Œ€๊ธฐ์—ด ์„ ํ˜ธ๋„๋Š” /proc/irq/$IRQ/smp_affinity_list์— ๋ช…์‹œ์ ์œผ๋กœ ์„ค์ •๋˜์—ˆ์Šต๋‹ˆ๋‹ค. libreactor ํ”„๋กœ์„ธ์Šค์™€ ์ˆ˜์‹  ํŒจํ‚ท์˜ ๋„คํŠธ์›Œํฌ ํ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ๋™์ผํ•œ CPU ์ฝ”์–ด๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ์†Œ์ผ“์„ ์ƒ์„ฑํ•  ๋•Œ SO_ATTACH_REUSEPORT_CBPF ํ”Œ๋ž˜๊ทธ๋ฅผ ์„ค์ •ํ•˜์—ฌ ์—ฐ๊ฒฐ๋˜๋Š” ์‚ฌ์šฉ์ž ์ง€์ • BPF ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ๋‚˜๊ฐ€๋Š” ํŒจํ‚ท์˜ ๋Œ€๊ธฐ์—ด์„ CPU์— ๋ฐ”์ธ๋”ฉํ•˜๊ธฐ ์œ„ํ•ด /sys/class/net/eth0/queues/tx- ์„ค์ •์ด ๋ณ€๊ฒฝ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. /xps_cpus. ์ „๋ฐ˜์ ์ธ ์„ฑ๋Šฅ์€ 38% ์ฆ๊ฐ€ํ–ˆ์œผ๋ฉฐ ์ฒ˜๋ฆฌ๋Ÿ‰์€ 603k req/s์—์„œ 834k req/s๋กœ ์ฆ๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค.
  • ์ธํ„ฐ๋ŸฝํŠธ ์ฒ˜๋ฆฌ ๋ฐ ํด๋ง ์‚ฌ์šฉ ์ตœ์ ํ™”. ENA ๋“œ๋ผ์ด๋ฒ„์—์„œadaptive-rx ๋ชจ๋“œ๋ฅผ ํ™œ์„ฑํ™”ํ•˜๊ณ  sysctl net.core.busy_read๋ฅผ ์กฐ์ž‘ํ•˜๋ฉด ์„ฑ๋Šฅ์ด 28% ํ–ฅ์ƒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค(์ฒ˜๋ฆฌ๋Ÿ‰์€ 834k req/s์—์„œ 1.06M req/s๋กœ ์ฆ๊ฐ€ํ•˜๊ณ  ๋Œ€๊ธฐ ์‹œ๊ฐ„์€ 361ฮผs์—์„œ 292ฮผs๋กœ ๊ฐ์†Œ).
  • ๋„คํŠธ์›Œํฌ ์Šคํƒ์—์„œ ๋ถˆํ•„์š”ํ•œ ์ฐจ๋‹จ์„ ์ดˆ๋ž˜ํ•˜๋Š” ์‹œ์Šคํ…œ ์„œ๋น„์Šค๋ฅผ ๋น„ํ™œ์„ฑํ™”ํ•ฉ๋‹ˆ๋‹ค. dhclient๋ฅผ ๋น„ํ™œ์„ฑํ™”ํ•˜๊ณ  IP ์ฃผ์†Œ๋ฅผ ์ˆ˜๋™์œผ๋กœ ์„ค์ •ํ•˜๋ฉด ์„ฑ๋Šฅ์ด 6% ์ฆ๊ฐ€ํ•˜๊ณ  ์ฒ˜๋ฆฌ๋Ÿ‰์ด 1.06M ์š”์ฒญ/์ดˆ์—์„œ 1.12M ์š”์ฒญ/์ดˆ๋กœ ์ฆ๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. dhclient๊ฐ€ ์„ฑ๋Šฅ์— ์˜ํ–ฅ์„ ๋ฏธ์น˜๋Š” ์ด์œ ๋Š” ์›์‹œ ์†Œ์ผ“์„ ์‚ฌ์šฉํ•œ ํŠธ๋ž˜ํ”ฝ ๋ถ„์„์— ์žˆ์Šต๋‹ˆ๋‹ค.
  • ํŒŒ์ดํŒ… ์Šคํ•€ ๋ฝ. sysctl "net.core.default_qdisc=noqueue" ๋ฐ "tc qdisc replacement dev eth0 root mq"๋ฅผ ํ†ตํ•ด ๋„คํŠธ์›Œํฌ ์Šคํƒ์„ "noqueue" ๋ชจ๋“œ๋กœ ์ „ํ™˜ํ•˜๋ฉด ์„ฑ๋Šฅ์ด 2% ์ฆ๊ฐ€ํ•˜๊ณ  ์ฒ˜๋ฆฌ๋Ÿ‰์ด 1.12M req/s์—์„œ 1.15M๋กœ ์ฆ๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. ์š”์ฒญ/์ดˆ
  • "ethtool -K eth0 gro off" ๋ช…๋ น์„ ์‚ฌ์šฉํ•˜์—ฌ GRO(์ผ๋ฐ˜ ์ˆ˜์‹  ์˜คํ”„๋กœ๋“œ)๋ฅผ ๋น„ํ™œ์„ฑํ™”ํ•˜๊ณ  sysctl "net.ipv4.tcp_congestion_control=reno"๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ๋น… ํ˜ผ์žก ์ œ์–ด ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ reno๋กœ ๋ฐ”๊พธ๋Š” ๋“ฑ์˜ ์ตœ์ข… ์‚ฌ์†Œํ•œ ์ตœ์ ํ™”์ž…๋‹ˆ๋‹ค. ์ „๋ฐ˜์ ์ธ ์ƒ์‚ฐ์„ฑ ์ฆ๊ฐ€๋Š” 4%์˜€์Šต๋‹ˆ๋‹ค. ์ฒ˜๋ฆฌ๋Ÿ‰์ด 1.15๋งŒ ์š”์ฒญ/์ดˆ์—์„œ 1.2๋งŒ ์š”์ฒญ/์ดˆ๋กœ ์ฆ๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค.

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

  • libreactor๋ฅผ ๋ณ„๋„๋กœ ์‹คํ–‰ํ•ด๋„ ์ปจํ…Œ์ด๋„ˆ์—์„œ ์‹คํ–‰ํ•˜๋Š” ๊ฒƒ๊ณผ ์„ฑ๋Šฅ์ด ๋‹ค๋ฅด์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. writev๋ฅผ send๋กœ ๋ฐ”๊พธ๊ณ , epoll_wait์—์„œ maxevents๋ฅผ ๋Š˜๋ฆฌ๊ณ , GCC ๋ฒ„์ „๊ณผ ํ”Œ๋ž˜๊ทธ๋ฅผ ์‹คํ—˜ํ•ด๋„ ํšจ๊ณผ๊ฐ€ ์—†์—ˆ์Šต๋‹ˆ๋‹ค(ํšจ๊ณผ๋Š” "-O3" ๋ฐ "-march-native" ํ”Œ๋ž˜๊ทธ์—์„œ๋งŒ ๋ˆˆ์— ๋„์—ˆ์Šต๋‹ˆ๋‹ค).
  • SCHED_FIFO ๋ฐ SCHED_RR ์Šค์ผ€์ค„๋Ÿฌ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  sysctl kernel.sched_min_granularity_ns, kernel.sched_wakeup_granularity_ns, transparent_hugepages=never,skew_tick=4.19 ๋ฐ clocksource=tsc๋ฅผ ์กฐ์ž‘ํ•˜์—ฌ Linux ์ปค๋„์„ ๋ฒ„์ „ 5.4 ๋ฐ 1๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•ด๋„ ์„ฑ๋Šฅ์— ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.
  • ENA ๋“œ๋ผ์ด๋ฒ„์—์„œ ์˜คํ”„๋กœ๋“œ ๋ชจ๋“œ(์„ธ๊ทธ๋จผํŠธํ™”, ๋ถ„์‚ฐ ์ˆ˜์ง‘, rx/tx ์ฒดํฌ์„ฌ) ํ™œ์„ฑํ™”, "-O3" ํ”Œ๋ž˜๊ทธ๋ฅผ ์‚ฌ์šฉํ•œ ๊ตฌ์ถ•, ena.rx_queue_size ๋ฐ ena.force_large_llq_header ๋งค๊ฐœ๋ณ€์ˆ˜ ์‚ฌ์šฉ์€ ํšจ๊ณผ๊ฐ€ ์—†์—ˆ์Šต๋‹ˆ๋‹ค.
  • ๋„คํŠธ์›Œํฌ ์Šคํƒ์˜ ๋ณ€๊ฒฝ์œผ๋กœ ์ธํ•ด ์„ฑ๋Šฅ์ด ํ–ฅ์ƒ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.
    • IPv6 ๋น„ํ™œ์„ฑํ™”: ipv6.disable=1
    • VLAN ๋น„ํ™œ์„ฑํ™”: modprobe -rv 8021q
    • ํŒจํ‚ค์ง€ ์†Œ์Šค ํ™•์ธ ๋น„ํ™œ์„ฑํ™”
      • net.ipv4.conf.all.rp_filter=0
      • net.ipv4.conf.eth0.rp_filter=0
      • net.ipv4.conf.all.accept_local=1(๋ถ€์ •์ ์ธ ํšจ๊ณผ)
    • net.ipv4.tcp_sack = 0
    • net.ipv4.tcp_dsack=0
    • net.ipv4.tcp_mem/tcp_wmem/tcp_rmem
    • net.core.netdev_budget
    • net.core.dev_weight
    • net.core.netdev_max_backlog
    • net.ipv4.tcp_slow_start_after_idle=0
    • net.ipv4.tcp_moderate_rcvbuf=0
    • net.ipv4.tcp_timestamps=0
    • net.ipv4.tcp_low_latency = 1
    • SO_PRIORITY
    • TCP_NODELAY

    ์ถœ์ฒ˜ : opennet.ru

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