المقدمة
لطالما كان تحليل الأداء في بيئة الإنتاج مجالاً للشجعان. لسنوات، واجه مهندسو SRE مقايضة غير مريحة: إما إرفاق أدوات تحليل أداء ثقيلة تُدخل زمن استجابة قابلاً للقياس وتخاطر بزعزعة استقرار أعباء العمل الإنتاجية، أو التحليق بدون رؤية والاعتماد على لوحات معلومات المقاييس التي تُظهر الأعراض ولكن لا تكشف أبداً عن الأسباب الجذرية. لقد غيّر ظهور eBPF كتقنية سائدة في نواة Linux هذه المعادلة بشكل جذري. باستخدام eBPF، يمكنك قياس كل طبقة تقريباً من النواة ومساحة المستخدم مع حمل لا يُذكر، مما ينتج نوع بيانات المراقبة العميقة التي كانت متاحة سابقاً فقط في بيئات الاختبار.
eBPF، الذي يرمز إلى extended Berkeley Packet Filter، تطور من أصوله كآلية لتصفية حزم الشبكة إلى آلة افتراضية متعددة الأغراض داخل النواة. يتم التحقق من البرامج المكتوبة لـ eBPF بواسطة النواة قبل التنفيذ، مما يضمن أنها لا تستطيع تعطيل النظام أو الدخول في حلقات لا نهائية أو الوصول إلى ذاكرة غير مصرح بها. هذا الضمان الأمني هو ما يجعل eBPF مناسباً بشكل فريد لتحليل الأداء في الإنتاج. يمكنك إرفاق مسابر بوظائف النواة ونقاط التتبع ومداخل وظائف مساحة المستخدم وعدادات أداء الأجهزة دون إعادة تجميع النواة أو إعادة تشغيل الخدمات.
يغطي هذا الدليل سير العمل العملية التي تستخدمها فرق SRE يومياً لتشخيص مشاكل الأداء في أنظمة Linux الإنتاجية. سنستعرض تحليل أداء المعالج وتحليل زمن الاستجابة واكتشاف تسرب الذاكرة وتتبع الشبكة وتحليل أداء الإدخال/الإخراج باستخدام سلسلة أدوات eBPF القياسية. كل أمر وسكريبت مُعروض هنا تم استخدامه في بيئات إنتاج تعمل بنواة 5.15 وأحدث.
لماذا يغير eBPF تحليل الأداء في الإنتاج
تفرض أدوات التحليل التقليدية تكاليف تجعلها غير عملية في الإنتاج. تشغيل strace على خدمة مشغولة يمكن أن يبطئها بمعامل 100 ضعف أو أكثر لأن strace يستخدم ptrace لاعتراض كل استدعاء نظام، مع التبديل بين السياق بين العملية المتتبعة وعملية التتبع لكل استدعاء. حتى perf، الذي يستخدم عدادات أداء الأجهزة وهو أخف بكثير من strace، لا يزال يتطلب كتابة بيانات العينات على القرص ويمكن أن يولد ضغط إدخال/إخراج كبير تحت معدلات أخذ عينات عالية.
يغير eBPF المعادلة بثلاث طرق مهمة. أولاً، تعمل برامج eBPF داخل النواة، مما يلغي حمل تبديل السياق للأدوات المبنية على ptrace. عندما ترفق kprobe أو tracepoint، ينفذ برنامج eBPF بشكل مضمن مع مسار كود النواة، عادةً بإضافة عشرات النانوثواني فقط لكل استدعاء. ثانياً، يمكن لبرامج eBPF تجميع البيانات داخل النواة باستخدام الخرائط، مما يعني أنه يمكنك حساب الرسوم البيانية والعدادات والملخصات دون نسخ كل حدث إلى مساحة المستخدم. الرسم البياني لزمن الاستجابة الذي سيولد ملايين الأحداث في الثانية مع strace ينتج قراءة خريطة واحدة لكل فترة مع eBPF. ثالثاً، يضمن محقق eBPF السلامة: لا يمكن لبرنامجك إلغاء مرجعية المؤشرات الفارغة أو الوصول إلى ذاكرة خارج الحدود أو الدخول في حلقة لا نهائية.
التأثير العملي مثير. يمكن لأدوات مثل biolatency تتبع كل طلب إدخال/إخراج كتلي على نظام يتعامل مع مئات الآلاف من عمليات الإدخال/الإخراج في الثانية، منتجةً رسماً بيانياً لزمن الاستجابة بأقل من 1% من حمل المعالج. يمكنك تشغيل funclatency ضد وظيفة ساخنة في خادم تطبيقك أثناء خدمة حركة المرور القصوى. هذا ببساطة لم يكن ممكناً مع الأجيال السابقة من أدوات التتبع.
إعداد سلسلة أدوات eBPF
تم توحيد نظام eBPF البيئي حول ثلاث مجموعات أدوات رئيسية: bcc-tools و bpftrace وبرامج CO-RE المبنية على libbpf. كل منها يخدم حالة استخدام مختلفة، ويجب أن تحتوي محطة عمل SRE المجهزة جيداً على الثلاثة.
على أنظمة Ubuntu و Debian، قم بتثبيت سلسلة الأدوات الكاملة:
sudo apt-get update
sudo apt-get install -y bpfcc-tools bpftrace linux-headers-$(uname -r)
sudo apt-get install -y libbpf-dev bpftool
على أنظمة RHEL و Fedora:
sudo dnf install -y bcc-tools bpftrace kernel-devel-$(uname -r)
sudo dnf install -y libbpf-devel bpftool
تحقق من أن نواتك تدعم BTF، وهو مطلوب لميزات bpftrace الحديثة وبرامج CO-RE:
ls /sys/kernel/btf/vmlinux
bpftool btf dump file /sys/kernel/btf/vmlinux format raw | head -c 100
إذا لم يكن BTF متاحاً، ستحتاج إلى التأكد من أن نواتك تم تجميعها مع CONFIG_DEBUG_INFO_BTF=y. معظم نوى التوزيعات من عام 2022 فصاعداً تتضمن دعم BTF.
توفر حزمة bcc-tools عشرات الأدوات الجاهزة التي تغطي سيناريوهات التحليل الأكثر شيوعاً. يتم تثبيتها عادةً كملفات تنفيذية بلاحقة -bpfcc على الأنظمة المبنية على Debian أو مباشرة تحت /usr/share/bcc/tools/ على RHEL. يوفر bpftrace لغة برمجة عالية المستوى لكتابة أوامر قصيرة وسكريبتات مخصصة. يُستخدم libbpf وبرامج CO-RE (Compile Once, Run Everywhere) لبناء أدوات eBPF محمولة بمستوى إنتاجي يتم توزيعها كملفات ثنائية مستقلة.
سير عمل تحليل أداء المعالج
تحليل أداء المعالج هو نقطة البداية الأكثر شيوعاً عند التحقيق في مشاكل الأداء. الهدف هو تحديد الوظائف التي تستهلك أكبر وقت معالج، سواء في مساحة النواة أو مساحة المستخدم، وإنشاء رسوم بيانية لهبية تجعل النقاط الساخنة واضحة بصرياً.
النهج الأبسط يستخدم أداة profile من bcc لأخذ عينات من تتبعات المكدس بتردد ثابت:
sudo profile-bpfcc -F 99 -a --stack-storage-size 16384 30 > /tmp/cpu-stacks.txt
هذا يأخذ عينات من جميع المعالجات بتردد 99 هرتز لمدة 30 ثانية. تردد 99 هرتز يتجنب التراكب مع النشاط المبني على المؤقت الذي يعمل غالباً بتردد 100 هرتز. تحتوي المخرجات على تتبعات مكدس مطوية يمكن تغذيتها مباشرة في أدوات FlameGraph لبريندان غريغ:
git clone https://github.com/brendangregg/FlameGraph.git
cat /tmp/cpu-stacks.txt | FlameGraph/stackcollapse-bpf.pl | FlameGraph/flamegraph.pl > cpu-flame.svg
للتحليل الأكثر استهدافاً، يتيح لك bpftrace تحليل عملية محددة والتصفية حسب المعالج:
sudo bpftrace -e 'profile:hz:99 /pid == 12345/ { @[ustack(perf), comm] = count(); }' > stacks.bt
عندما تحتاج إلى فهم سلوك جدولة المعالج بدلاً من وقت التنفيذ، تُظهر أداة cpudist المدة التي تعمل فيها الخيوط على المعالج قبل إلغاء جدولتها:
sudo cpudist-bpfcc -p 12345 10 1
هذا يطبع رسماً بيانياً لفترات التشغيل على المعالج للعملية 12345 خلال فترة 10 ثوانٍ. أوقات التشغيل القصيرة على المعالج مع تبديلات سياق عالية تشير إلى تنافس على الأقفال. أوقات التشغيل الطويلة على المعالج مع إنتاجية منخفضة تشير إلى اختناقات حسابية.
للتحقيق في مشاكل ترحيل المعالج في أنظمة NUMA، يمكنك تتبع أحداث المجدول:
sudo bpftrace -e 'tracepoint:sched:sched_migrate_task {
printf("pid=%d comm=%s from_cpu=%d to_cpu=%d\n",
args->pid, args->comm, args->orig_cpu, args->dest_cpu);
}'
تحليل زمن الاستجابة
تحليل زمن الاستجابة هو المجال الذي يتألق فيه eBPF حقاً لأنه يمكنه قياس الوقت بين أحداث عشوائية دون التأثير على مسار الكود المُقاس. تتضمن مجموعة bcc-tools عدة أدوات مخصصة لزمن الاستجابة.
يتم قياس زمن استجابة الإدخال/الإخراج الكتلي باستخدام biolatency، الذي يتتبع الوقت من طلب الإدخال/الإخراج الكتلي إلى الاكتمال:
sudo biolatency-bpfcc -D 10 1
علم -D يقسم زمن الاستجابة حسب جهاز القرص، مما يسهل تحديد الأقراص البطيئة. المخرجات هي رسم بياني بقوى العدد اثنين يُظهر توزيع أزمنة الاستجابة بالميكروثواني.
زمن استجابة طابور التشغيل، الذي يقيس المدة التي تنتظرها الخيوط في طابور المجدول قبل الحصول على وقت المعالج، يُقاس باستخدام runqlat:
sudo runqlat-bpfcc -p 12345 10 1
زمن استجابة عالٍ لطابور التشغيل يعني أن عملياتك تنتظر المعالج، مما يشير إلى تشبع المعالج. إذا رأيت أزمنة استجابة أعلى من 10 ميلي ثانية أثناء التشغيل الطبيعي، فإنك تحتاج إلى سعة معالج أكبر أو تحتاج للتحقيق فيما يستهلك المعالج.
زمن استجابة الوظيفة يقيس وقت تنفيذ وظيفة محددة في النواة أو مساحة المستخدم:
sudo funclatency-bpfcc -p 12345 'c:malloc' 10 1
هذا يتتبع استدعاءات malloc في libc للعملية 12345 ويُظهر رسماً بيانياً لزمن الاستجابة. يمكنك تتبع أي وظيفة لها رمز في الملف الثنائي أو المكتبة المشتركة. لوظائف النواة:
sudo funclatency-bpfcc 'vfs_read' 10 1
لتتبع زمن الاستجابة على مستوى التطبيق باستخدام bpftrace، يمكنك قياس الوقت بين نقطتي مسبار:
sudo bpftrace -e '
uprobe:/usr/bin/myapp:process_request { @start[tid] = nsecs; }
uretprobe:/usr/bin/myapp:process_request /@start[tid]/ {
@latency_us = hist((nsecs - @start[tid]) / 1000);
delete(@start[tid]);
}
END { clear(@start); }
'
تحليل الذاكرة
تتراوح مشاكل الذاكرة في الإنتاج من التسربات التدريجية التي تسبب إنهاء OOM على مدار أيام إلى عدم كفاءة التخزين المؤقت التي تُضعف الأداء. يوفر eBPF عدة أدوات لكل فئة.
أداة memleak تتتبع استدعاءات تخصيص وتحرير الذاكرة، وتتبع التخصيصات المعلقة لتحديد التسربات:
sudo memleak-bpfcc -p 12345 --combined-only 30
هذا يرتبط بالعملية 12345 وبعد 30 ثانية يطبع تتبعات المكدس للتخصيصات التي لم يتم تحريرها، مرتبة حسب إجمالي البايتات المعلقة. هذا لا يُقدر بثمن لاكتشاف التسربات في الخدمات طويلة التشغيل دون إعادة تشغيلها مع تمكين تصحيح أخطاء المُخصص المتخصص.
لتتبع تخصيص ذاكرة النواة:
sudo memleak-bpfcc --combined-only 30
بدون علم pid، يتتبع memleak تخصيصات النواة عبر kmalloc و kfree، والتي يمكنها تحديد تسربات ذاكرة النواة الناتجة عن برامج التشغيل أو وحدات النواة.
سلوك التخزين المؤقت له تأثير هائل على أداء التطبيق. توفر أداة cachestat إحصائيات كل ثانية عن ذاكرة التخزين المؤقت للصفحات:
sudo cachestat-bpfcc 5
تتضمن المخرجات الإصابات والأخطاء والصفحات المتسخة ونسب القراءة/الكتابة. نسبة أخطاء عالية تشير إلى أن مجموعة العمل الخاصة بك تتجاوز الذاكرة المتاحة، ويجب أن تفكر فيما إذا كان تطبيقك يحتاج إلى المزيد من RAM أو أنماط وصول أفضل.
يمكن تتبع عمليات إنهاء OOM في الوقت الفعلي لفهم العمليات التي يتم إنهاؤها ولماذا:
sudo bpftrace -e 'kprobe:oom_kill_process {
printf("OOM kill: pid=%d comm=%s pages=%d\n",
((struct task_struct *)arg1)->pid,
((struct task_struct *)arg1)->comm,
arg0);
}'
للحصول على نهج أبسط، تلتقط أداة oomkill من bcc هذا تلقائياً:
sudo oomkill-bpfcc
هذا يطبع سطراً في كل مرة يتم فيها استدعاء OOM killer، بما في ذلك تفاصيل العملية المُسببة والعملية المُنهاة.
تتبع الشبكة
مشاكل أداء الشبكة صعبة التشخيص بشكل سيئ لأنها تتضمن تفاعلات بين التطبيق ومكدس TCP للنواة والبنية التحتية للشبكة. يوفر eBPF أدوات دقيقة لكل طبقة.
أداة tcplife تتتبع أعمار جلسات TCP، وتُظهر متى يتم إنشاء الاتصالات وإغلاقها مع البايتات المنقولة:
sudo tcplife-bpfcc -D
علم -D يتضمن الطوابع الزمنية. كل سطر يُظهر معرف العملية واسم العملية والعناوين المحلية والبعيدة والمنافذ والمدة والبايتات المرسلة/المستلمة. هذا ضروري لتحديد تغير الاتصالات والاتصالات قصيرة العمر غير المتوقعة أو الخدمات التي تحتفظ بالاتصالات مفتوحة لفترة أطول من المتوقع.
إعادة إرسال TCP هي مؤشر حاسم على صحة الشبكة:
sudo tcpretrans-bpfcc -l
علم -l يتضمن مسابير فقدان الذيل. يتم طباعة كل حدث إعادة إرسال مع عناوين المصدر والوجهة والحالة ووظيفة النواة التي أطلقت إعادة الإرسال. تجمعات إعادة الإرسال إلى وجهة محددة تشير إلى مشاكل في مسار الشبكة.
يمكن تتبع الحزم المُسقطة في طبقة TCP باستخدام tcpdrop:
sudo tcpdrop-bpfcc
يتم طباعة كل حزمة مُسقطة مع تتبع مكدس النواة الخاص بها، الذي يخبرك بالضبط لماذا أسقطت النواة الحزمة. تشمل الأسباب الشائعة تجاوز سعة مخزن المقبس وإعادة تعيين الاتصال وضغط الذاكرة.
لتحليل حالة اتصال TCP المفصل، يمكنك كتابة سكريبت bpftrace يتتبع انتقالات الحالة:
sudo bpftrace -e '
tracepoint:tcp:tcp_set_state {
printf("pid=%d sport=%d dport=%d oldstate=%d newstate=%d\n",
pid, args->sport, args->dport, args->oldstate, args->newstate);
}
'
زمن استجابة حل DNS هو مصدر مُغفل في كثير من الأحيان لزمن استجابة التطبيق. يمكنك تتبع عمليات بحث DNS على مستوى المُحلل:
sudo bpftrace -e '
uprobe:/lib/x86_64-linux-gnu/libc.so.6:getaddrinfo { @start[tid] = nsecs; }
uretprobe:/lib/x86_64-linux-gnu/libc.so.6:getaddrinfo /@start[tid]/ {
@dns_us = hist((nsecs - @start[tid]) / 1000);
delete(@start[tid]);
}
'
تحليل أداء الإدخال/الإخراج
الإدخال/الإخراج للتخزين هو أحد أكثر مصادر زمن الاستجابة شيوعاً في الإنتاج، ويوفر eBPF أدوات تتتبع الإدخال/الإخراج على مستويات متعددة من مكدس التخزين.
أداة biosnoop تتتبع عمليات الإدخال/الإخراج الكتلي الفردية مع الطوابع الزمنية وأزمنة الاستجابة وإسناد العملية:
sudo biosnoop-bpfcc -d sda 10
هذا يتتبع كل الإدخال/الإخراج الكتلي لجهاز sda لمدة 10 ثوانٍ، مُظهراً معرف العملية واسم العملية والقرص ونوع العملية والقطاع والبايتات وزمن الاستجابة لكل عملية. هذه هي الأداة المفضلة عندما تحتاج لفهم ما الذي يولد الإدخال/الإخراج بالضبط على قرص محدد.
يوفر التتبع على مستوى نظام الملفات سياقاً أعلى مستوى. أداة ext4slower تتتبع عمليات ext4 التي تتجاوز حداً معيناً لزمن الاستجابة:
sudo ext4slower-bpfcc 10
هذا يطبع جميع عمليات ext4 الأبطأ من 10 ميلي ثانية، بما في ذلك القراءات والكتابات والفتحات والمزامنات. هذا يحدد فوراً عمليات نظام الملفات البطيئة دون الحاجة لربط تتبعات مستوى الكتلة مع بيانات وصفية نظام الملفات.
للتتبع العام لنظام الملفات عبر جميع أنواع أنظمة الملفات، يخدم fileslower نفس الغرض:
sudo fileslower-bpfcc 10
أنماط الكتابة حاسمة لفهم كيف تتفاعل التطبيقات مع التخزين. مكافئ filetop في bpftrace يُظهر الملفات التي تتم قراءتها وكتابتها بأكبر تكرار:
sudo bpftrace -e '
tracepoint:syscalls:sys_enter_write {
@writes[comm, pid] = count();
}
interval:s:5 { print(@writes); clear(@writes); }
'
لأعباء العمل الثقيلة في fsync مثل قواعد البيانات، يمكن أن يكشف تتبع عمليات المزامنة عن أنماط تفريغ غير متوقعة:
sudo bpftrace -e '
kprobe:vfs_fsync_range {
@fsync_latency[comm] = count();
}
kretprobe:vfs_fsync_range {
printf("fsync completed: comm=%s\n", comm);
}
'
بناء أوامر bpftrace المخصصة
تأتي القوة الحقيقية لـ eBPF من القدرة على كتابة برامج تتبع مخصصة مصممة لمكدسك المحدد. تجعل لغة البرمجة الخاصة بـ bpftrace هذا متاحاً لأي شخص يمكنه كتابة سكريبت shell.
البنية الأساسية لأمر bpftrace القصير هي مواصفة المسبار متبوعة بكتلة إجراء. يمكن للمسابير الارتباط بـ kprobes (وظائف النواة) و uprobes (وظائف مساحة المستخدم) و tracepoints (أحداث النواة المستقرة) وأحداث البرمجيات.
عد استدعاءات النظام حسب العملية:
sudo bpftrace -e 'tracepoint:raw_syscalls:sys_enter { @[comm] = count(); }'
رسم بياني لأحجام القراءة حسب العملية:
sudo bpftrace -e 'tracepoint:syscalls:sys_exit_read /args->ret > 0/ {
@read_bytes[comm] = hist(args->ret);
}'
تتبع إنشاء عمليات جديدة مع سطور الأوامر الكاملة:
sudo bpftrace -e 'tracepoint:syscalls:sys_enter_execve {
printf("exec: pid=%d ppid=%d %s\n", pid, curtask->real_parent->pid, str(args->filename));
}'
تتبع فتح الملفات مع المسارات الكاملة:
sudo bpftrace -e 'tracepoint:syscalls:sys_enter_openat {
printf("open: pid=%d comm=%s file=%s\n", pid, comm, str(args->filename));
}'
قياس الوقت الذي يقضيه تطبيقك في وظيفة محددة، مجمعاً حسب مكدس الاستدعاءات:
sudo bpftrace -e '
uprobe:/opt/myapp/bin/server:DatabaseQuery { @start[tid] = nsecs; }
uretprobe:/opt/myapp/bin/server:DatabaseQuery /@start[tid]/ {
@query_ns[ustack(5)] = hist(nsecs - @start[tid]);
delete(@start[tid]);
}
'
للأحداث عالية التكرار، استخدم الخرائط للتجميع داخل النواة وتجنب إرهاق مخزن الإخراج:
sudo bpftrace -e '
tracepoint:syscalls:sys_exit_read /args->ret > 0/ {
@total_bytes[comm] = sum(args->ret);
@total_calls[comm] = count();
}
interval:s:10 {
printf("\n--- Top readers (10s window) ---\n");
print(@total_bytes, 10);
print(@total_calls, 10);
clear(@total_bytes);
clear(@total_calls);
}
'
تكامل التحليل المستمر للأداء
بينما التحليل المخصص باستخدام bpftrace و bcc-tools ضروري للاستجابة للحوادث، يوفر التحليل المستمر رؤية أداء دائمة. يقود هذا المجال مشروعان مفتوحا المصدر: Parca و Pyroscope.
يستخدم Parca eBPF لأخذ عينات مستمرة من تتبعات المكدس عبر جميع العمليات على المضيف مع حمل أدنى. يعمل وكيل Parca كـ DaemonSet في Kubernetes أو خدمة systemd على الأجهزة المعدنية:
sudo parca-agent --remote-store-address=parca-server:7070 \
--node=production-host-01 \
--sampling-ratio=1.0 \
--http-address=:7071
يكتشف الوكيل تلقائياً جميع العمليات الجارية، ويحل الرموز من معلومات التصحيح وبيانات BTF، ويبث بيانات التحليل إلى خادم Parca. يخزن الخادم الملفات الشخصية بتنسيق عمودي محسن لاستعلامات السلاسل الزمنية ويوفر واجهة مستخدم لاستكشاف الرسوم البيانية اللهبية ومقارنة الملفات الشخصية عبر نوافذ زمنية وتحديد الانحدارات.
يتخذ Pyroscope نهجاً مشابهاً لكنه يدعم أوضاع تحليل إضافية بخلاف المعالج، بما في ذلك تحليل تخصيص الذاكرة وتحليل تنافس الأقفال وتحليل goroutine لتطبيقات Go:
# pyroscope-agent.yaml
server-address: http://pyroscope-server:4040
log-level: info
targets:
- service-name: api-server
spy-name: ebpfspy
application-name: api-server
- service-name: worker
spy-name: ebpfspy
application-name: worker-pool
تتكامل كلتا الأداتين مع Grafana لإنشاء لوحات المعلومات والتنبيهات. يتضمن إعداد التحليل المستمر النموذجي:
# Grafana data source configuration for Parca
curl -X POST http://grafana:3000/api/datasources \
-H "Content-Type: application/json" \
-d '{
"name": "Parca",
"type": "parca",
"url": "http://parca-server:7070",
"access": "proxy"
}'
تظهر القيمة الحقيقية للتحليل المستمر بمرور الوقت. عندما يتم نشر انحدار في الأداء، يمكنك مقارنة الملف الشخصي الحالي بخط أساس من قبل النشر ورؤية الوظائف التي تستهلك المزيد من المعالج فوراً. هذا يحول تصحيح أخطاء الأداء من تحقيق تفاعلي إلى نظام كشف استباقي.
أفضل الممارسات والسلامة في الإنتاج
ضمانات سلامة eBPF لا تعني أنه يمكنك تشغيل أي برنامج eBPF على أي نظام إنتاج دون تفكير. بينما يمنع المحقق تعطل النواة، يمكن لبرامج eBPF المكتوبة بشكل سيئ أن تستهلك معالجاً مفرطاً أو تولد مخرجات هائلة أو تتداخل مع أداء النظام.
حدد دائماً حدوداً زمنية على bpftrace و bcc-tools. يجب أن يكون لكل جلسة تحليل مدة صريحة:
# Good: explicit 30-second duration
sudo biolatency-bpfcc 30 1
# Dangerous: runs until manually stopped
sudo biolatency-bpfcc
كن حذراً مع المسابير عالية التكرار. إرفاق kprobe بوظيفة تنطلق ملايين المرات في الثانية سيضيف حملاً قابلاً للقياس حتى لو كان برنامج eBPF نفسه بسيطاً. قبل إرفاق مسبار في الإنتاج، قدّر التكرار:
sudo bpftrace -e 'kprobe:vfs_read { @count = count(); } interval:s:1 { print(@count); clear(@count); }'
إذا انطلقت الوظيفة أكثر من بضع مئات الآلاف من المرات في الثانية، فكر فيما إذا كان يمكنك استخدام tracepoint بدلاً من kprobe، أو إضافة مرشح لتقليل عدد الأحداث المعالجة، أو أخذ عينات بدلاً من تتبع كل حدث.
استخدم علم --dry-run في bpftrace للتحقق من السكريبتات قبل التنفيذ:
sudo bpftrace --dry-run -e 'kprobe:vfs_read { @[comm] = count(); }'
حدد أحجام الخرائط لمنع النمو غير المحدود للذاكرة:
sudo bpftrace -e 'tracepoint:raw_syscalls:sys_enter { @[comm] = count(); }' --map-max-entries=10000
لأنظمة الإنتاج، أنشئ دليل تشغيل لأدوات وسكريبتات eBPF المعتمدة مسبقاً. مجموعة bcc-tools مختبرة جيداً وآمنة للاستخدام في الإنتاج. يجب مراجعة سكريبتات bpftrace المخصصة من قبل الفريق واختبارها في بيئة الاختبار قبل الاستخدام في الإنتاج.
فكر في تشغيل أدوات eBPF داخل حاويات مع القدرات المناسبة بدلاً من الوصول الكامل لـ root:
docker run --rm -it --privileged \
-v /sys/kernel/debug:/sys/kernel/debug:ro \
-v /sys/kernel/btf:/sys/kernel/btf:ro \
-v /proc:/proc:ro \
quay.io/iovisor/bpftrace:latest \
bpftrace -e 'tracepoint:raw_syscalls:sys_enter { @[comm] = count(); }'
أخيراً، وثّق سير عمل التحليل الخاصة بك. عندما يحدث حادث في الثالثة صباحاً، لا تريد أن تكتب سكريبتات bpftrace من الصفر. حافظ على مستودع من سكريبتات التحليل المختبرة المنظمة حسب العرض: معالج عالٍ، زمن استجابة عالٍ، نمو الذاكرة، أخطاء الشبكة، وتشبع الإدخال/الإخراج. يجب أن يتضمن كل سكريبت تعليقات تشرح ما يقيسه والحمل المتوقع وكيفية تفسير المخرجات. يمنحك eBPF قوى خارقة في الإنتاج، لكن فقط إذا كنت قد تدربت على استخدامها قبل وصول حالة الطوارئ.