هذه ميزة في private preview، وقد تتغير مستقبلًا على نحو غير متوافق مع الإصدارات السابقة.
فعِّل استخدام محرك الجدول TimeSeries
باستخدام الإعداد
enable_time_series_table.
أدخِل الأمر set enable_time_series_table = 1.محرك الجدول
TimeSeries متاح في ClickHouse Cloud كميزة في private preview.
الخدمات المشارِكة في private preview لديها بالفعل الإعداد
enable_time_series_table مهيَّأً. أما خدمات ClickHouse Cloud الأخرى
فلا تتوفر لديها هذه التهيئة، ولا يمكنك تفعيل المحرك بنفسك على
مثل هذه الخدمة.الصياغة
للكلمة المفتاحية
SAMPLES اسم مستعار هو DATA، وللكلمة المفتاحية METRIC FAMILIES اسم مستعار هو METRICS، وقد أُبقي على كليهما للحفاظ على التوافق مع الإصدارات السابقة.
يُكتب تعريف الجدول الخاص بأي version أقدم من 4 باستخدام METRICS، حتى يتمكن خادم أقدم من قراءته.الاستخدام
من الأسهل البدء بالإعدادات الافتراضية لكل شيء (يُسمح بإنشاء جدولTimeSeries من دون تحديد قائمة بالأعمدة):
الأعمدة الخارجية
تُنشأ أعمدة جدول TimeSeries تلقائيًا. وهذه هي الأعمدة الخارجية؛ فهي لا تخزّن أي بيانات، وإنما توفّر فقط واجهة لـ SELECT/INSERT. وتُخزَّن البيانات الفعلية في الجداول الهدف. وفيما يلي قائمة الأعمدة الخارجية:
مثال:
metric_name فارغة عند الإدخال، ما يعني أن اسم المقياس يُحدَّد في tags ضمن __name__، على سبيل المثال:
metric_family وtype وunit وhelp:
تحديد الأعمدة الخارجية
يمكن إدراج العمود الخارجيsamples صراحةً في عبارة CREATE TABLE لاستبدال نوعه الافتراضي Array(Tuple(DateTime64(3), Float64)) (كما يُقبل اسمه القديم time_series أيضاً). يستخرج ClickHouse نوعَي الطابع الزمني والقيمة scalar من الـ tuple ويُمرّرهما إلى جدول العينات الداخلي:
INNER COLUMNS الخاصة بجدول samples:
CREATE TABLE نفسها، فيجب أن تتطابق الأنواع المُعلنة.
الجداول الهدف
لا يحتوي جدولTimeSeries على بيانات خاصة به، إذ يُخزَّن كل شيء في جداوله الهدف.
وهذا يشبه طريقة عمل العرض المادي،
مع فارق أن العرض المادي له جدول هدف واحد،
بينما يحتوي جدول TimeSeries على ثلاثة جداول هدف إلزامية باسم samples وtags وعائلة المقياس،
وجدول هدف اختياري لـ العينات الحديثة يكون مُمكّنًا افتراضيًا
(انظر الإعداد recent_samples_ttl_seconds).
يمكن تحديد الجداول الهدف صراحةً في استعلام CREATE TABLE
أو يمكن لمحرك الجدول TimeSeries إنشاء الجداول الهدف الداخلية تلقائيًا.
تُحوَّل الصفوف المُدرجة في جدول TimeSeries، وتُقسَّم إلى كتل، ثم تُدرج في هذه الجداول الهدف.
الجداول الهدف هي كما يلي:
جدول العينات
يحتوي جدول samples على سلاسل زمنية مرتبطة بمعرّف معيّن. يجب أن يحتوي جدول samples على الأعمدة التالية:
تستخدم الأعمدة التي ينشئها المحرك تلقائيًا برامج ترميز ضغط للسلاسل الزمنية:
timestamp CODEC(Delta, T64, ZSTD(3)) وvalue CODEC(ALP, ZSTD(3)). بالكاد
تُضغط الطوابع الزمنية شبه الرتيبة باستخدام برامج الترميز العامة، وقد تستحوذ لولا ذلك على معظم حجم جدول العينات على القرص.
يفعّل المحرك ALP لجداول العينات الداخلية وجداول العينات الحديثة الخاصة به دون الحاجة إلى ضبط enable_alp_codec.
انظر أيضًا ضبط أنواع الأعمدة.
جدول العينات الحديثة
جدول العينات الحديثة اختياري ومُفعّل افتراضيًا (راجع إعداد recent_samples_ttl_seconds؛ إذ يؤدي ضبطه على صفر إلى تعطيل الجدول). يحتوي على نسخة من العينات الأحدث من قيمة TTL التي يحددها هذا الإعداد، ويجب أن يتضمن الأعمدة نفسها الموجودة في جدول العينات. يستخدم العمود المُولَّدtimestamp الترميز CODEC(Delta, T64, ZSTD(3))،
ويستخدم العمود المُولَّد value الترميز CODEC(ALP, ZSTD(3)).
تُكتب كل عينة مُدرجة في كلٍّ من جدول العينات وجدول العينات الحديثة.
تقرأ الاستعلامات التي يقع نطاقها الزمني ضمن نافذة TTL من جدول العينات الحديثة بدلًا من جدول العينات الرئيسي
لأنه أصغر بكثير (يمكن تعطيل ذلك باستخدام إعداد على مستوى الاستعلام time_series_prefer_recent_samples_table).
تُشتق قيمة TTL لجدول العينات الحديثة الداخلي دائمًا من إعداد recent_samples_ttl_seconds.
جدول الوسوم
يحتوي جدول tags على المعرّفات المحسوبة لكل توليفة من اسم مقياس والوسوم. يجب أن يحتوي جدول tags على الأعمدة التالية:
تحتوي جداول الوسوم الداخلية الجديدة من version 5 فما بعد، والتي تستخدم محركًا من عائلة
MergeTree، على فهرس نصي معكوس على tags:
INDEX tags_idx tags TYPE text(tokenizer = 'keyValuePairs'). وهو يسرّع المطابقات التامة للوسوم مثل
{job="api"} في PromQL عبر البحث عن المفتاح والقيمة معًا. أما المقارنات مع سلسلة فارغة فتطابق أيضًا الوسوم المفقودة ولا تستفيد من هذا الفهرس.
تحلّ الفهارس الصريحة المعلَنة في TAGS INNER COLUMNS محل الفهرس الافتراضي. أما الجداول الموجودة وجداول الوسوم الخارجية فتحتفظ بفهارسها؛ ولتفعيله عليها، أضف الفهرس وجسّده على جدول الهدف الخاص بوسومها.
جدول عائلات المقاييس
يحتوي جدول metric families على بعض المعلومات حول عائلات المقاييس التي تُجمع، وأنواع تلك العائلات وأوصافها. عائلة المقياس هي مجموعة من المقاييس التي تحمل الاسم نفسه (الوسم__name__) والنوع نفسه، فعلى سبيل المثال المُدرَّج التكراري هو عائلة مقياس تتكون من عدة مقاييس.
يجب أن يحتوي جدول metric families على الأعمدة التالية:
الإنشاء
توجد عدة طرق لإنشاء جدول باستخدام محرك الجدولTimeSeries.
أبسط عبارة
SHOW CREATE TABLE my_table):
INNER COLUMNS. وكُتب الإعداد recent_samples_ttl_seconds في عبارة SETTINGS
بقيمته الافتراضية: يحدد الإعداد TTL لجدول العينات الحديثة، لذا تُثبَّت قيمته الفعلية عند الإنشاء.
كما جرى تثبيت أحدث إصدار من المخطط في الإعداد version (انظر إصدارات المخطط).
تحمل الجداول الهدف الداخلية أسماء مثل .inner_id.samples.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx،
و.inner_id.recentsamples.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx، و.inner_id.tags.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx،
و.inner_id.metricfamilies.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
ولكل جدول هدف مجموعته الخاصة من الأعمدة:
إنشاء جدول AS جدول موجود
تنشئ العبارةCREATE TABLE new_table AS existing_table جدول TimeSeries مهيأً على غرار existing_table،
الذي يجب أن يكون بدوره جدول TimeSeries. لا تُنسخ الأهداف الخارجية لـ existing_table؛ إذ يجب أن تعرّفها العبارة
بنفسها.
تنسخ العبارة من existing_table:
- عبارة
SETTINGS، باستثناءversion: يحصل الجدول الجديد دائمًا على أحدث إصدار. تُدمج الإعدادات المكتوبة في العبارة نفسها مع الإعدادات المنسوخة بحسب الاسم، لذا يتقدم الإعداد المكتوب على الإعداد المنسوخ، ويؤديname = DEFAULTإلى إعادة ضبط إعداد منسوخ إلى قيمته الافتراضية؛ - عبارتا
INNER COLUMNSوINNER ENGINEلكل جدول داخلي. يُحتفظ بالأعمدة المخصصة (مثل الأعمدة الإضافية والأعمدة التي تحتوي على برنامج ترميز الضغط أو تعبير DEFAULT) وأجزاء المحرك المخصصة (مثل محرك ذي arguments أو sorting key مخصص أو إعداد للمحرك)، بينما تُضبط الأعمدة وأجزاء المحرك الأخرى وفقًا لإعدادات الجدول الجديد، بحيث تسري، على سبيل المثال، قيمtags_to_columnsأوaggregate_min_time_and_max_timeأوtags_index_granularityالمكتوبة في العبارة.
id والطابع الزمني والقيمة، ونوع النسخ المتماثل للمحركات الداخلية (MergeTree،
ReplicatedMergeTree أو SharedMergeTree) من existing_table، ما لم تعرّفها العبارة بنفسها.
تُعاد إنشاء قائمة الأعمدة الخارجية ولا تُنسخ.
يمكن استخدام جدول أنشأه إصدار أقدم من ClickHouse بصفته existing_table: يحصل الجدول الجديد على
البنية الحالية، مثل نوع id الحالي وتعبير المعرّف الافتراضي.
ضبط أنواع الأعمدة
يمكنك ضبط أنواع الأعمدة في الجداول الهدف الداخلية باستخدام عبارةINNER COLUMNS. على سبيل المثال، لتخزين الطوابع الزمنية بالميكروثانية والقيم كـ Float32، استخدم:
العمود id
يحتوي العمود id على معرّفات، ويُحتسب كل معرّف استنادًا إلى تركيبة من اسم المقياس والوسوم.
يمكن تخصيص النوع وتعبير DEFAULT المستخدم لتوليد المعرّفات عبر العبارة TAGS INNER COLUMNS:
id من أي نوع غير Nullable قابل للمقارنة. يجب أن تتطابق أنواع id المُعلنة في الجدولين الداخليين samples وtags.
إذا لم يتم تحديد التعبير DEFAULT للعمود id ولم يكن الإعداد id_generator مُعيَّنًا، فسيختار ClickHouse التعبير DEFAULT تلقائيًا بناءً على نوع id، ولكن فقط إذا كان نوع id أحد الأنواع UUID أو UInt64 أو UInt128 أو FixedString(16)، أو الأنواع نفسها المغلّفة بـLowCardinality، أو زوجًا من اثنين من هذه الأنواع. بالنسبة إلى هذا الزوج، يحسب التعبير المختار تلقائيًا تجزئةً لاسم المقياس في المكوّن الأول وتجزئةً لجميع الوسوم في المكوّن الثاني.
يُبقي نوع المعرّف LowCardinality، مثل Tuple(UInt64, LowCardinality(UUID))، المعرّفات مُرمَّزة بالقاموس: إذ يخزّن جدول samples قواميس صغيرة لكل كتلة مع فهارس القاموس بدلًا من تكرار المعرّف الكامل في كل صف، مما يقلل كمية البيانات التي تقرؤها الاستعلامات.
يوفّر الإعداد id_generator مستوى التخصيص نفسه من دون استخدام العبارة INNER COLUMNS:
id حتى إذا كانت قيمة DEFAULT الخاصة بالعمود تحتوي على تعبير مختلف.
يمكن أيضًا تحديد نوع العمود id في الإعداد id_type بدلًا من العبارة INNER COLUMNS:
id_generator مُعيَّنًا، يُسجَّل الإعداد id_type تلقائيًا عند CREATE،
بحيث يحتفظ التعريف بالنوع الذي كُتب التعبير من أجله.
العمود tags
يحتوي العمود tags على جميع وسوم السلسلة الزمنية، بما في ذلك الوسم __name__ الذي يحتوي على اسم المقياس.
يتيح الإعداد tags_to_columns تحديد وسم معيّن لتخزينه أيضًا في عمود منفصل
بالإضافة إلى الخريطة داخل العمود tags:
instance وjob إلى جدول الوسوم الهدف الداخلي.
ستُخزَّن قيم الوسمين instance وjob في العمودين المذكورين وفي العمود tags.
في الجداول التي أنشأتها إصدارات أقدم من ClickHouse، يحتوي العمود
tags على الوسوم التي لا توجد لها
أعمدة مخصصة فقط، ولا يتضمن اسم المقياس، بينما يكون العمود all_tags عمودًا مؤقتًا جرى ملؤه عند الإدراج
بجميع الوسوم باستثناء اسم المقياس.محركات الجداول الخاصة بالجداول الهدف الداخلية
تستخدم الجداول الهدف الداخلية، افتراضيًا، محركات الجداول التالية:- يستخدم جدول العينات محرك MergeTree;
- يستخدم جدول العينات الحديثة محرك MergeTree مقسمًا إلى حاويات زمنية مدتها 5 ساعات (راجع إعداد recent_samples_partition_by) مع قيمة
TTLمشتقة من إعداد recent_samples_ttl_seconds ومع تمكينttl_only_drop_parts، بحيث تُحذف الأجزاء المنتهية الصلاحية كاملةً؛ - يستخدم جدول الوسوم محرك AggregatingMergeTree لأن البيانات نفسها تُدرج في هذا الجدول غالبًا عدة مرات، لذا نحتاج إلى طريقة
لإزالة التكرارات، وكذلك لأن التجميع مطلوب للعمودين
min_timeوmax_time; - يستخدم جدول عائلات المقاييس محرك ReplacingMergeTree لأن البيانات نفسها تُدرج في هذا الجدول غالبًا عدة مرات، لذا نحتاج إلى طريقة لإزالة التكرارات.
default_table_engine:
فعند استخدام default_table_engine = ReplicatedMergeTree أو SharedMergeTree، تستخدم الجداول الداخلية محركات
Replicated أو Shared المقابلة. ومع default_table_engine = None (أو أي قيمة أخرى)، يجب
تحديد محركات الجداول الداخلية صراحةً.
يجب أن تكون جميع الجداول الداخلية من نفس نوع النسخ المتماثل: فإذا كان أحدها متماثلًا (أو مشتركًا)، يجب أن تكون الجداول الداخلية
الأخرى متماثلة (أو مشتركة) أيضًا، وإلا فستتباين محتوياتها بين النسخ المتماثلة. على سبيل المثال،
يتطلب تعريف SAMPLES INNER ENGINE = ReplicatedMergeTree(...) أن تكون المحركات الداخلية الأخرى متماثلة أيضًا -
إما بتعريفها صراحةً أو بإنشائها باستخدام default_table_engine = ReplicatedMergeTree.
كما يمكن استخدام محركات جداول أخرى للجداول الهدف الداخلية إذا تم تحديد ذلك:
tags) خارج مفتاح الفرز الخاص به،
وهو ما يرفضه AggregatingMergeTree افتراضيًا (راجع allow_dimensions_outside_sorting_key).
وهذا آمن هنا لأن تلك الأعمدة تعتمد وظيفيًا على id، وهو جزء من مفتاح الفرز، لذا فإن جميع
الصفوف التي تدمجها عملية دمج في الخلفية معًا تتشارك القيم نفسها. وعندما يُنشأ جدول الوسوم الداخلي أو يُحدَّد محركه inline كما هو موضح أعلاه، يضبط TimeSeries القيمة allow_dimensions_outside_sorting_key = 1 عليه تلقائيًا؛
أما بالنسبة إلى جدول الوسوم التجميعي الخارجي الذي يُنشأ يدويًا، فيجب عليك تعيين هذا الإعداد بنفسك.
الجداول الهدف الخارجية
يمكن إعداد جدولTimeSeries لاستخدام جدول أُنشئ يدويًا:
RECENT SAMPLES my_recent_samples_table).
يجب أن يحتوي هذا الجدول على الأعمدة نفسها الموجودة في جدول عينات خارجي، وأن يحتفظ ببيانات لمدة لا تقل عن
recent_samples_ttl_seconds ثانية، وتقع مسؤولية ذلك على عاتق المستخدم.
يجب أن تتطابق أنواع أعمدة الجداول الخارجية (id وtimestamp وvalue وأعمدة <tag_value_column> المدرجة في tags_to_columns) مع ما كان جدول TimeSeries سيُنشئه داخليًا في الحالة العادية (راجع جدول العينات وجدول الوسوم وجدول عائلات المقاييس للاطلاع على قيود الأنواع). ويُبلَّغ عن أي عدم تطابق في الأنواع عند تنفيذ CREATE.
يُسجَّل نوع عمود id في جدول الوسوم الخارجي والتعبير المولِّد للمعرّفات في الإعدادين id_type وid_generator عند تنفيذ CREATE (بدءًا من الإصدار 2)، بحيث يحتفظ بهما تعريف جدول TimeSeries: على سبيل المثال، يقرأ CREATE TABLE ... AS my_table نوع id من تعريف my_table دون قراءة جداوله الهدف الخارجية. وإذا لم يُحدَّد الإعداد id_generator، فيُعيَّن إلى DEFAULT المعرَّف في عمود id للجدول الخارجي (إن وجد)، وإلا فإلى المولِّد القياسي المشتق من نوع id. ويُستخدَم التعبير المسجَّل لتوليد id حتى إذا تغيّرت قيمة DEFAULT في الجدول الخارجي لاحقًا — راجع عمود id للتفاصيل.
تعديل الإعدادات
يمكن تغيير إعدادَين بعدCREATE:
id_generatorfilter_by_min_time_and_max_time
id_generator بعد وجود بيانات بالفعل في جدول الوسوم قد يؤدي إلى إنشاء معرّفات مختلفة لنفس تركيبة metric+tag — إذ تحتفظ الصفوف القديمة بمعرّفاتها القديمة، بينما تستخدم الصفوف الجديدة المولِّد الجديد.
ولا يمكن تغيير الإعدادات الأخرى باستخدام ALTER ... MODIFY SETTING: فمعظمها يكون مدمجًا في مخطط الجداول الداخلية عند CREATE،
كما أن الإعداد version يُثبَّت تلقائيًا عند CREATE ويُعرِّف المخطط نفسه (انظر إصدارات المخطط).
الإعدادات
فيما يلي قائمة بالإعدادات التي يمكن تحديدها عند تعريف جدولTimeSeries:
إصدارات المخطط
لا يزال محرك الجدولTimeSeries وطبقة تنفيذ PromQL قيد التطوير النشط:
فمجموعة الجداول الهدف وبنيتها قد تتغيّر بين إصدارات ClickHouse.
ولجعل مثل هذه التغييرات قابلة للاكتشاف، يخزّن كل جدول TimeSeries إصداره في الإعداد version.
ويُثبَّت الإصدار تلقائيًا في استعلام CREATE عند إنشاء الجدول - وقيمته هي أحدث إصدار معروف للخادم (حاليًا 5) -
ويبقى محفوظًا في بيانات الجدول الوصفية، ولا يمكن تغييره باستخدام ALTER. أما الجداول التي أُنشئت قبل أن يُضاف هذا الإعداد فتُعدّ من الإصدار 0.
وفي الأحوال العادية يُستحسن إغفال هذا الإعداد في استعلام CREATE TABLE، فيحصل الجدول عندئذٍ على أحدث إصدار.
ويُقبل تحديد version صراحةً إذا كان الخادم يدعم ذلك الإصدار؛ عندئذٍ يُعرَّف الجدول بالطريقة التي يعتمدها ذلك الإصدار (انظر سجل الإصدارات).
ولا ينسخ CREATE TABLE ... AS other_table إصدار الجدول الآخر، انظر إنشاء جدول AS جدول موجود.
يدعم الخادم نطاقًا من الإصدارات، وقد يختلف الحد الأدنى للإصدار بين القراءة عبر SELECT، والكتابة عبر INSERT
أو بروتوكول remote-write الخاص بـ Prometheus، وتقييم PromQL (دوال الجداول prometheusQuery
وprometheusQueryRange
وtimeSeriesSelector،
ولهجة promql، وواجهة برمجة تطبيقات الاستعلام عبر HTTP الخاصة بـ Prometheus):
- إذا كان إصدار جدول
TimeSeriesأقدم مما يدعمه PromQL، تُرفض استعلامات PromQL التي تجري عليه. ويقترح الاستثناء إعادة إنشاء الجدول: أنشئ جدولTimeSeriesجديدًا، وانسخ البيانات باستعلامINSERT ... SELECT، ثم استبدل الجدول القديم بالجديد. - إذا كان الإصدار أقدم من أن يُكتب فيه، تُرفض استعلامات
INSERTوبروتوكول remote-write الخاص بـ Prometheus، بينما تظل استعلاماتSELECTتعمل. - وإذا كان الإصدار أقدم من أن يدعمه الخادم أصلًا، يُرفض كل استعلام على الجدول (باستثناء
SHOW CREATE TABLEوDETACHوDROP).
سجل الإصدارات
الدوال
فيما يلي قائمة بالدوال التي تقبل جدولTimeSeries كوسيطة: