نظرة عامة
- يستخدم
serdeلترميز الصفوف وفك ترميزها. - يدعم سمات
serde:skip_serializingوskip_deserializingوrename. - يستخدم تنسيق
RowBinaryعبر نقل HTTP.- توجد خطط للانتقال إلى
Nativeعبر TCP.
- توجد خطط للانتقال إلى
- يدعم TLS (عبر ميزتَي
native-tlsوrustls-tls). - يدعم الضغط وفك الضغط (LZ4).
- يوفّر واجهات برمجة تطبيقات للاستعلام عن البيانات أو إدراجها، وتنفيذ أوامر DDL، والتجميع على جهة العميل.
- يوفّر كائنات محاكاة مناسبة لاختبارات الوحدة.
التثبيت
لاستخدامحزمة، أضف ما يلي إلى ملف Cargo.toml:
ميزات Cargo
lz4(مفعّلة افتراضيًا) — تفعّل البديلينCompression::Lz4وCompression::Lz4Hc(_). وإذا كانت مفعّلة، فسيُستخدمCompression::Lz4افتراضيًا في جميع الاستعلامات باستثناءWATCH، الذي لا تقبله إلا إصدارات ClickHouse الأقدم من v26.9.native-tls— تدعم عناوين URL ذات مخططHTTPSعبرhyper-tls، والذي يرتبط بـ OpenSSL.rustls-tls— تدعم عناوين URL ذات مخططHTTPSعبرhyper-rustls، والذي لا يرتبط بـ OpenSSL.inserter— تفعّلclient.inserter().test-util— تضيف كائنات محاكاة. راجع المثال. استخدمها فقط فيdev-dependencies.watch— تفعّل وظيفةclient.watch. وهي تصدر استعلامWATCH، الذي أُزيل في ClickHouse v26.9 معWINDOW VIEW، لذا فهي لا تعمل إلا مع الخوادم الأقدم.uuid— تضيفserde::uuidللعمل مع حزمة uuid.time— تضيفserde::timeللعمل مع حزمة time.
توافق إصدارات ClickHouse
العميل متوافق مع إصدارات LTS أو الأحدث من ClickHouse، وكذلك مع ClickHouse Cloud. يتعامل خادم ClickHouse الأقدم من v22.6 مع RowBinary بشكل غير صحيح في بعض الحالات النادرة. يمكنك استخدام v0.11+ وتمكين الميزةwa-37420 لحل هذه المشكلة. ملاحظة: لا ينبغي استخدام هذه الميزة مع إصدارات ClickHouse الأحدث.
أمثلة
نهدف إلى تغطية سيناريوهات متنوعة لاستخدام مكتبة العميل من خلال الأمثلة الموجودة في مستودع العميل. تتوفر لمحة عامة عنها في README الخاص بالأمثلة. إذا كان هناك ما هو غير واضح أو ناقص في الأمثلة أو في الوثائق التالية، فلا تتردد في التواصل معنا.الاستخدام
تُعد حزمة ch2rs مفيدة لتوليد نوع يمثّل صفًا من ClickHouse.
إنشاء مثيل للعميل
اتصال عبر HTTPS أو ClickHouse Cloud
يعمل HTTPS مع ميزتَي Cargorustls-tls أو native-tls.
بعد ذلك، أنشئ عميل كالمعتاد. في هذا المثال، تُستخدَم متغيرات البيئة لتخزين تفاصيل الاتصال:
- مثال HTTPS مع ClickHouse Cloud في مستودع عميل. ينبغي أن ينطبق هذا أيضًا على اتصالات HTTPS المستضافة محليًا.
تحديد الصفوف
- يُستبدل العنصر النائب
?fieldsبـno, name(حقولRow). - يُستبدل العنصر النائب
?بالقيم في استدعاءاتbind()اللاحقة. - يمكن استخدام الطريقتين المناسبتين
fetch_one::<Row>()وfetch_all::<Row>()للحصول على الصف الأول أو جميع الصفوف، على الترتيب. - يمكن استخدام
sql::Identifierلربط أسماء الجداول.
query(...).with_option("wait_end_of_query", "1") لتمكين تخزين الاستجابة مؤقتًا على جهة الخادم. مزيد من التفاصيل. وقد يكون الخيار buffer_size مفيدًا أيضًا.
إدراج الصفوف
- إذا لم يتم استدعاء
end()، فسيتم إلغاءINSERT. - تُرسَل الصفوف تدريجيًا على شكل تدفّق لتوزيع حمل الشبكة.
- يُدرِج ClickHouse الدُفعات بصورة ذرّية فقط إذا كانت جميع الصفوف تقع ضمن partition نفسها وكان عددها أقل من
max_insert_block_size.
الإدراج غير المتزامن (التجميع من جهة الخادم)
يمكنك استخدام عمليات الإدراج غير المتزامن في ClickHouse لتجنب تجميع البيانات الواردة من جهة العميل. ويمكنك القيام بذلك ببساطة عبر تمرير الخيارasync_insert إلى الدالة insert (أو حتى إلى مثيل Client نفسه، بحيث يسري ذلك على جميع استدعاءات insert).
- مثال على async insert في مستودع مكتبة عميل.
ميزة Inserter (التجميع على جهة العميل)
يتطلب ذلك تفعيل ميزةinserter في Cargo.
- ينهي
Inserterعملية الإدراج النشطة فيcommit()إذا تم بلوغ أيٍّ من العتبات (max_bytes،max_rows،period). - يمكن إزاحة الفاصل الزمني بين إنهاء أوامر
INSERTالنشطة باستخدامwith_period_biasلتجنّب ارتفاعات الحمل الناتجة عن أدوات الإدراج المتوازية. - يمكن استخدام
Inserter::time_left()لاكتشاف موعد انتهاء الفترة الحالية. استدعِInserter::commit()مرة أخرى للتحقق من الحدود إذا كان التدفق يُصدر العناصر بوتيرة متباعدة. - تُنفَّذ العتبات الزمنية باستخدام حزمة quanta لتسريع
inserter. ولا يُستخدم ذلك إذا كانtest-utilمُمكّنًا (وبالتالي يمكن التحكم في الوقت عبرtokio::time::advance()في الاختبارات المخصّصة). - تُدرَج جميع الصفوف بين استدعاءات
commit()ضمن عبارةINSERTنفسها.
تنفيذ DDLs
في النشر أحادي العقدة، يكفي تنفيذ DDLs كما يلي:wait_end_of_query. ويمكن إجراء ذلك على النحو التالي:
إعدادات ClickHouse
يمكنك تطبيق إعدادات ClickHouse المختلفة باستخدام الطريقةwith_option. على سبيل المثال:
query، يعمل الأمر بالطريقة نفسها مع الطريقتين insert وinserter؛ بالإضافة إلى ذلك، يمكن استدعاء الطريقة نفسها على مثيل Client لضبط إعدادات عامة لجميع الاستعلامات.
معرّف الاستعلام
باستخدام.with_option، يمكنك تعيين الخيار query_id لتمييز الاستعلامات في سجل استعلامات ClickHouse.
query، يعمل الأمر بالمثل مع طريقتَي insert وinserter.
إذا عيّنت
query_id يدويًا، فتأكد من أنه فريد. تُعد معرّفات UUID خيارًا جيدًا لهذا الغرض.معرّف الجلسة
على غرارquery_id، يمكنك تعيين session_id لتنفيذ التعليمات ضمن الجلسة نفسها. ويمكن تعيين session_id إما على مستوى العميل بشكل عام، أو لكل استدعاء query أو insert أو inserter على حدة.
في عمليات النشر العنقودية، ونظرًا لعدم وجود “جلسات مثبتة”، تحتاج إلى الاتصال بـ عقدة معيّنة في العنقود لكي تتمكن من استخدام هذه الميزة بشكل صحيح، لأن موازن التحميل بنظام round-robin، على سبيل المثال، لا يضمن أن الطلبات اللاحقة ستُعالَج على عقدة ClickHouse نفسها.
رؤوس HTTP مخصصة
إذا كنت تستخدم المصادقة عبر proxy أو تحتاج إلى تمرير رؤوس مخصصة، فيمكنك القيام بذلك كما يلي:عميل HTTP مخصّص
قد يكون هذا مفيدًا لتعديل إعدادات مجمّع اتصالات HTTP الأساسي.أنواع البيانات
راجع أيضًا الأمثلة الإضافية التالية:
- يقابل
(U)Int(8|16|32|64|128)في التحويل من/إلى الأنواع المناظرة(u|i)(8|16|32|64|128)أوnewtypesالمبنية عليها. - لا يتوفر دعم مباشر لـ
(U)Int256، ولكن يوجد حل بديل لذلك. - يقابل
Float(32|64)في التحويل من/إلىf(32|64)المناظرة أوnewtypesالمبنية عليها. - يقابل
Decimal(32|64|128)في التحويل من/إلىi(32|64|128)المناظرة أوnewtypesالمبنية عليها. ويكون استخدامfixnumأو أي تنفيذ آخر للأعداد العشرية الثابتة ذات الإشارة أكثر ملاءمة. - يقابل
Booleanفي التحويل من/إلىboolأوnewtypesالمبنية عليه. - يقابل
Stringفي التحويل من/إلى أي نوع من أنواع السلاسل النصية أو البايتات، مثل&strو&[u8]وStringوVec<u8>أوSmartString. كما أن الأنواع الجديدة مدعومة أيضًا. ولتخزين البايتات، يُنصح باستخدامserde_bytes، لأنه أكثر كفاءة.
- النوع
FixedString(N)مدعوم على هيئة مصفوفة من البايتات، مثل[u8; N].
- يُدعَم
Enum(8|16)باستخدامserde_repr.
- يُحوَّل
UUIDمن/إلىuuid::Uuidباستخدامserde::uuid. ويتطلب ذلك الميزةuuid.
- يقابل
IPv6النوعstd::net::Ipv6Addrذهابًا وإيابًا. - يقابل
IPv4النوعstd::net::Ipv4Addrذهابًا وإيابًا باستخدامserde::ipv4.
- يُحوَّل
Dateمن/إلىu16أو إلى نوعٍ من نمطnewtypeمبنيّ عليه، ويمثّل عدد الأيام المنقضية منذ1970-01-01. كما أنtime::Dateمدعوم أيضًا باستخدامserde::time::date، وهذا يتطلب الميزةtime.
- يُحوَّل
Date32من/إلىi32أوnewtypeيلتف حوله، ويمثل عدد الأيام المنقضية منذ1970-01-01. كما أنtime::Dateمدعوم عند استخدامserde::time::date32، وهذا يتطلب الميزةtime.
- يُحوَّل
DateTimeمن وإلىu32أوnewtypeمبني عليه، ويمثل عدد الثواني المنقضية منذ حقبة Unix. كما أنtime::OffsetDateTimeمدعوم أيضًا باستخدامserde::time::datetime، ويتطلب ذلك تفعيل ميزةtime.
- يُربَط
DateTime64(_)مع/منi32أو معnewtypeيغلّفه، ويمثل زمنًا منقضيًا منذ حقبة UNIX. كما أنtime::OffsetDateTimeمدعوم أيضًا باستخدامserde::time::datetime64::*، وهذا يتطلب تفعيل الميزةtime.
Tuple(A, B, ...)يقابل ذهابًا وإيابًا(A, B, ...)أوnewtypeيغلّفه.Array(_)يقابل ذهابًا وإيابًا أيslice، مثلVec<_>و&[_]. كما أن الأنواع الجديدة مدعومة أيضًا.Map(K, V)يتعامل مثلArray((K, V)).LowCardinality(_)مدعوم بسلاسة.Nullable(_)يقابل ذهابًا وإيابًاOption<_>. وبالنسبة إلى الدوال المساعدةclickhouse::serde::*، أضِف::option.
- يُدعَم
Nestedعبر توفير عدة مصفوفات مع إعادة تسميتها.
- الأنواع
Geoمدعومة. ويعملPointمثل زوجٍ مرتب(f64, f64)، أما بقية الأنواع فهي مجرد تسلسلات من النقاط.
- لا تزال أنواع البيانات
VariantوDynamicوJSON(النوع الجديد) غير مدعومة بعد.
المحاكاة
توفر الحزمة أدوات مساعدة لمحاكاة خادم CH واختبار استعلامات DDL وSELECT وINSERT وWATCH (لا يقبل WATCH إلا ClickHouse الأقدم من v26.9). ويمكن تمكين هذه الوظيفة باستخدام الميزة test-util. استخدمها فقط كاعتماد تطويري.
راجع المثال.
استكشاف الأخطاء وإصلاحها
CANNOT_READ_ALL_DATA
السبب الأكثر شيوعًا لخطأCANNOT_READ_ALL_DATA هو أن تعريف الصف في جهة التطبيق لا يطابق التعريف في ClickHouse.
لننظر إلى الجدول التالي:
EventLog مُعرَّفًا في التطبيق بأنواع غير متطابقة، على سبيل المثال:
EventLog:
القيود المعروفة
- أنواع البيانات
VariantوDynamicوJSON(الجديدة) غير مدعومة حتى الآن. - ربط المعلّمات على جهة الخادم غير مدعوم حتى الآن؛ راجع هذه التذكرة لمتابعة الحالة.