قابلية المراقبة · OpenTelemetry

Tail Sampling في OpenTelemetry: احتفظ بالدليل دون إغراق الـCollectors

دليل إنتاجي لضبط سعة Tail Sampling في OpenTelemetry عبر توجيه Trace ID ونوافذ القرار وميزانيات السياسات ومعالجة Spans المتأخرة وحماية قابلة للقياس من الحمل الزائد.

المسار المرتبطالسحابة وDevOps وKubernetes
رسم تصوري أصلي لـSpans تدخل إلى Collector shards موجّهة حسب Trace ID، فتُحفظ Traces ذات الأخطاء والبطء بينما تتلاشى العادية؛ وليس لوحة حقيقية أو صورة حدث.
تصوّر بصري للفكرة — يتبعه شرح ومخطط تنفيذي داخل المقال.

يتخذ Head Sampling القرار عند بدء الـTrace، قبل أن يعرف النظام هل سيفشل الطلب أو يصبح بطيئًا. أما Tail Sampling فينتظر تراكم الـSpans، فيستطيع الاحتفاظ بـTrace لأنه يحتوي خطأً أو تجاوز حدًا للزمن أو مر عبر خدمة حرجة. يصبح الدليل أكثر فائدة، لكن القرار يحتاج الآن إلى حالة: يجب أن تحتفظ الـCollectors بأجزاء الـTrace، وتجمع الـSpans القادمة من مسارات مختلفة، وتقيّم السياسات، ثم تصدّر ما اختير قبل نفاد السعة.

تصف OpenTelemetry Tail Sampling بأنه قرار يُتخذ بعد اكتمال Spans الخاصة بالـTrace، خلافًا لقرار Head Sampling عند Root Span. ويوفر Collector Processor الحالي سياسات للحالة والزمن والخصائص والاحتمال وحدود المعدل والحجم. ويعرض مثال أهمية الخدمة نسبًا مختلفة، من الاحتفاظ بالخدمات الحرجة إلى عينة أساس صغيرة للخدمات منخفضة الأهمية.

هذا شرح مبني على الوثائق الحالية، وليس ادعاءً بأن OpenTelemetry أطلقت Tail Sampling اليوم. جرى التحقق من الوثائق المرتبطة في 29 سبتمبر 2026. القيم أدناه فرضيات بداية؛ أما سعة الإنتاج فتُشتق من معدل الـSpans وعرض الـTraces وتأخرها وميزانية الفشل لديك.

وجّه الـTrace كاملة قبل تقييمها

يمكن لموازن Round Robin عادي أن يقسم Spans التابعة للـTrace نفسها بين عدة نسخ من Collector. ترى كل نسخة قصة ناقصة، وقد تصل كل منها إلى قرار مختلف. توصي إرشادات نشر البوابة في OpenTelemetry ببنية من طبقتين لهذه الحالة: تستخدم Collectors في الطبقة الأولى Load-Balancing Exporter بمفتاح واعٍ لـTrace ID، بينما تشغّل الطبقة الثانية Tail-Sampling Processor ذي الحالة. يجب أن تصل كل Spans للـTrace نفسها إلى نسخة واحدة في الطبقة الثانية.

اجعل الطبقة الأولى عديمة الحالة قدر الإمكان. تستقبل OTLP، وتجري معالجة أولية آمنة، ثم توجّه حسب Trace ID. وتمتلك الطبقة الثانية نافذة القرار وتقييم السياسات وDecision Cache. لا يبدأ التصدير إلا بعد قرار الاحتفاظ. يسمح هذا الفصل بتوسيع الاستقبال وفق عدد الاتصالات، وتوسيع طبقة Sampling وفق حالة الـTraces النشطة.

اختبر خاصية التوجيه، لا صحة الـEndpoints فقط. أرسل Trace تأتي Spans الخاصة بها من خدمات وAgents متعددة، ثم تحقق أن نسخة Sampler واحدة تراها كلها. كرر الاختبار أثناء Rolling Deployment وتغير عضوية DNS وتعطل نسخة. قد يكون الـFleet سليمًا ظاهريًا لكنه ينتج دليلًا غير موثوق إذا جزّأ الـTraces.

تعامل مع نافذة القرار كحالة لا كمهلة فقط

يمثل `decision_wait` الفترة من أول Span حتى القرار. تقلل النافذة القصيرة الذاكرة وزمن القرار، لكنها ترفع احتمال وصول Span بطيئة أو متأخرة تحمل الخطأ بعد اتخاذه. تحسن النافذة الأطول الاكتمال، لكنها تضاعف الحالة النشطة.

استخدم التقريب التالي للتخطيط، ثم اختبره تحت الحمل:

الـTraces النشطة ≈ Traces الجديدة/ثانية × نافذة القرار
ميزانية الذاكرة ≈ Traces النشطة × متوسط Spans/Trace × البايتات المحفوظة/Span × معامل أمان

