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 ๊ธฐ๋ฐ ์๋ฃจ์ ์ด ๋ ๋์ ์ฑ๋ฅ์ ๋ณด์ฌ ํ ์คํธ์ ์ฌ์ฉ๋์์ต๋๋ค).
๊ธฐ๋ณธ ์ต์ ํ:
- 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