الانتقال إلى المحتوى الرئيسي
يوضح لك هذا الدليل العملي كيفية صيانة بيانات rollup مُسبقة التجميع انطلاقًا من جدول أحداث كبير الحجم باستخدام العروض المادية. ستنشئ ثلاثة كائنات: جدولًا خامًا، وجدول rollup، والعرض المادي الذي يكتب إلى جدول الـrollup تلقائيًا.

متى تستخدم هذا النمط

استخدم هذا النمط عندما:
  • يكون لديك تدفّق أحداث للإلحاق فقط (النقرات، مشاهدات الصفحات، إنترنت الأشياء، السجلات).
  • تكون معظم الاستعلامات عمليات تجميع عبر نطاقات زمنية (لكل دقيقة/ساعة/يوم).
  • تريد عمليات قراءة متسقة بأقل من ثانية من دون إعادة فحص جميع الصفوف الخام.
1

إنشاء جدول الأحداث الخام

ملاحظات
  • PARTITION BY toYYYYMM(event_time) يُبقي الأقسام صغيرة ويسهّل حذفها.
  • ORDER BY (event_time, user_id) يدعم الاستعلامات المقيّدة زمنيًا + عامل تصفية ثانوي.
  • LowCardinality(String) يوفّر الذاكرة للأبعاد الفئوية.
  • TTL ينظّف البيانات الخام بعد 90 يومًا (اضبطه وفقًا لمتطلبات الاحتفاظ لديك).
2

صمّم جدول الـ rollup (المجمّع)

سنُجري التجميع المسبق على مستوى الساعة. اختر مستوى التفاصيل بما يتوافق مع نطاق التحليل الأكثر شيوعًا.
نحن نخزّن حالات التجميع (مثل AggregateFunction(sum, ...)) التي تمثّل بشكل مضغوط قيم تجميع جزئية، ويمكن دمجها أو تحويلها إلى نتائج نهائية لاحقًا.
3

أنشئ عرضًا ماديًا يملأ الـ rollup

يعمل هذا العرض المادي تلقائيًا عند إدراج بيانات في events_raw ويكتب حالات التجميع إلى الـ rollup.
4

أدرِج بعض البيانات النموذجية

أدرِج بعض البيانات النموذجية:
5

الاستعلام عن الـ rollup

يمكنك إما دمج حالات التجميع عند القراءة، أو تحويلها إلى قيم نهائية:

إذا كنت تتوقع أن تستهدف عمليات القراءة دائمًا الـ rollup، فيمكنك إنشاء عرض مادي ثانٍ يكتب قيمًا نهائية إلى جدول MergeTree «عادي» وبنفس الدقة 1h. تمنح حالات التجميع مرونة أكبر، بينما تجعل القيم النهائية عمليات القراءة أبسط قليلًا.
6

صفِّ البيانات حسب الحقول في المفتاح الأساسي للحصول على أفضل أداء

يمكنك استخدام الأمر EXPLAIN لمعرفة كيفية استخدام الفهرس لتقليص نطاق البيانات:
Query
Response
تُظهر خطة تنفيذ الاستعلام أعلاه استخدام ثلاثة أنواع من الفهارس: فهرس MinMax، وفهرس التقسيم، وفهرس المفتاح الأساسي. يستخدم كل فهرس الحقول المحددة في مفتاحنا الأساسي: (bucket_start, country, event_type). وللحصول على أفضل أداء في التصفية، احرص على أن تستخدم استعلاماتك حقول المفتاح الأساسي لاستبعاد البيانات غير اللازمة.
7

أشكال شائعة

  • مستويات دقة مختلفة: أضِف تجميعًا يوميًا:
ثم عرض مادي ثانٍ:
  • الضغط: طبّق ترميزات الضغط على الأعمدة الكبيرة (مثال: Codec(ZSTD(3))) في الجدول الخام.
  • التحكم في التكلفة: اجعل عبء الاحتفاظ المكثّف في الجدول الخام، واحتفظ بالتجميعات المُلخّصة طويلة الأمد.
  • الاستدراك: عند تحميل البيانات التاريخية، أدرِجها في events_raw ودَع materialized view ينشئ التجميعات المُلخّصة تلقائيًا. بالنسبة إلى الصفوف الموجودة، استخدم POPULATE عند إنشاء materialized view إذا كان ذلك مناسبًا، أو INSERT SELECT.
8

التنظيف والاحتفاظ

  • زِد مدة TTL للبيانات الخام (مثلًا، 30/90 يومًا)، مع الإبقاء على البيانات المُجمَّعة لفترة أطول (مثلًا، سنة واحدة).
  • يمكنك أيضًا استخدام TTL للنقل لنقل الأجزاء القديمة إلى وحدة تخزين أقل تكلفة إذا كان التخزين المتدرج مفعّلًا.
9

استكشاف الأخطاء وإصلاحها

  • هل لا يتم تحديث العرض المادي؟ تحقّق من أن عمليات الإدراج تتم إلى events_raw (وليس إلى جدول الـ rollup)، وأن وجهة العرض المادي صحيحة (TO events_rollup_1h).
  • هل الاستعلامات بطيئة؟ تأكّد من أنها تصل إلى الـ rollup (من خلال الاستعلام من جدول الـ rollup مباشرةً)، وأن عوامل تصفية الوقت تتوافق مع مستوى التجميع في الـ rollup.
  • هل توجد حالات عدم تطابق في backfill؟ استخدم SYSTEM FLUSH LOGS وتحقّق من system.query_log / system.parts للتأكد من عمليات الإدراج وعمليات الدمج.
آخر تعديل في ٢٥ يونيو ٢٠٢٦