هذا ليس ضمانًا من OpenTelemetry، ولا يشمل كل تخصيصات Go أو مداخل Cache أو Queues. إنه نموذج سعة يجبر القياسات المهمة على الظهور. قس التوزيعات لا المتوسطات فقط: Endpoint ذات Fan-out قد تنشئ مئات Spans، وBurst قد يتجاوز معدل الـTraces المستقر. أضف عبء Runtime وطوابير التصدير ومساحة لـGarbage Collection.

اضبط `num_traces` من تقدير الحالة النشطة مع هامش للاندفاعات. واضبط `expected_new_traces_per_sec` من Percentile مرتفع واقعي، لأن Processor يستخدمه لحجز بنى البيانات. لا ترفع أي قيمة إلا بعد تأكيد حد ذاكرة Pod واختبار سلوك Heap المقابل. الرقم الكبير في YAML ليس سعة إذا كانت العملية لا تستطيع الاحتفاظ به.

حوّل قواعد الاحتفاظ إلى ميزانية صريحة

تبدأ سياسة مفيدة بالدليل الذي لا يمكن إعادة إنتاجه: Traces التشخيصية الإجبارية، والأخطاء، والزمن المرتفع على نحو غير عادي. بعدها تأتي الخدمات الحرجة أو المسارات المنظمة. وتحفظ عينة احتمالية صغيرة من المرور العادي مجموعة مقارنة، وقد تكشف أنماط فشل غير معروفة. وأخيرًا تحد ميزانية معدل أو حجم كلية من التصدير وفق عقد الـBackend.

يحتاج تركيب السياسات إلى اختبارات. قد تحتفظ سياسات Top-level متعددة بالـTrace نفسها، بينما تغيّر `and` و`drop` و`composite` تفاعل الشروط والتوزيعات. توثق مرجعية Processor الحالية Composite Allocation وسياسات تحديد المعدل والحجم. عامل كل قاعدة ككود: امنحها مالكًا، وانتقائية متوقعة، وميزانية قصوى، وتاريخ انتهاء للاستثناءات الطارئة.

لا تساوِ بين وصف الخدمة بالحرجة وبين الاحتفاظ بكل شيء إلى الأبد. يستخدم المثال الرسمي `service.criticality` لنسب مختلفة، لكن التصنيف لا يكون موثوقًا إلا بقدر صحة Resource Attributes الداخلة. راقب القيم المفقودة وغير المعروفة. لا ينبغي لخدمة تغير اسمها وتفقد Criticality Attribute أن تقع صامتة في Default غير محدود أو تختفي من دليل الحادث.

يفصل Tail Sampling الموثوق بين الاستقبال عديم الحالة وحالة مرتبطة بكل Trace، ثم يتخذ قرار الاحتفاظ ضمن ميزانية صريحة للذاكرة والتصدير.
يفصل Tail Sampling الموثوق بين الاستقبال عديم الحالة وحالة مرتبطة بكل Trace، ثم يتخذ قرار الاحتفاظ ضمن ميزانية صريحة للذاكرة والتصدير. اضغط لعرض أكبر

صمّم للـSpans المتأخرة وللحمل الزائد

تتيح Decision Cache للـSpans المتأخرة إعادة استخدام قرار Keep أو Drop السابق بدل بدء قرار ثانٍ. اضبط حجمي Sampled وNon-sampled Caches وفق نافذة التأخر المرصودة، واجعل Cache Misses مرئية. إذا أنتجت Trace Spans بعد انتهاء المدخل، فحدد هل النتيجة المقبولة Trace جزئية، أو Fragment تُسقط عمدًا، أو فترة احتفاظ أطول.

يمكن لـMemory Limiter حماية العملية، لكن إسقاط Spans الداخلة تحت الضغط يجعل الدليل ناقصًا. لذلك هو Circuit Breaker لا خطة سعة. طبّق Admission Control قبل الطبقة، واستخدم Queues محدودة، وافرض ميزانيات معدل أو حجم للـBackend، وأنذر قبل بلوغ الحد الصلب. عند حمل مستمر، خفض عينة المرور العادي عمدًا أكثر أمانًا من فقد Spans عشوائيًا عبر كل السياسات.

توثق مرجعية Processor أيضًا Tail-Storage Extension تجريبية خلف Feature Gate ومعطلة افتراضيًا. لا تتعامل معها كمخرج شفاف من قيود RAM. قيّم المتانة والزمن ودلالات الفشل وتوافق الترقية بوضوح قبل الاعتماد على حالة خارجية تجريبية.

راقب الـSampler كخدمة إنتاجية

اجمع ثلاث مجموعات من الإشارات. تشمل المدخلات: Traces الجديدة/ثانية، وSpans/Trace، والبايتات المسلسلة، وPercentiles التأخر. وتشمل الحالة: Traces النشطة، وHeap وRSS، وتوقفات Garbage Collection، وCache Hits وMisses، وTraces المطرودة قبل القرار. وتشمل المخرجات: Traces وSpans والبايتات المحتفظ بها حسب السياسة، وعمر Export Queue، والإرسالات الفاشلة، وخنق الـBackend.

