نظرة عامة
- يستخدم
serdeلترميز الصفوف وفك ترميزها. - يدعم سمات
serde:skip_serializingوskip_deserializingوrename. - يستخدم تنسيق
RowBinaryعبر بروتوكول HTTP.- توجد خطط للانتقال إلى
Nativeعبر TCP.
- توجد خطط للانتقال إلى
- يدعم TLS (عبر ميزتَي
native-tlsوrustls-tls). - يدعم الضغط وفك الضغط (LZ4).
- يوفّر واجهات API للاستعلام عن البيانات أو إدراجها، وتنفيذ عبارات DDL، والتجميع على جانب العميل.
- يوفّر كائنات محاكاة ملائمة لاختبار الوحدات.
التثبيت
Cargo.toml:
ميزات Cargo
lz4(مفعّلة افتراضيًا) — تفعّل الخيارينCompression::Lz4وCompression::Lz4Hc(_). وإذا كانت مفعّلة، فسيُستخدمCompression::Lz4افتراضيًا لجميع queries باستثناءWATCH.native-tls— تدعم عناوين URL ذات المخططHTTPSعبرhyper-tls، والذي يرتبط بـ OpenSSL.rustls-tls— تدعم عناوين URL ذات المخططHTTPSعبرhyper-rustls، والذي لا يرتبط بـ OpenSSL.inserter— تفعّلclient.inserter().test-util— تضيف كائنات محاكاة. راجع المثال. استخدمها فقط فيdev-dependencies.watch— تفعّل إمكاناتclient.watch. راجع القسم المقابل لمزيد من التفاصيل.uuid— تضيفserde::uuidللعمل مع حزمة uuid.time— تضيفserde::timeللعمل مع حزمة time.
توافق إصدارات ClickHouse
wa-37420 لحل هذه المشكلة. ملاحظة: لا ينبغي استخدام هذه الميزة مع إصدارات ClickHouse الأحدث.
أمثلة
الاستخدام
تُعد حزمة ch2rs مفيدة لتوليد نوع صف من ClickHouse.
إنشاء مثيل للعميل
اتصال HTTPS أو ClickHouse Cloud
rustls-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.
الإدراج غير المتزامن (التجميع على جانب الخادم)
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()مرة أخرى للتحقق من الحدود إذا كان التدفق لديك يُصدر العناصر على فترات متباعدة. - تُنفَّذ الحدود الزمنية باستخدام crate quanta لتسريع
inserter. ولا تُستخدم إذا كانtest-utilمفعّلًا (وبالتالي يمكن إدارة الوقت بواسطةtokio::time::advance()في الاختبارات المخصّصة). - تُدرَج جميع الصفوف بين استدعاءات
commit()ضمن تعليمةINSERTنفسها.
تنفيذ DDLs
wait_end_of_query. ويمكن القيام بذلك على النحو التالي:
إعدادات ClickHouse
with_option. على سبيل المثال:
query، ينطبق الأمر نفسه على الطريقتين insert وinserter؛ كما يمكن أيضًا استدعاء الطريقة نفسها على مثيل Client لضبط الإعدادات العامة لجميع الاستعلامات.
معرّف الاستعلام
.with_option، يمكنك تعيين الخيار query_id لتحديد الاستعلامات في سجل استعلامات ClickHouse.
query، فهو يعمل بطريقة مماثلة مع الطريقتين insert وinserter.
إذا عيّنت
query_id يدويًا، فتأكد من أنه فريد. تُعد UUIDs خيارًا جيدًا لهذا الغرض.معرّف الجلسة
query_id، يمكنك تعيين session_id لتنفيذ التعليمات ضمن الجلسة نفسها. ويمكن تعيين session_id إما على مستوى العميل بشكل عام، أو لكل استدعاء query أو insert أو inserter على حدة.
في عمليات النشر العنقودية، ونظرًا إلى عدم توفّر “الجلسات الثابتة”، يجب أن تكون متصلًا بـ عقدة معيّنة في العنقود لكي تتمكّن من استخدام هذه الميزة بشكل صحيح، لأن موازن حمل من نوع round-robin، على سبيل المثال، لا يضمن أن الطلبات اللاحقة ستُعالَج على عقدة ClickHouse نفسها.
رؤوس 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. ويتطلب ذلك feature 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, ...)أو نوع جديد يغلّفه. -
Array(_)يمكن تحويله من/إلى أي slice، مثلVec<_>و&[_]. الأنواع الجديدة مدعومة أيضًا. -
Map(K, V)يتعامل مثلArray((K, V)). -
LowCardinality(_)مدعوم بسلاسة. -
Nullable(_)يمكن تحويله من/إلىOption<_>. بالنسبة إلى مساعداتclickhouse::serde::*، أضف::option.
- يُدعَم
Nestedعبر توفير عدة مصفوفات مع إعادة تسميتها.
- الأنواع
Geoمدعومة. ويتصرفPointمثل زوج مرتب(f64, f64)، أما بقية الأنواع فهي مجرد مقاطع من النقاط.
- أنواع البيانات
VariantوDynamicوJSONالجديدة غير مدعومة بعد.
المحاكاة
SELECT وINSERT وWATCH. يمكن تفعيل هذه الإمكانية باستخدام الميزة test-util. استخدمها فقط كتبعية للتطوير.
اطّلع على المثال.
استكشاف الأخطاء وإصلاحها
CANNOT_READ_ALL_DATA
CANNOT_READ_ALL_DATA هو أن تعريف الصف في جهة التطبيق لا يطابق التعريف المقابل له في ClickHouse.
تأمل الجدول التالي:
EventLog مُعرَّفًا من جهة التطبيق بأنواع غير متطابقة، على سبيل المثال:
EventLog:
القيود المعروفة
- أنواع البيانات
VariantوDynamicوJSON(الجديدة) غير مدعومة حتى الآن. - ربط المعلّمات على جهة الخادم غير مدعوم حتى الآن؛ راجع هذه المشكلة لمتابعتها.