يستخدم ClickHouse jemalloc باعتباره allocator العام لديه. ويأتي jemalloc مزوّدًا بأدوات لأخذ عينات التخصيص وإجراء التنميط.
يتيح لك ClickHouse وKeeper التحكّم في أخذ العينات باستخدام إعدادات التهيئة، وإعدادات الاستعلام، وأوامر SYSTEM، وأوامر الكلمات ذات الأحرف الأربعة (4LW) في Keeper. وهناك عدة طرق لفحص النتائج:
- اجمع العينات في
system.trace_logتحت النوعJemallocSampleلإجراء تحليل لكل استعلام على حدة. - اعرض إحصاءات الذاكرة المباشرة واسترجع ملف تعريف الكومة عبر واجهة الويب المدمجة لـ jemalloc (26.2+).
- استعلم عن ملف تعريف الكومة الحالي مباشرةً من SQL باستخدام
system.jemalloc_profile_text(26.2+). - نفّذ flush لملفات ملف تعريف الكومة إلى disk ثم حلّلها باستخدام
jeprof.
أخذ عينات من تخصيصات الذاكرة
لأخذ عينات من تخصيصات الذاكرة وتنميطها، شغّل ClickHouse/Keeper مع تفعيل إعداد jemalloc_enable_global_profiler:
<clickhouse>
<jemalloc_enable_global_profiler>1</jemalloc_enable_global_profiler>
</clickhouse>سيأخذ jemalloc عينات من عمليات تخصيص الذاكرة ويخزّن المعلومات داخليًا.
يمكنك أيضًا تمكين أخذ العينات لكل query باستخدام الإعداد jemalloc_enable_profiler.
تخزين عينات jemalloc في system.trace_log
يمكنك تخزين عينات jemalloc في system.trace_log ضمن النوع JemallocSample.
لتمكين ذلك على مستوى النظام بالكامل، استخدم إعداد jemalloc_collect_global_profile_samples_in_trace_log:
<clickhouse>
<jemalloc_collect_global_profile_samples_in_trace_log>1</jemalloc_collect_global_profile_samples_in_trace_log>
</clickhouse>يمكنك أيضًا تفعيل هذا الإعداد لكل query باستخدام jemalloc_collect_profile_samples_in_trace_log.
مثال: تحليل استهلاك الذاكرة لاستعلام
أولًا، شغِّل استعلامًا مع تفعيل مُحلِّل jemalloc واجمع العيّنات في system.trace_log:
SELECT *
FROM numbers(1000000)
ORDER BY number DESC
SETTINGS max_bytes_ratio_before_external_sort = 0
FORMAT `Null`
SETTINGS jemalloc_enable_profiler = 1, jemalloc_collect_profile_samples_in_trace_log = 1
Query id: 8678d8fe-62c5-48b8-b0cd-26851c62dd75
Ok.
0 rows in set. Elapsed: 0.009 sec. Processed 1.00 million rows, 8.00 MB (108.58 million rows/s., 868.61 MB/s.)
Peak memory usage: 12.65 MiB.افرغ system.trace_log:
SYSTEM FLUSH LOGS trace_logثم نفّذ استعلامًا عليه للحصول على الاستخدام التراكمي للذاكرة مع مرور الوقت:
WITH per_bucket AS
(
SELECT
event_time_microseconds AS bucket_time,
sum(size) AS bucket_sum
FROM system.trace_log
WHERE trace_type = 'JemallocSample'
AND query_id = '8678d8fe-62c5-48b8-b0cd-26851c62dd75'
GROUP BY bucket_time
)
SELECT
bucket_time,
sum(bucket_sum) OVER (
ORDER BY bucket_time ASC
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
) AS cumulative_size,
formatReadableSize(cumulative_size) AS cumulative_size_readable
FROM per_bucket
ORDER BY bucket_timeحدِّد الوقت الذي بلغ فيه استخدام الذاكرة أعلى مستوى:
SELECT
argMax(bucket_time, cumulative_size),
max(cumulative_size)
FROM
(
WITH per_bucket AS
(
SELECT
event_time_microseconds AS bucket_time,
sum(size) AS bucket_sum
FROM system.trace_log
WHERE trace_type = 'JemallocSample'
AND query_id = '8678d8fe-62c5-48b8-b0cd-26851c62dd75'
GROUP BY bucket_time
)
SELECT
bucket_time,
sum(bucket_sum) OVER (
ORDER BY bucket_time ASC
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
) AS cumulative_size,
formatReadableSize(cumulative_size) AS cumulative_size_readable
FROM per_bucket
ORDER BY bucket_time
)وباستخدام هذه النتيجة، تعرّف على مكدسات التخصيص الأكثر نشاطًا وقت الذروة:
SELECT
concat(
'\n',
arrayStringConcat(
arrayMap(
(x, y) -> concat(x, ': ', y),
arrayMap(x -> addressToLine(x), allocation_trace),
arrayMap(x -> demangle(addressToSymbol(x)), allocation_trace)
),
'\n'
)
) AS symbolized_trace,
sum(s) AS per_trace_sum
FROM
(
SELECT
ptr,
sum(size) AS s,
argMax(trace, event_time_microseconds) AS allocation_trace
FROM system.trace_log
WHERE trace_type = 'JemallocSample'
AND query_id = '8678d8fe-62c5-48b8-b0cd-26851c62dd75'
AND event_time_microseconds <= '2025-09-04 11:56:21.737139'
GROUP BY ptr
HAVING s > 0
)
GROUP BY ALL
ORDER BY per_trace_sum ASCواجهة مستخدم ويب لـ jemalloc
يوفّر ClickHouse واجهة مستخدم ويب مدمجة لعرض إحصاءات ذاكرة jemalloc عند نقطة نهاية HTTP /jemalloc.
وتعرض مقاييس الذاكرة المباشرة مع مخططات، بما في ذلك الذاكرة المخصصة والنشطة والمقيمة والمعيّنة، بالإضافة إلى إحصاءات كل ساحة وكل bin.
ويمكنك أيضًا جلب ملفات ملف تعريف الكومة العامة وملفات ملف تعريف الكومة لكل استعلام مباشرةً من الواجهة.
http://localhost:8123/jemallocتتضمن واجهة المستخدم الخاصة بالخادم جميع علامات التبويب: Summary وAllocations وArenas وOperations وGlobal Profiler وQuery Profiler وRaw Output.
http://localhost:9182/jemallocتتوفر واجهة مستخدم Keeper على منفذ HTTP control. هذا المنفذ معطّل افتراضيًا ويجب تمكينه صراحةً عبر تعيين keeper_server.http_control.port في تهيئة Keeper:
<clickhouse>
<keeper_server>
<http_control>
<port>9182</port>
</http_control>
</keeper_server>
</clickhouse>بمجرد تمكينه، توفّر الواجهة نفس التصورات التي يوفّرها الخادم — Summary وAllocations وArenas وOperations وGlobal Profiler وRaw Output — باستثناء علامة التبويب Query Profiler التي تتطلب SQL وsystem.trace_log.
يكشف Keeper أيضًا عن نقاط نهاية REST لواجهة برمجة التطبيقات للوصول البرمجي:
GET /jemalloc/stats— مخرجاتmalloc_stats_printالخامGET /jemalloc/status— حالة profiling بصيغة JSON (prof_enabled,prof_active,thread_active_init,lg_sample)GET /jemalloc/profile?format={collapsed|raw}— يُفرغ ملف ملف تعريف الكومة مع تحويل الرموز على جانب الخادم، ويعيد collapsed stacks المناسبة لعرض flame graph (افتراضيًا) أو dump jemalloc الخام
جلب ملفات تعريف heap من SQL
يتيح لك جدول النظام system.jemalloc_profile_text جلب ملف تعريف الكومة الحالي لـ jemalloc وعرضه مباشرةً من SQL، من دون الحاجة إلى أدوات خارجية أو إلى تفريغه إلى القرص أولًا.
يحتوي الجدول على عمود واحد:
| العمود | النوع | الوصف |
|---|---|---|
line |
String | سطر من ملف تعريف الكومة لـ jemalloc بعد تحليل الرموز. |
يمكنك الاستعلام عن الجدول مباشرةً — لا حاجة إلى تفريغ ملف تعريف الكومة مسبقًا:
SELECT * FROM system.jemalloc_profile_textتنسيق الإخراج
يُتحكَّم في تنسيق الإخراج بواسطة الإعداد jemalloc_profile_text_output_format، الذي يدعم ثلاث قيم:
raw— ملف تعريف الكومة خام كما يُنتجه jemalloc.symbolized— تنسيق متوافق مع jeprof مع تضمين رموز الدوال. وبما أن الرموز مضمنة بالفعل، يمكن لـjeprofتحليل المخرجات دون الحاجة إلى ملف ClickHouse التنفيذي.collapsed(الافتراضي) — مكدسات مطوية متوافقة مع FlameGraph، بمكدس واحد في كل سطر مع عدد البايتات.
على سبيل المثال، للحصول على ملف التعريف الخام:
SELECT * FROM system.jemalloc_profile_text
SETTINGS jemalloc_profile_text_output_format = 'raw'للحصول على مخرجات تتضمن الرموز المحلولة:
SELECT * FROM system.jemalloc_profile_text
SETTINGS jemalloc_profile_text_output_format = 'symbolized'إعدادات إضافية
jemalloc_profile_text_symbolize_with_inline(Bool، الافتراضي:true) — ما إذا كان سيتم تضمين الإطارات المضمّنة عند فكّ الرموز. يؤدي تعطيل هذا الخيار إلى تسريع فكّ الرموز بشكل ملحوظ، لكنه يقلل الدقة لأن استدعاءات الدوال المضمّنة لن تظهر في المكدسات. لا يؤثر ذلك إلا في التنسيقينsymbolizedوcollapsed.jemalloc_profile_text_collapsed_use_count(Bool، الافتراضي:false) — عند استخدام التنسيقcollapsed، يتم التجميع حسب عدد التخصيصات بدلًا من البايتات.
مثال: إنشاء مخطط اللهب من SQL
بما أن تنسيق الإخراج الافتراضي هو collapsed، يمكنك تمرير الإخراج مباشرةً إلى FlameGraph:
clickhouse-client -q "SELECT * FROM system.jemalloc_profile_text" | flamegraph.pl --color=mem --title="Allocation Flame Graph" --width 2400 > result.svgلإنشاء مخطط اللهب حسب عدد التخصيصات بدلًا من البايتات:
clickhouse-client -q "SELECT * FROM system.jemalloc_profile_text SETTINGS jemalloc_profile_text_collapsed_use_count = 1" | flamegraph.pl --color=mem --title="Allocation Count Flame Graph" --width 2400 > result.svgتفريغ ملفات تعريف الكومة إلى القرص
إذا كنت بحاجة إلى حفظ ملفات تعريف الكومة كملفات لتحليلها دون اتصال باستخدام jeprof، فيمكنك تفريغها إلى القرص.
افتراضيًا، سيتم إنشاء ملف تعريف الكومة في /tmp/jemalloc_clickhouse._pid_._seqnum_.heap، حيث يشير _pid_ إلى معرّف العملية (PID) الخاص بـ ClickHouse، ويشير _seqnum_ إلى رقم التسلسل العام لملف تعريف الكومة الحالي.
بالنسبة إلى Keeper، يكون الملف الافتراضي هو /tmp/jemalloc_keeper._pid_._seqnum_.heap، ويتبع القواعد نفسها.
لتفريغ ملف التعريف الحالي:
SYSTEM JEMALLOC FLUSH PROFILEسيُرجع مسار ملف التعريف المُفرَّغ.
echo jmfp | nc localhost 9181يمكن تحديد مسار مختلف عبر إضافة الخيار prof_prefix إلى متغير البيئة MALLOC_CONF.
على سبيل المثال، إذا كنت تريد إنشاء ملفات التعريف في المجلد /data بحيث تكون بادئة اسم الملف هي my_current_profile، فيمكنك تشغيل ClickHouse/Keeper باستخدام متغير البيئة التالي:
MALLOC_CONF=prof_prefix:/data/my_current_profileسيُضاف إلى بادئة الملف المُنشأ معرّف العملية PID ورقم تسلسلي.
تحليل ملفات ملف تعريف الكومة باستخدام jeprof
بعد تفريغ ملفات ملف تعريف الكومة إلى القرص، يمكن تحليلها باستخدام أداة jemalloc المسماة jeprof. ويمكن تثبيتها بعدة طرق:
- باستخدام مدير الحزم الخاص بالنظام
- استنساخ مستودع jemalloc وتشغيل
autogen.shمن المجلد الجذر. سيوفّر لك ذلك البرنامج النصيjeprofداخل المجلدbin
تتوفر العديد من تنسيقات الإخراج المختلفة. شغّل jeprof --help للحصول على القائمة الكاملة بالخيارات.
ملفات تعريف الكومة المُرمَّزة بالرموز
اعتبارًا من الإصدار 26.1+، ينشئ ClickHouse تلقائيًا ملفات تعريف كومة مُرمَّزة بالرموز عند تنفيذ عملية flush باستخدام SYSTEM JEMALLOC FLUSH PROFILE.
ويحتوي ملف التعريف المُرمَّز بالرموز (ذو الامتداد .symbolized) على رموز الدوال المضمّنة، ويمكن تحليله باستخدام jeprof دون الحاجة إلى الملف التنفيذي لـ ClickHouse.
على سبيل المثال، عند تشغيل:
SYSTEM JEMALLOC FLUSH PROFILEسيُرجع ClickHouse مسار ملف التعريف المُرمَّز بالرموز (على سبيل المثال، /tmp/jemalloc_clickhouse.12345.0.heap.symbolized).
يمكنك بعد ذلك تحليله مباشرةً باستخدام jeprof:
jeprof /tmp/jemalloc_clickhouse.12345.0.heap.symbolized --output_format [ > output_file]إذا كان لديك ملف تعريف قديم للذاكرة غير مُرمَّز بالرموز وما زال بإمكانك الوصول إلى الملف التنفيذي لـ ClickHouse، فيمكنك استخدام الطريقة التقليدية:
jeprof path/to/clickhouse path/to/heap/profile --output_format [ > output_file]عند مقارنة ملفَّي تعريف، يمكنك استخدام الوسيط --base:
jeprof --base /path/to/first.heap.symbolized /path/to/second.heap.symbolized --output_format [ > output_file]أمثلة
استخدام ملفات التعريف مُرمَّزة بالرموز (مُستحسن):
- أنشئ ملفًا نصيًا تُكتب فيه كل دالة في سطر منفصل:
jeprof /tmp/jemalloc_clickhouse.12345.0.heap.symbolized --text > result.txt- أنشئ ملف PDF يتضمن مخطط الاستدعاءات:
jeprof /tmp/jemalloc_clickhouse.12345.0.heap.symbolized --pdf > result.pdfاستخدام ملفات التوصيف غير المُرمَّزة بالرموز (يتطلب ملفًا تنفيذيًا):
- أنشئ ملفًا نصيًا بحيث يُكتب كل إجراء في سطر مستقل:
jeprof /path/to/clickhouse /tmp/jemalloc_clickhouse.12345.0.heap --text > result.txt- أنشئ ملف PDF يحتوي على مخطط الاستدعاءات:
jeprof /path/to/clickhouse /tmp/jemalloc_clickhouse.12345.0.heap --pdf > result.pdfإنشاء مخطط اللهب
يتيح لك jeprof إنشاء مكدس مطوي لاستخدامها في إنشاء مخططات اللهب.
تحتاج إلى استخدام الوسيط --collapsed:
jeprof /tmp/jemalloc_clickhouse.12345.0.heap.symbolized --collapsed > result.collapsedأو باستخدام ملف تعريف غير مُرمَّز بالرموز:
jeprof /path/to/clickhouse /tmp/jemalloc_clickhouse.12345.0.heap --collapsed > result.collapsedبعد ذلك، يمكنك استخدام العديد من الأدوات المختلفة لتصوّر مكدس مطوي.
الأكثر شيوعًا هو FlameGraph، ويتضمن برنامجًا نصيًا يسمى flamegraph.pl:
cat result.collapsed | /path/to/FlameGraph/flamegraph.pl --color=mem --title="Allocation Flame Graph" --width 2400 > result.svgهناك أداة أخرى مفيدة للاهتمام، وهي speedscope، تتيح لك تحليل المكدسات التي جُمعت بطريقة أكثر تفاعلية.
خيارات إضافية لـ Profiler
يوفّر jemalloc العديد من الخيارات المرتبطة بـ Profiler، ويمكن التحكم فيها عبر تعديل متغير البيئة MALLOC_CONF.
على سبيل المثال، يمكن التحكم في الفاصل الزمني بين عينات التخصيص باستخدام lg_prof_sample.
إذا كنت تريد إخراج ملف تعريف الكومة كل N بايت، فيمكنك تفعيل ذلك باستخدام lg_prof_interval.
يُنصح بالرجوع إلى الصفحة المرجعية الخاصة بـ jemalloc للحصول على قائمة كاملة بالخيارات.
موارد أخرى
يعرض ClickHouse/Keeper مقاييس مرتبطة بـ jemalloc بطرق عديدة ومختلفة.
جدول النظام asynchronous_metrics
SELECT *
FROM system.asynchronous_metrics
WHERE metric LIKE '%jemalloc%'
FORMAT Verticalجدول النظام jemalloc_bins
يحتوي على معلومات عن تخصيصات الذاكرة التي يجريها مُخصِّص jemalloc عبر فئات الأحجام المختلفة (bins)، والمجمّعة من جميع الساحات.
جدول النظام jemalloc_stats (26.2+)
يعرض الناتج الكامل للدالة malloc_stats_print() كسلسلة نصية واحدة. وهو مكافئ للأمر SYSTEM JEMALLOC STATS.
SELECT * FROM system.jemalloc_statsPrometheus
تُعرَض أيضًا جميع المقاييس المتعلقة بـ jemalloc من asynchronous_metrics عبر نقطة نهاية Prometheus في كلٍّ من ClickHouse وKeeper.
أمر jmst 4LW في Keeper
يدعم Keeper الأمر jmst 4LW الذي يعرض إحصاءات أساسية للمخصِّص:
echo jmst | nc localhost 9181