فعّل إسناد القرار إلى السياسة عندما تسمح حالة الـFeature ومخاطرتها التشغيلية، أو أعد إنتاج الأعداد باختبارات مضبوطة. السؤال ليس هل Collector تعمل فقط، بل هل احتفظت كل سياسة بالدليل الذي وعدت به ضمن ميزانيتها. قد ترفع زيادة Traces ذات الأخطاء حجم التصدير بصورة صحيحة، بينما قد يخفضه غياب Criticality Attribute بصورة خاطئة. يجب أن تميز اللوحة بين الحالتين.

عرّف SLO لاكتمال الدليل. مثلًا: من بين Traces اصطناعية تحتوي عمدًا Error Span، يجب أن تصل النسبة المتوقعة كاملة إلى الـBackend ضمن وقت محدود. شغّل Probes لـTraces طويلة وعريضة، وأخرى بخطأ متأخر، وأخرى تعبر خدمات متعددة. يختبر ذلك المسار الكامل من SDK عبر التوجيه وSampling والتصدير.

استخدم الـTraces المأخوذة بحذر في التحليلات

مجموعة منحازة إلى الأخطاء والطلبات البطيئة ممتازة للتشخيص، لكنها ليست تقديرًا خامًا لتركيب المرور. لا تحسب Product Conversion أو حجم الطلبات أو Percentiles الزمن العامة من Traces مختارة باحتمالات غير متساوية ما لم تحفظ احتمالات صحيحة وتطبقها.

تعرّف مواصفة Probability Sampling في TraceState قيمة عشوائية مشتركة وRejection Threshold، وتشرح Adjusted Count بوصفه مقلوب احتمال Sampling. كما تشير إلى إمكانية دمج Tail وHead Sampling. يظل تكامل TraceState في Collector Processor خلف Feature Gate، لذلك تحقق من الإصدار الدقيق وتركيب السياسات قبل ادعاء صحة إحصائية للأعداد المعدلة. قواعد الاحتفاظ للتشخيص والقياس غير المنحاز مرتبطان، لكنهما ليسا النظام نفسه تلقائيًا.

احتفظ بمقاييس مستقلة للإجماليات وSLOs. استخدم Traces لتفسير السلوك وربط المسارات، واستخدم Counters وHistograms مصممة للتجميع لقياس المجتمع. إذا اشتققت Metrics من Spans مأخوذة، فسجل عقد الاحتمال واختبره من البداية إلى النهاية.

أطلق عبر اختبارات تشبه الفشل

ابدأ بمسار Copy أو Shadow لا يستبدل الدليل الحالي. أعد تشغيل مرور ممثل يشمل نجاحًا عاديًا وأخطاء نادرة وFan-out بطيئًا وTraces عريضة جدًا وSpans متأخرة وAttributes مفقودة. قارن اكتمال الـTrace والبايتات المختارة وأعداد السياسات بإجابة معروفة. ثم نفذ Canary لخدمات قليلة ولا تتوسع إلا بعد تطابق نافذة القرار ونموذج الذاكرة مع الرصد.

اختبر الأعطال التي تغير التوجيه أو الحالة: أوقف Sampler Pod وهي تحتفظ بـTraces، وأضف نسخًا واحذفها، واقطع Exporter، واخنق Backend، وأعد التشغيل أثناء Trace طويلة. تأكد أن التنبيهات تصف الدليل المفقود لا صحة الـPod فقط. وثق وضع الحمل الزائد ومفتاح الرجوع وأقصى Blind Interval مقبولة.

يستحق Tail Sampling تكلفته عندما يحفظ دليلًا كان Head Sampling سيفقده. لذلك ليس التصميم الموثوق مجرد `tail_sampling` مع نسبة. إنه توجيه Trace-affine، وميزانية حالة مقاسة، وسياسات دليل مرتبة، وحدود تصدير صريحة، وسلوك محدد للـSpans المتأخرة، وصدق إحصائي، واختبارات فشل تثبت بقاء الدليل عندما يتعرض النظام للضغط.

المراجع الرسمية

تدعم هذه المراجع سلوك الأدوات المذكورة. الأمثلة وقرارات التصميم توضيحية، ويجب تكييفها مع متطلبات المشروع وإصداراته.

إعداد: Noor Yasser

من القرار إلى التنفيذ

تعمل على تحدٍ تقني مشابه؟

أساعد الفرق على تحويل القرار المعماري إلى نطاق واضح وتنفيذ يمكن تشغيله ومراجعته بثقة.

احجز لقاءً لمدة ٣٠ دقيقةالخدمة المرتبطةتحسين الأداء والبنية السحابية والنشرمشروع من الأعمالمنصة اللوجستيات