Секундына 1.2 миллион JSON сұрауларын өңдеу үшін Linux оңтайландыруы

HTTP сұрауларын өңдеу үшін максималды өнімділікке қол жеткізу үшін Linux ортасын баптау бойынша толық нұсқаулық жарияланды. Ұсынылған әдістер Amazon EC2 ортасындағы (4 vCPU) libreactor кітапханасына негізделген JSON процессорының өнімділігін 224 ядросы бар Amazon Linux 2 стандартты параметрлері бар секундына 4.14 мың API сұрауынан 1.2 миллион сұрауға дейін арттыруға мүмкіндік берді. оңтайландырудан кейінгі екінші орында (436%-ға өсті), сонымен қатар сұраныстарды өңдеудегі кідірістердің 79%-ға қысқаруына әкелді. Ұсынылған әдістер libreactor-ға тән емес және басқа http серверлерін, соның ішінде nginx, Actix, Netty және Node.js пайдаланған кезде жұмыс істейді (libreactor сынақтарда пайдаланылды, себебі оған негізделген шешім жақсы өнімділікті көрсетті).

Секундына 1.2 миллион JSON сұрауларын өңдеу үшін Linux оңтайландыруы

Негізгі оңтайландырулар:

  • Либреактор кодын оңтайландыру. Techempower жинағынан R18 опциясы негіз ретінде пайдаланылды, ол пайдаланылатын процессор өзектерінің санын шектеу үшін кодты жою арқылы жақсартылды (оңтайландыру жұмысты 25-27%-ға жылдамдатуға мүмкіндік берді, GCC-де «-O3» опцияларымен құрастырылды. (5-10% өсу ) және "-марш-нативті" (5-10%), оқу/жазу қоңырауларын recv/send (5-10%) арқылы ауыстыру және pthreads пайдалану кезінде үстеме шығындарды азайту (2-3%) . Кодты оңтайландырудан кейін жалпы өнімділік өсімі 55% құрады және өткізу қабілеті 224к рек/с-тан 347к рек/с дейін өсті.
  • Спекуляциялық орындалу осалдықтарынан қорғауды өшіріңіз. Ядроны жүктеу кезінде «nospectre_v1 nospectre_v2 pti=off mds=off tsx_async_abort=off» параметрлерін пайдалану өнімділікті 28%-ға арттыруға мүмкіндік берді, ал өткізу қабілеті 347к рек/с-тан 446к рек/с-қа дейін өсті. Сонымен қатар, «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 multihit, Спекуляциялық дүкенді айналып өту және SRBDS шабуылдарынан қорғау параметрлері өзгеріссіз қалдырылды, олар сыналған конфигурациямен қиылыспағандықтан өнімділікке әсер етпеді (мысалы, KVM-ге тән, кірістірілген виртуализация және басқа CPU үлгілері).
  • Докер контейнерін іске қосқан кезде "auditctl -a never,task" пәрменін пайдалану және "--security-opt seccomp=unconfined" опциясын көрсету арқылы тексеруді және жүйелік қоңырауларды блоктау механизмдерін өшіру. Жалпы өнімділік өсімі 11% құрады және өткізу қабілеті 446 мың рекв/с-тан 495 мың сұраныс/с дейін өсті.
  • Байланысты ядро ​​модульдерін босату арқылы iptables/netfilter өшіру. Арнайы серверлік шешімде пайдаланылмаған брандмауэрді өшіру идеясы nf_hook_slow функциясы орындалу уақытының 18%-ын алатын нәтижелерді профильдеу арқылы туындады. Айта кетейік, nftables iptables қарағанда тиімдірек жұмыс істейді, бірақ Amazon Linux iptables пайдалануды жалғастыруда. Iptables өшірілгеннен кейін өнімділік 22% артты, ал өткізу қабілеті 495к рекв/с-тан 603к рекв/с дейін өсті.
  • Процессор кэшін пайдалану тиімділігін арттыру үшін әртүрлі процессорлық ядролар арасындағы өңдеушілердің көші-қоны азайтылды. Оңтайландыру либреактор процестерін процессор өзектерімен байланыстыру деңгейінде де (CPU Pinning) және ядро ​​желісі өңдегіштерін бекіту (Receive Side Scaling) арқылы жүзеге асырылды. Мысалы, irqbalance өшірілген және процессорға кезек сәйкестігі /proc/irq/$IRQ/smp_affinity_list ішінде анық орнатылған. Либреактор процесін және кіріс пакеттердің желілік кезегін өңдеу үшін бірдей процессор өзегін пайдалану үшін ұяны жасау кезінде SO_ATTACH_REUSEPORT_CBPF жалауын орнату арқылы қосылған теңшелетін BPF өңдеушісі пайдаланылады. Шығыс пакеттердің кезектерін процессорға байланыстыру үшін /sys/class/net/eth0/queues/tx- параметрлері өзгертілді. /xps_cpus. Жалпы өнімділік өсімі 38% құрады, өткізу қабілеті 603 мың сұраныс/с-тан 834 мың сұраныс/с-қа дейін өсті.
  • Үзілістерді өңдеуді және сауалнаманы пайдалануды оңтайландыру. ENA драйверінде адаптивті-rx режимін қосу және sysctl net.core.busy_read өңдеу өнімділікті 28%-ға арттырды (өткізу қабілеті 834к рек/с-тан 1.06М рек/с-қа дейін өсті, ал кідіріс 361μс-тен 292μs дейін төмендеді).
  • Желі стекінде қажетсіз блоктауға әкелетін жүйелік қызметтерді өшіру. dhclient өшіру және IP мекенжайын қолмен орнату өнімділіктің 6%-ға артуына және өткізу қабілеттілігінің 1.06М сұраныс/с-тан 1.12М рек/с-қа дейін артуына әкелді. dhclient өнімділікке әсер ету себебі шикі розетка көмегімен трафикті талдау болып табылады.
  • Fighting Spin Lock. Желілік стекті sysctl “net.core.default_qdisc=noqueue” және “tc qdisc dev eth0 root mq алмастыру” арқылы “noqueue” режиміне ауыстыру өнімділіктің 2%-ға артуына әкелді және өткізу қабілеті 1.12М сұраныс/с-тан 1.15М-ға дейін өсті. сұраныс/с.
  • «ethtool -K eth0 gro off» пәрменімен GRO (Generic Receive Offload) өшіру және sysctl «net.ipv4.tcp_congestion_control=reno» көмегімен текшелік кептелісті басқару алгоритмін reno-ға ауыстыру сияқты соңғы шағын оңтайландырулар. Жалпы өнімділік өсімі 4%-ды құрады. Өткізу қабілеттілігі 1.15 млн рекв/с-тан 1.2 млн сұраныс/с дейін өсті.

Жұмыс істеген оңтайландыруларға қоса, мақалада күтілетін өнімділікті арттыруға әкелмеген әдістер де талқыланады. Мысалы, мыналар тиімсіз болып шықты:

  • Либреакторды бөлек іске қосу өнімділігі бойынша оны контейнерде іске қосудан ерекшеленбеді. writev дегенді жіберумен ауыстыру, epoll_wait ішіндегі максималды оқиғаларды ұлғайту және GCC нұсқалары мен жалаушаларымен тәжірибе жасау еш нәтиже бермеді (әсер тек “-O3” және “-naur-native” жалаушаларында байқалды).
  • SCHED_FIFO және SCHED_RR жоспарлаушыларын пайдаланып, Linux ядросын 4.19 және 5.4 нұсқаларына жаңарту, sysctl kernel.sched_min_granularity_ns, kernel.sched_wakeup_granularity_ns, transparent_hugepages=never және clock өнімділігіне әсер етпеді.
  • 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

пікір қалдыру