تحسين Linux للتعامل مع 1.2 مليون طلب JSON في الثانية

تم نشر دليل تفصيلي حول ضبط بيئة Linux لتحقيق أقصى قدر من الأداء لمعالجة طلبات HTTP. أتاحت الطرق المقترحة زيادة أداء معالج JSON استنادًا إلى مكتبة libreactor في بيئة Amazon EC2 (4 vCPU) من 224 ألف طلب API في الثانية مع الإعدادات القياسية لـ Amazon Linux 2 مع kernel 4.14 إلى 1.2 مليون طلب في الثانية الثانية بعد التحسين (زيادة قدرها 436%)، وأدى أيضًا إلى تقليل التأخير في معالجة الطلبات بنسبة 79%. الأساليب المقترحة ليست خاصة بـ libreactor وتعمل عند استخدام خوادم http أخرى، بما في ذلك nginx وActix وNetty وNode.js (تم استخدام libreactor في الاختبارات لأن الحل المبني عليه أظهر أداء أفضل).

تحسين Linux للتعامل مع 1.2 مليون طلب JSON في الثانية

التحسينات الأساسية:

  • تحسين كود libreactor. تم استخدام خيار R18 من مجموعة Techempower كأساس، والذي تم تحسينه عن طريق إزالة التعليمات البرمجية للحد من عدد نوى وحدة المعالجة المركزية المستخدمة (سمح التحسين بتسريع العمل بنسبة 25-27%)، والتجميع في دول مجلس التعاون الخليجي باستخدام خيارات "-O3" (زيادة قدرها 5-10%) و"-march-native" (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" (الحماية من Specter v1 + SWAPGS) 1-2%، "nospectre_v2" (الحماية من Specter v2) - 15-20%، "pti=off" (Spectre v3/Meltdown) - 6%، "mds=off tsx_async_abort=off" (MDS/Zombieload وTSX Asynchronous Abort) - 6%. تم ترك إعدادات الحماية ضد هجمات L1TF/Foreshadow (l1tf=flush)، وiTLB multihit، وSpectulative Store Bypass، وهجمات SRBDS دون تغيير، مما لم يؤثر على الأداء نظرًا لأنها لم تتقاطع مع التكوين الذي تم اختباره (على سبيل المثال، خاص بـ KVM، المتداخل الافتراضية ونماذج وحدة المعالجة المركزية الأخرى).
  • تعطيل آليات التدقيق وحظر مكالمات النظام باستخدام الأمر "auditctl -a Never,task" وتحديد خيار "-security-opt seccomp=unconfined" عند بدء تشغيل حاوية عامل الإرساء. بلغت الزيادة الإجمالية في الأداء 11%، وزادت الإنتاجية من 446 ألف طلب/ثانية إلى 495 ألف طلب/ثانية.
  • تعطيل iptables/netfilter عن طريق إلغاء تحميل وحدات kernel المرتبطة بها. جاءت فكرة تعطيل جدار الحماية، الذي لم يتم استخدامه في حل خادم معين، من خلال نتائج التوصيف، والتي من خلالها استغرق تنفيذ وظيفة nf_hook_slow 18% من الوقت. تجدر الإشارة إلى أن nftables يعمل بكفاءة أكبر من iptables، لكن Amazon Linux يستمر في استخدام iptables. بعد تعطيل iptables، ارتفع الأداء بنسبة 22%، وزادت الإنتاجية من 495 ألف طلب/ثانية إلى 603 ألف طلب/ثانية.
  • تقليل ترحيل المعالجات بين مراكز وحدة المعالجة المركزية المختلفة لتحسين كفاءة استخدام ذاكرة التخزين المؤقت للمعالج. تم إجراء التحسين على مستوى عمليات ربط libreactor بنوى وحدة المعالجة المركزية (CPU Pinning) ومن خلال تثبيت معالجات شبكة kernel (Receive Side Scaling). على سبيل المثال، تم تعطيل irqbalance وتم تعيين تقارب قائمة الانتظار لوحدة المعالجة المركزية بشكل صريح في /proc/irq/$IRQ/smp_affinity_list. لاستخدام نفس نواة وحدة المعالجة المركزية لمعالجة عملية libreactor وقائمة انتظار الشبكة للحزم الواردة، يتم استخدام معالج BPF مخصص، متصل عن طريق تعيين علامة SO_ATTACH_REUSEPORT_CBPF عند إنشاء المقبس. لربط قوائم انتظار الحزم الصادرة بوحدة المعالجة المركزية، تم تغيير الإعدادات /sys/class/net/eth0/queues/tx- /xps_cpus. بلغت الزيادة الإجمالية في الأداء 38%، وزادت الإنتاجية من 603 ألف طلب/ثانية إلى 834 ألف طلب/ثانية.
  • تحسين التعامل مع المقاطعة واستخدام الاقتراع. أدى تمكين وضع Adaptive-RX في برنامج تشغيل ENA ومعالجة sysctl net.core.busy_read إلى زيادة الأداء بنسبة 28% (زادت الإنتاجية من 834 ألف طلب/ثانية إلى 1.06 مليون طلب/ثانية، وانخفض زمن الوصول من 361 ميكروثانية إلى 292 ميكروثانية).
  • تعطيل خدمات النظام التي تؤدي إلى حظر غير ضروري في مكدس الشبكة. أدى تعطيل dhclient وتعيين عنوان IP يدويًا إلى زيادة الأداء بنسبة 6% وزيادة الإنتاجية من 1.06 مليون طلب/ثانية إلى 1.12 مليون طلب/ثانية. السبب وراء تأثير dhclient على الأداء هو تحليل حركة المرور باستخدام مأخذ توصيل خام.
  • قفل تدور القتال. أدى تحويل مكدس الشبكة إلى وضع "noqueue" عبر sysctl "net.core.default_qdisc=noqueue" و"tc qdisc استبدال dev eth0 root mq" إلى زيادة في الأداء بنسبة 2%، وزيادة الإنتاجية من 1.12 مليون طلب/ثانية إلى 1.15 مليون الطلب / ثانية.
  • التحسينات الطفيفة النهائية، مثل تعطيل GRO (استقبال إلغاء التحميل العام) باستخدام الأمر "ethtool -K eth0 gro off" واستبدال خوارزمية التحكم في الازدحام المكعب بـ reno باستخدام sysctl "net.ipv4.tcp_congestion_control=reno". وبلغت الزيادة الإجمالية في الإنتاجية 4%. تمت زيادة الإنتاجية من 1.15 مليون طلب/ثانية إلى 1.2 مليون طلب/ثانية.

بالإضافة إلى التحسينات التي نجحت، تتناول المقالة أيضًا الأساليب التي لم تؤدي إلى زيادة الأداء المتوقع. على سبيل المثال، تبين أن ما يلي غير فعال:

  • تشغيل libreactor بشكل منفصل لم يختلف في الأداء عن تشغيله في حاوية. لم يكن لاستبدال writev بـ send، وزيادة maxevents في epoll_wait، وتجربة إصدارات وأعلام دول مجلس التعاون الخليجي أي تأثير (كان التأثير ملحوظًا فقط بالنسبة للأعلام "-O3" و"-march-native").
  • ترقية نواة Linux إلى الإصدارين 4.19 و5.4، باستخدام جدولي SCHED_FIFO وSCHED_RR، ومعالجة sysctl kernel.sched_min_granularity_ns، وkernel.sched_wakeup_granularity_ns، وtransparent_hugepages=never، وskew_tick=1، وclocksource=tsc لم تؤثر على الأداء.
  • في برنامج تشغيل 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

إضافة تعليق