المئينات: p50 وp95 وp99
يصف المئين (percentile) كيف تتوزع مجموعة من القياسات. فالمئين الخامس والتسعون، p95، هو القيمة التي تقع عندها أو دونها 95% من القياسات: فإذا كان p95 لزمن استجابة واجهة البحث 600 مللي ثانية، فقد استغرق 95 بحثاً من كل 100 مدة 600 مللي ثانية أو أقل، واستغرقت 5 عمليات بحث أطول من ذلك. أما p50 فهو الوسيط (median)، أي الطلب المعتاد، بينما يصف p95 وp99 الطرف البطيء الذي يسمّيه المختبِرون الذيل (tail).
قدّم درس مقاييس الأداء زمن الاستجابة والإنتاجية ومعدل الأخطاء. ويتناول هذا الدرس تلخيص أزمنة الاستجابة: آلاف القياسات تصبح أرقاماً قليلة تقارنها بهدف محدد، واختيار المئينات بدلاً من المتوسط يحدد هل تظهر الطلبات البطيئة في تقريرك أصلاً.
لماذا يهم
لا يشعر المستخدم بالمتوسط، بل يتذكر طلباته البطيئة. ويمكن لعدد قليل من الطلبات البطيئة جداً أن يختبئ خلف متوسط يبدو سليماً، فقد تصف عبارة «المتوسط 220 مللي ثانية» إصداراً يستغرق فيه طلب من كل عشرة أكثر من ثانية.
والمئينات تجعل الأداء قابلاً للاختبار. فعبارة «يجب أن تكون الواجهة سريعة» لا يمكن أن تفشل، أما «p95 أقل من 500 مللي ثانية عند 200 طلب في الثانية» فيمكن. وتتيح المئينات أيضاً مقارنة نسختين بإنصاف، ووصف الانحدار في الأداء بلغة يستطيع المطور أن يعمل بها.
ما المئين وكيف تحسبه
رتّب كل أزمنة الاستجابة التي قستها لعملية واحدة من الأسرع إلى الأبطأ. فالمئين p هو القيمة التي تقع عندها أو دونها نسبة p بالمئة منها. ولحسابه يدوياً استخدم طريقة الرتبة الأقرب (nearest-rank): rank = ceil(p / 100 × n)، أي p بالمئة من عدد القياسات مقرّبة إلى الأعلى، ثم اقرأ القيمة عند تلك الرتبة.
مع 20 قياساً يكون p50 هو القيمة عند الرتبة 10، وp95 عند الرتبة 19، وp99 عند الرتبة 20، أي أبطأ طلب ببساطة. فدقة المئين محدودة بالبيانات التي يستند إليها: p99 تحدده أبطأ 1% من الطلبات، أي طلبان فقط من 200، لذا يحتاج إلى مئات العيّنات أو آلافها.
- بعض الأدوات يستخدم الرتبة الأقرب، وبعضها يستوفي (interpolation) بين القيم المتجاورة، لذا قد تعطي أداتان رقمين مختلفين للتشغيل نفسه حين تكون العيّنات قليلة. ومع آلاف العيّنات يصبح الفرق صغيراً.
- وتختلف التسميات: تكتب k6 الصيغة
p(95)، ويضم تقرير Aggregate Report في JMeter عموداً باسم95% Line. وتحقّق من المئينات التي يعرضها الملخص؛ ففي k6 تختارها عبر الخيارsummaryTrendStats. - احسب المئينات لكل عملية على حدة: فحص صحة (health check) يستغرق 5 مللي ثانية وبحث يستغرق 400 مللي ثانية في قائمة واحدة ينتجان p95 لا يصف أياً منهما.
ماذا يخبرك كل من p50 وp95 وp99
يجيب كل مئين عن سؤال مختلف، لذا تعرض التقارير عدة مئينات جنباً إلى جنب. وعبارة «1% فقط» أكبر مما تبدو: فعند 50 طلباً في الثانية تعني 30 طلباً بطيئاً كل دقيقة، وإذا أجرت صفحة 10 استدعاءات مستقلة لكل منها احتمال 1% أن يكون أبطأ من p99 الخاص به، فاحتمال أن يكون واحد منها على الأقل بطيئاً هو 1 - 0.99^10، أي نحو 10%.
- p50، الوسيط: نصف الطلبات أسرع منه ونصفها أبطأ. يصف التجربة المعتادة، ويتحرك حين يبطئ تغيير ما كل شيء، كاستعلام فقد فهرسه.
- p95: طلب واحد من كل 20 أبطأ منه. وهو خيار شائع لأهداف الاختبار وأهداف مستوى الخدمة، لأنه يغطي كل الطلبات تقريباً وهو أقل تأثراً بقيمة شاذة واحدة من p99.
- p99: طلب واحد من كل 100 أبطأ منه. هذا هو الذيل، حيث تظهر توقفات جمع المهملات (garbage collection) وتنافس الأقفال والذاكرة المؤقتة الباردة وإعادة المحاولات والتبعيات البطيئة. يحتاج إلى عيّنات كثيرة، وكثيراً ما يرتفع قبل الوسيط كلما زاد الحمل.
- الحد الأقصى طلب واحد: افحصه بحثاً عن انتهاء المهلات، لكنه متقلب جداً فلا يصلح هدفاً. والخدمات ذات الحركة العالية تتابع p99.9 أيضاً.
لماذا يضلّل المتوسط
توزيع أزمنة الاستجابة ملتوٍ: معظم الطلبات يتجمع قرب الطرف السريع، ويمتد ذيل طويل من الطلبات البطيئة نحو القيم الكبيرة. والمتوسط يجمع كل القيم ويقسمها على عددها، فترفعه بضعة طلبات بطيئة، لكنه لا يقول شيئاً عن عدد المستخدمين الذين انتظروا.
خدمتان تعالج كل منهما 100 طلب بمتوسط 200 مللي ثانية. الخدمة A تجيب 20 طلباً في كل من 180 و190 و200 و210 و220 مللي ثانية. والخدمة B تجيب 88 طلباً في 100 مللي ثانية، و7 طلبات في 600، و4 طلبات في 1250، وطلباً واحداً في 2000 مللي ثانية. قيم A هي p50 200 وp95 220 وp99 220 مللي ثانية، وقيم B هي p50 100 وp95 600 وp99 1250 مللي ثانية. فالخدمة B أسرع لمعظم المستخدمين وأبطأ بكثير لغير المحظوظين منهم، ولا تحقق هدف p95 البالغ 500 مللي ثانية إلا الخدمة A.
الخدمة A: 100 طلب، كلها بين 180 و220 مللي ثانية
- ≤ 500 msهدف p95 متحقق
- > 500 msهدف p95 غير متحقق
- 1200 ms p50 = المتوسطنصف الطلبات استغرق 200 مللي ثانية أو أقل، والمتوسط أيضاً 200: حين لا يوجد ذيل يتفق الاثنان.
- 2220 ms p95 = p99ضمن هدف 500 مللي ثانية: حتى أبطأ الطلبات لم تتجاوز 220 مللي ثانية.نجاح
الخدمة B: 88 طلباً في 100 مللي ثانية، و12 طلباً بين 600 و2000 مللي ثانية
- ≤ 500 msهدف p95 متحقق
- > 500 msهدف p95 غير متحقق
- 1100 ms p50 (الوسيط)الطلب المعتاد أسرع بمرتين منه في A.
- 2200 ms المتوسطمطابق تماماً لـA: المتوسط 200 مللي ثانية لا يميّز بين الخدمتين.
- 3600 ms
p95فوق هدف 500 مللي ثانية: 12 طلباً من 100 استغرقت 600 مللي ثانية أو أكثر.فشل - 41250 ms
p99الذيل: 5 طلبات استغرقت 1250 مللي ثانية أو أكثر.
المئينات محسوبة بطريقة الرتبة الأقرب. وأبطأ طلب في الخدمة B، 2000 مللي ثانية، يقع بعد نهاية المحور.
- قد يصف المتوسط طلباً لم يحدث قط: إذا وجد 80% من الطلبات بياناتها في الذاكرة المؤقتة (cache) خلال 20 مللي ثانية، ولم تجدها 20% فاستغرقت 800 مللي ثانية، فالمتوسط 176 مللي ثانية، وهو زمن لم يستغرقه أي طلب.
- لا يصح حساب متوسط المئينات. فـp95 لخادمين، أو ليوم من نوافذ مدة كل منها دقيقة، ليس متوسط قيم p95 الخاصة بها؛ احسبه من القياسات الخام أو من مدرّج تكراري (histogram) مدمج يعدّ الطلبات في كل نطاق من أزمنة الاستجابة.
- الخطأ الذي يعود في 5 مللي ثانية قد يخفض المتوسط والمئينات ويجعل نظاماً معطلاً يبدو سريعاً. أبلغ عن زمن استجابة الطلبات الناجحة ومعدل الأخطاء جنباً إلى جنب.
مثال تطبيقي: 20 طلب بحث
بعد إصدار جديد، يرسل مختبِر 20 طلباً متتالياً إلى واجهة البحث في بيئة ما قبل الإنتاج (staging) من دون حمل آخر، ليتحقق من هدف الفريق: p95 لا يتجاوز 500 مللي ثانية. تضم الكتلة أدناه الأزمنة الخام والقائمة المرتبة والحساب.
- المتوسط: 4400 / 20 = 220 مللي ثانية. يبدو مريحاً، لكن 17 طلباً من 20 كانت أسرع منه، واثنين كانا أبطأ بكثير.
- p50: الرتبة 10 ← 125 مللي ثانية. البحث المعتاد سريع.
- p95: الرتبة 19 ← 600 مللي ثانية. الهدف لم يتحقق، والذي حسم ذلك هو ثاني أبطأ طلب.
- p99: الرتبة 20 ← 1400 مللي ثانية، وهو الحد الأقصى نفسه. عشرون عيّنة لا تكفي لـp99، فلا تذكره في التقرير.
- يذكر التقرير p50 وp95 والحد الأقصى مع حجم العيّنة والحمل، وينص على أن الهدف لم يتحقق، ويسمّي الطلبين البطيئين (الرابع والعاشر) لفحصهما، ويطلب إعادة القياس بعدة مئات من الطلبات تحت الحمل المتفق عليه قبل أي قرار.
Search API, staging, 20 sequential requests, response time in ms
Target: p95 <= 500 ms
As measured: 128 113 96 600 122 136 104 150 117 1400
110 131 194 101 125 240 142 108 163 120
Sorted:
rank 1 2 3 4 5 6 7 8 9 10
ms 96 101 104 108 110 113 117 120 122 125
rank 11 12 13 14 15 16 17 18 19 20
ms 128 131 136 142 150 163 194 240 600 1400
Mean = 4400 / 20 = 220 ms
p50 = rank ceil(0.50 x 20) = 10 -> 125 ms
p95 = rank ceil(0.95 x 20) = 19 -> 600 ms (target 500 ms: not met)
p99 = rank ceil(0.99 x 20) = 20 -> 1400 ms (= the maximum)كتابة أهداف زمن الاستجابة وأهداف مستوى الخدمة بالمئينات
في كتاب Site Reliability Engineering من Google، مؤشر مستوى الخدمة (SLI) قياس محدد بعناية لجانب من الخدمة، مثل زمن استجابة الطلبات، وهدف مستوى الخدمة (SLO) هو القيمة المستهدفة أو النطاق المستهدف له. أما اتفاقية مستوى الخدمة (SLA) فعقد تترتب عليه عواقب إذا لم يتحقق الهدف. وتُكتب أهداف زمن الاستجابة بالمئينات لأنها يجب أن تصدق على المستخدمين جميعاً تقريباً، لا على مستخدم متوسط.
الهدف المكتمل يحدد خمسة أشياء: أي الطلبات (العملية، والناجحة فقط أم الكل)، والمئين، والحد، والنافذة أو مدة الاختبار، والظروف مثل الحمل. و«95% من الطلبات تكتمل خلال 500 مللي ثانية» وp95 ≤ 500 ms شرط واحد. وفي k6 يصبح المعيار عتبات (thresholds): إذا لم تتحقق إحداها فشل التشغيل وانتهى برمز خروج غير صفري، فيستطيع خط CI أن يتوقف عنده. ويحوّل السكربت في نهاية هذا القسم معيار اختبار الحمل أدناه إلى k6: يبدأ السيناريو فيه 200 طلب في الثانية مهما كان زمن الاستجابة، ويرسلها من مجموعة تضم بين 100 و400 مستخدم افتراضي (preAllocatedVUs وmaxVUs)؛ ويشرح الدرس التالي عن المستخدمين المتزامنين ونماذج عبء العمل هذا النموذج المفتوح (Open Model) وكيف يُحدَّد حجم تلك المجموعة. ويقصر المرشّح {expected_response:true} عتبات زمن الاستجابة على الاستجابات الناجحة.
- هدف مستوى خدمة في الإنتاج: «99% من طلبات
GET /products/{id}الناجحة تكتمل خلال 300 مللي ثانية، مقيسة على نافذة متحركة مدتها 28 يوماً». - مستويان لإتمام الشراء: «
p95 ≤ 800 msوp99 ≤ 2 sلطلباتPOST /checkout»، فيُضبط الطلب البطيء المعتاد والذيل معاً. - معيار لاختبار الحمل مشتق من هدف مستوى الخدمة: «لطلبات
GET /searchعند 200 طلب في الثانية لمدة 30 دقيقة:p95 ≤ 500 msوp99 ≤ 1200 msللطلبات الناجحة، ومعدل أخطاء أقل من 0.5%». الأرقام في هذه الأمثلة للتوضيح؛ فالأرقام الحقيقية تأتي من احتياجات المستخدمين وفريق المنتج، لا من معيار.
import http from 'k6/http';
export const options = {
scenarios: {
search: {
executor: 'constant-arrival-rate', // 200 iterations a second, one request each
rate: 200,
timeUnit: '1s',
duration: '30m',
preAllocatedVUs: 100,
maxVUs: 400,
},
},
thresholds: {
'http_req_duration{expected_response:true}': ['p(95)<=500', 'p(99)<=1200'],
http_req_failed: ['rate<0.005'],
},
};
export default function () {
http.get('https://staging.example.com/search?q=lamp');
}أخطاء شائعة
- الإبلاغ عن متوسط زمن الاستجابة وحده، أو تقديمه في العنوان فوق المئينات.
- ذكر p99 من أقل من 100 عيّنة، حيث يكون p99 بطريقة الرتبة الأقرب مجرد أبطأ طلب.
- حساب متوسط المئينات عبر الخوادم أو نقاط النهاية أو النوافذ الزمنية بدلاً من حسابها من البيانات الخام.
- خلط عمليات مختلفة، أو طلبات ناجحة وفاشلة، في مجموعة واحدة من أزمنة الاستجابة.
- كتابة هدف من دون ظروفه: p95 مقيس بمستخدم واحد لا يقول شيئاً عن p95 عند ذروة الحمل.
- مقارنة نتائج أداتين أو تشغيلين دون التأكد من أنهما استخدما طريقة المئين نفسها والطلبات نفسها والحمل نفسه.
من منظور ضمان الجودة
أثناء مراجعة المتطلبات، اطلب أن تُكتب أهداف زمن الاستجابة بالمئينات، وأكملها مع مالك المنتج والمطورين أو مهندسي موثوقية المواقع (SRE) الذين يشغّلون الخدمة: أي العمليات؟ أي مئين؟ أين يُقاس وعلى أي نافذة؟ تحت أي حمل؟ وهل تُحتسب الطلبات الفاشلة؟ فعبارة «يجب أن يكون البحث سريعاً» لا تصبح قابلة للاختبار إلا بعد هذا الحوار.
في كل تقرير، اعرض p50 وp95، وp99 حين تكفي العيّنة، لكل عملية مع حجم العيّنة ومعدل الأخطاء والحمل والأداة وطريقة حساب المئين. وإذا لم يحقق مئين هدفه، فأعطِ المطورين الطلبات البطيئة نفسها بأوقاتها ومعاملاتها، وقارن كل نسخة بسابقتها في الظروف نفسها، حتى يُكتشف الانحدار في الذيل قبل أن يشعر به المستخدمون.
تمرين عملي
افحص إصداراً مقابل هدفه المئيني
أجرى زميلك اختباراً على واجهة سجل الطلبات (order history) في بيئة ما قبل الإنتاج بعد الإصدار 2.8 وكتب: «المتوسط 190 مللي ثانية، أقل بكثير من الهدف 400 مللي ثانية. ناجح». استخرج الحكم الصحيح من المادة أدناه بالورقة والقلم أو بجدول بيانات.
بعد ذلك، على نقطة نهاية تملكها أو مسموح لك باختبارها، قارن المتوسط والوسيط وp95 التي تعرضها أداة Response Time Analyzer.
Order history API, staging, release 2.8, 21 requests sent, no concurrent load
Target: p95 <= 400 ms and p99 <= 1000 ms, successful requests only
Successful (ms): 118 95 136 87 470 110 121 104 158 92
131 960 112 99 144 127 390 107 124 115
Failed: 1 request, HTTP 500 after 9 ms- رتّب أزمنة الاستجابة العشرين الناجحة واحسب المتوسط.
- استخرج p50 وp95 وp99 بطريقة الرتبة الأقرب.
- قارن كل نتيجة بالهدف، وقرّر النجاح أو الفشل، ودوّن ما لا تستطيع 20 عيّنة أن تخبرك به.
- قرّر كيف يُحتسب الطلب الفاشل، ثم اكتب النتيجة في جملتين.
إظهار الإجابة النموذجية
القيم مرتبة: 87, 92, 95, 99, 104, 107, 110, 112, 115, 118, 121, 124, 127, 131, 136, 144, 158, 390, 470, 960. المجموع 3800 مللي ثانية، فالمتوسط 190 مللي ثانية: حساب زميلك صحيح.
p50 = الرتبة 10 = 118 مللي ثانية؛ وp95 = الرتبة 19 = 470 مللي ثانية؛ وp99 = الرتبة 20 = 960 مللي ثانية، أي الحد الأقصى.
الحكم: فاشل. p95 يبلغ 470 مللي ثانية مقابل 400، وطلبان من 20 استغرقا أكثر من 400 مللي ثانية. شرط p99 متحقق على الورق، لكن مع أقل من 100 عيّنة يكون p99 مجرد أبطأ طلب فلا يثبت شيئاً.
يبقى الخطأ HTTP 500 خارج أرقام زمن الاستجابة («الطلبات الناجحة فقط») لكن يجب الإبلاغ عنه: فشل طلب واحد من 21، أي نحو 4.8%. ولو احتُسب لخفض زمنه البالغ 9 مللي ثانية المتوسط إلى نحو 181 مللي ثانية، فجمّل صورة إصدار فاشل.
النتيجة: «الإصدار 2.8 لا يحقق هدف زمن الاستجابة: p95 يبلغ 470 مللي ثانية مقابل 400 (p50 118 مللي ثانية، والحد الأقصى 960 مللي ثانية؛ 20 طلباً ناجحاً متتالياً دون حمل متزامن)، وفشل طلب واحد من 21 بالخطأ HTTP 500. يُعاد القياس بعدة مئات من الطلبات تحت الحمل المتفق عليه، ويُفحص الطلبان الخامس والثاني عشر والخطأ».
أسئلة شائعة
هل p50 هو المتوسط نفسه؟
لا. p50 هو الوسيط: القيمة الوسطى بعد ترتيب القياسات. أما المتوسط فهو المجموع مقسوماً على العدد. ولا يتساويان إلا في التوزيع المتماثل، وأزمنة الاستجابة لها عادةً ذيل بطيء يرفع المتوسط فوق الوسيط.
هل أجعل الهدف p95 أم p99؟
عادةً كليهما ولأسباب مختلفة. p95 يضبط ما تعيشه الطلبات كلها تقريباً، ويحتاج إلى عيّنات أقل من p99 ليستقر؛ وp99 يضبط الذيل الذي يهم حين يرسل المستخدمون طلبات كثيرة أو حين تقع الخدمة خلف خدمات أخرى. أما الحد الأقصى فطلب واحد ومتقلب جداً فلا يصلح هدفاً، لكن انظر إليه دائماً بحثاً عن انتهاء المهلات.
كم طلباً أحتاج للحصول على p99 موثوق؟
أكثر بكثير من 100. فبالرتبة الأقرب يكون p99 لأقل من 100 قياس مجرد أبطأ طلب، ومع 1000 قياس يظل مستنداً إلى أبطأ 10 طلبات فقط. اجمع آلاف العيّنات لكل عملية، أو قِس على نافذة أطول، قبل أن تعامل p99 رقماً مستقراً.
ما الفرق بين هدف مستوى الخدمة وهدف اختبار الأداء؟
هدف مستوى الخدمة (SLO) هدف للخدمة العاملة، يُقاس باستمرار على نافذة مثل 28 يوماً. أما هدف اختبار الأداء فينطبق على تشغيل اختبار واحد في ظروف محددة. ويشتق المختبِرون عادةً هدف الاختبار من هدف مستوى الخدمة، حتى يُرجَّح أن يحافظ الإصدار الذي ينجح في الاختبار على الهدف في الإنتاج.
المراجع
- Site Reliability Engineering: How Google Runs Production Systemsأهداف مستوى الخدمة وميزانيات الخطأ ومراقبة «الإشارات الذهبية الأربع» والتعامل مع الحمل الزائد — الجانب التشغيلي للمرونة.
- Monitoring Distributed Systems — Site Reliability Engineering (Rob Ewaschuk)إرشادات SRE من Google في المراقبة: المراقبة من الخارج (black-box) مقابل المراقبة من الداخل (white-box)، والإشارات الذهبية الأربع — زمن الاستجابة والحركة والأخطاء والتشبّع.
- Grafana k6 documentationالتوثيق الرسمي لأداة Grafana k6، وهي أداة مفتوحة المصدر وقابلة للتوسعة لاختبار الحمل والأداء.
- Apache JMeter User's Manualكيف تُبنى اختبارات الحمل وتُعامَل بالمعاملات وتُشغَّل في JMeter، وكيف تُقرأ مستمعاته وتقاريره.
تدرّب بأدوات متقن
قِس زمن استجابة نقطة نهاية عبر عدة عيّنات: الحد الأدنى والأقصى والمتوسط والوسيط وp95.
شغّل قياس أداء صغيراً وآمناً على نقطة نهاية عامة (بعدد طلبات وتزامن محدودَين) واحصل على الإنتاجية ومئينيات زمن الاستجابة.
قارن أزمنة الاستجابة والأحجام بين نقطتي نهاية (مثل v1 مقابل v2، أو staging مقابل الإنتاج) جنباً إلى جنب.
للتعمّق أكثر
تقدّمك في هذا الموضوع
سجّل الدخول لتتابع تقدّمك
علّم الموضوعات مكتملة، وتابع من حيث توقفت، وافتح امتحانات التخصص.