يحتاج تشغيل الخدمات الإنتاجية إلى معرفة ما يحدث داخلها، لكن إضافة المقاييس ليست مجانية. في عرض نشرته InfoQ، يوضح Brian Martin، الشريك المؤسس في IOP Systems، أن الفرق بين تنفيذ وآخر قد يحول تحديث عداد من عملية تكلف نحو 5 نانوثوانٍ إلى عملية تتجاوز ميكروثانية واحدة. ومع المدرجات التكرارية، قد يتسع الفرق من نحو 7 نانوثوانٍ إلى عشرات الميكروثواني عند التنافس بين الخيوط.
الفكرة الأساسية في العرض ليست اختيار مكتبة Rust بعينها، بل التعامل مع القياس بوصفه جزءاً من تصميم الأداء. فالمقياس الموضوع داخل مسار يُستدعى ملايين المرات يضخم أي كلفة صغيرة، في حين أن غياب القياس يجعل تشخيص البطء وحوادث الإنتاج وتحسين الأداء أكثر صعوبة.
ابدأ بفهم نوع البيانات وكلفة تحديثها
يميز Martin بين ثلاثة أنواع رئيسية من المقاييس: العداد الذي لا ينخفض عادة، مثل عدد الطلبات؛ والمقياس اللحظي الذي يمثل قيمة حالية، مثل عمق الطابور؛ والمدرج التكراري الذي يصف توزيع القيم، مثل أزمنة الاستجابة. هذا التمييز مهم لأن كل نوع يفرض عمليات مختلفة، كما أن المدرجات التكرارية تقدم معلومات لا يوفرها عداد إجمالي واحد.
في أبسط الحالات، يكون atomic fetch_add مناسباً للعدادات الصحيحة. أما حلقات المقارنة والاستبدال، أو CAS، فتحتاج عادة إلى إعادة المحاولة عندما تتنافس خيوط متعددة على الموقع نفسه. ويعود جزء كبير من الكلفة إلى مزامنة أسطر الذاكرة المخبئية بين الأنوية. يورد العرض قياسات على آلة AWS Graviton تضم 32 وحدة معالجة افتراضية: بلغ سقف المعالجة النظري نحو 119 مليون طلب في الثانية مع تحديث ذري منخفض الكلفة، مقابل نحو 23 مليوناً عند استخدام تنفيذ أعلى كلفة مع Prometheus.
خفّض التنافس بالتقسيم بحسب المعالج
عندما تتشارك جميع الخيوط عداداً واحداً، تنتقل سطر الذاكرة المخبئية بين الأنوية باستمرار. يقترح Martin بدلاً من ذلك إنشاء عداد مستقل لكل معالج، بحيث تكون عمليات الكتابة غير متنافسة تقريباً، ثم جمع القيم عند القراءة. هذه المقاربة ترفع كلفة القراءة قليلاً، لكنها تحمي مسار الكتابة الساخن، وهو الجانب الذي يتكرر مع كل طلب.
ينبغي الانتباه هنا إلى ظاهرة false sharing. فوجود عدادات مستقلة منطقياً لا يكفي إذا وضعت في سطر ذاكرة مخبئية واحد؛ إذ يبلغ حجم السطر 64 بايت، ما يعني أن ثمانية عدادات من نوع 64-bit قد تتجاور فيه. لذلك يوصي العرض بتجميع العدادات وحشوها بحيث تشغل أسطر ذاكرة منفصلة. ووفق الأرقام المعروضة، يمكن أن ينتقل الأداء النظري من نحو 119 مليون طلب في الثانية مع العداد الذري إلى نحو 6.4 مليار طلب في الثانية عند استخدام التقسيم المناسب.
صمّم المدرجات التكرارية لمسار التحديث
تبدأ كلفة المدرج التكراري من تحديد الحاوية التي تنتمي إليها القيمة. البحث الخطي داخل قائمة الحاويات هو الخيار الأبسط والأبطأ، بينما يقلل البحث الثنائي عدد المقارنات لكنه يظل مرتبطاً بعدد الحاويات. البديل الأسرع هو الفهرسة المباشرة، التي تحسب رقم الحاوية من القيمة بدلاً من البحث عنها.
توجد مفاضلات في هذه الفهرسة. التقسيم إلى نطاقات خطية سريع، لكنه قد ينتج خطأ نسبياً كبيراً عند القيم الصغيرة. والفهرسة اللوغاريتمية تحافظ بدرجة أفضل على الخطأ النسبي، إلا أن حساب اللوغاريتم نفسه مكلف. يعرض Martin استخدام نطاقات خارجية مبنية على Log2، مع حاويات فرعية تضبط الدقة، كما في HDR Histogram وH2Histogram. وفي اختبار غير ذري، استغرق تحديد الحاوية والتحديث نحو 2.65 نانوثانية في HDR Histogram ونحو 2.15 نانوثانية في H2Histogram.
متى يكون الاتساق التقريبي مقبولاً؟
لا تتحدد كلفة المدرج بطريقة الفهرسة وحدها. بعض التطبيقات تحدث عدة ذريات في كل عملية، أو تستخدم CAS لمجموع القيم، أو تفرض قفلاً للحصول على لقطة متسقة. ويشير العرض إلى أن بعض التنفيذات وصلت إلى أكثر من ميكروثانيتين، بل إلى عشرات الميكروثواني عند 32 نواة، بينما كان التنفيذ القائم على فهرسة مباشرة وتحديث ذري واحد أقرب إلى كلفة العداد.
البديل هو الاتساق التقريبي: قد تتغير بعض الحاويات أثناء قراءة المدرج، لكن الفارق بين قراءتين متتاليتين يظل مفيداً عندما تكون المقاييس تقريبية أصلاً. هذه ليست قاعدة عامة؛ فالأنظمة التي تحتاج لقطة متسقة تماماً قد تفضل المزامنة رغم كلفتها.
القراءة التحريرية من certi.news
ما يتغير عملياً هو أن قرار إضافة المقاييس يجب أن يشمل بنية التحديث، لا أسماء المقاييس فقط. العداد الذري، والتقسيم بحسب المعالج، والفهرسة المباشرة قد تجعل القياس قابلاً للاستخدام داخل المسارات الحساسة، بينما قد تفرض المدرجات المتزامنة أو القابلة للتوسع ديناميكياً كلفة كبيرة تحت الضغط. لا يقدم العرض وصفة واحدة صالحة لكل مكتبة أو خدمة؛ فهو يوضح أن المرونة، وقابلية استخدام المكتبة داخل مشاريع أخرى، والاتساق، والأداء أهداف متعارضة جزئياً. لذلك ينبغي اختبار التنفيذ الفعلي تحت مستويات التنافس وحجم المعالجة المستهدفين، بدلاً من الاعتماد على اسم المكتبة أو نتيجة الحالة غير المتنافسة.
يعرض Martin أيضاً استخدام eBPF عبر مشروع Rezolus للحصول على مقاييس دقيقة من نواة Linux، بما في ذلك المجدول ومسارات استدعاءات النظام ومكدس TCP، من دون تعديل كود النواة. ويظل السؤال المفتوح هو مقدار الدقة والاتساق المطلوبين في كل حالة، وما إذا كانت كلفة القراءة أو جمع الأجزاء ستظل مقبولة عند توسيع النظام.
كيف أعددنا هذا الخبر؟
اعتمد الخبر على المصدر الأصلي الموضح أعلاه. قد نستخدم أدوات آلية للمساعدة في الاستخراج والتصنيف والصياغة،
لكن النشر يخضع لقواعد تمنع المحتوى المكرر والقصير أو الروتيني منخفض القيمة.
اقرأ سياستنا التحريرية.