مكتبة Java client للتواصل مع خادم DB عبر بروتوكولاته. يدعم التطبيق الحالي واجهة HTTP interface فحسب.
توفر المكتبة واجهة برمجة تطبيقات خاصة بها لإرسال الطلبات إلى الخادم، كما توفر أدوات للعمل مع تنسيقات البيانات الثنائية المختلفة (RowBinary* & Native*).
تتطلب المصادقة عبر رمز الوصول ضبط رمز الوصول من خلال استدعاء تتطلب المصادقة عبر شهادة SSL للعميل تحديد اسم المستخدم، وتفعيل مصادقة SSL، وضبط شهادة العميل ومفتاحه من خلال استدعاء
سيؤدي ذلك إلى القيمة التالية لـ يمكن للتطبيق تعيين رأس HTTP الخاص به ⚠️ عند تعيين الخيارات عبر طريقة عند تعيين الخيارات عبر الـ method الخاصة بـ المعاملاتالمعاملاتالمعاملاتالمعاملاتالمعاملاتالمعاملاتالمعاملاتالمعاملاتطرق إدراج بيانات بتنسيق TSV - الإصدار V2.
الإعداد
- Maven Central (صفحة المشروع على الويب): https://mvnrepository.com/artifact/com.clickhouse/client-v2
- الإصدارات الليلية (رابط المستودع): https://central.sonatype.com/repository/maven-snapshots/
- مستودع Artifactory القديم للإصدارات الليلية (رابط المستودع): https://s01.oss.sonatype.org/content/repositories/snapshots/
- Maven
- Gradle (Kotlin)
- Gradle
التهيئة
يتم تهيئة كائن Client عبرcom.clickhouse.client.api.Client.Builder#build(). يمتلك كل client سياقه الخاص، ولا تُشارَك أي كائنات بين الـ clients.
يوفر Builder طرق ضبط تُيسّر عملية الإعداد.مثال:showLineNumbers
Client هو AutoCloseable ويجب إغلاقه عند انتهاء الحاجة إليه.المصادقة
تُهيَّأ المصادقة لكل عميل في مرحلة التهيئة. وتتوفر ثلاث طرق مصادقة مدعومة: بكلمة المرور، أو برمز الوصول، أو بشهادة SSL للعميل.تتطلب المصادقة بكلمة مرور تعيين اسم المستخدم وكلمة المرور من خلال استدعاءsetUsername(String) وsetPassword(String):showLineNumbers
setAccessToken(String):showLineNumbers
setUsername(String) وuseSSLAuthentication(boolean) وsetClientCertificate(String) وsetClientKey(String) على التوالي:showLineNumbers
قد يصعب استكشاف أخطاء مصادقة SSL وإصلاحها في بيئة الإنتاج لأن كثيرًا من الأخطاء الصادرة عن مكتبات SSL لا توفّر معلومات كافية. على سبيل المثال، إذا لم تتطابق شهادة العميل مع المفتاح، فسينهي الخادم الاتصال فورًا (وفي حالة HTTP، تكون هذه مرحلة بدء الاتصال حيث لا تُرسل أي طلبات HTTP، وبالتالي لا يُرسل أي رد).استخدم أدوات مثل openssl للتحقق من الشهادات والمفاتيح:
- التحقق من سلامة المفتاح:
openssl rsa -in [key-file.key] -check -noout - التحقق من أن شهادة العميل تتضمن CN مطابقًا لمستخدم:
- استخراج CN من شهادة المستخدم -
openssl x509 -noout -subject -in [user.cert] - التحقق من ضبط القيمة نفسها في قاعدة البيانات
select name, auth_type, auth_params from system.users where auth_type = 'ssl_certificate'(سيُظهر الاستعلامauth_paramsبشيء مثل{"common_names":["some_user"]})
- استخراج CN من شهادة المستخدم -
التهيئة
يتم تعريف جميع الإعدادات عبر طرق النسخة (المعروفة أيضاً بطرق الإعداد)، مما يجعل نطاق وسياق كل قيمة واضحاً. تُعرَّف معاملات الإعداد الرئيسية ضمن نطاق واحد (العميل أو العملية) ولا تتجاوز بعضها البعض.يتم تحديد الإعداد أثناء إنشاء الـ client. راجعcom.clickhouse.client.api.Client.Builder.إعداد العميل
- الاتصال ونقاط النهاية
- المصادقة
- مهلات الانتظار & إعادة المحاولة
- خيارات Socket
- الضغط
- SSL/الأمان
- الوسيط
- HTTP والترويسات
- إعدادات الخادم
- المنطقة الزمنية
- متقدم
تعريف العميل
يوجد حقلان في سجل الاستعلام يُحدِّدان التطبيق الذي أنشأ الطلب:client_name وhttp_user_agent. يستخدم بروتوكول native TCP الحقلَ client_name لتعريف التطبيق، بينما يستخدم بروتوكول HTTP الحقلَ http_user_agent لهذا الغرض. يوفر الـ Client builder الأسلوبَ setClientName لضبط القيم الصحيحة لكلا البروتوكولين.
يُضبط الحقل http_user_agent وفق التنسيق الشائع لترويسة User-Agent: application-name[/version] [(operating-system; architecture; ...)].
تتكرر هذه المجموعة من القيم لكل طبقة: التطبيق، ومكتبة الـ client، ومكتبة الـ HTTP client. ويأتي ما يُحدَّد عبر الأسلوب setClientName في مقدمة القائمة.على سبيل المثال:showLineNumbers
http_user_agent:User-Agent للتعريف عن نفسه. غير أن الجزء clickhouse-java-v2/0.9.6-SNAPSHOT سيُلحَق بنهاية الرأس.تحديد العملية
يتضمن سجل الاستعلام حقلين إضافيين هماquery_id وlog_comment، يمكن استخدامهما لتحديد عملية معينة وإضافة معلومات إضافية إلى سجل الاستعلام.query_id هو معرّف فريد للعملية. يمكن تعيينه من قِبل التطبيق عن طريق استدعاء الدالة setQueryId في الفئة QuerySettings.showLineNumbers
log_comment هو تعليق يمكن إضافته إلى سجل الاستعلام. يمكن للتطبيق ضبطه عبر استدعاء الدالة logComment من الفئة QuerySettings.showLineNumbers
إعدادات الخادم
يمكن تعيين إعدادات جانب الخادم على مستوى العميل مرةً واحدة أثناء الإنشاء (راجع الدالةserverSetting في Builder)، وعلى مستوى العملية (راجع serverSetting في class إعدادات العملية).showLineNumbers
setOption (سواء في Client.Builder أو في فئة إعدادات العملية)، يجب أن يُسبَق اسم إعداد الخادم بالبادئة clickhouse_setting_. قد يكون com.clickhouse.client.api.ClientConfigProperties#serverSetting() مفيدًا في هذه الحالة.HTTP Header مخصص
يمكن تعيين HTTP headers مخصصة لجميع العمليات (على مستوى العميل) أو لعملية واحدة فقط (على مستوى العملية).showLineNumbers
setOption (سواء في Client.Builder أو class إعدادات العملية)، يجب أن يبدأ اسم الـ header المخصص بالبادئة http_header_. وقد تكون الـ method الخاصة بـ com.clickhouse.client.api.ClientConfigProperties#httpHeader() مفيدةً في هذه الحالة.التعريفات الشائعة
ClickHouseFormat
تعداد الصيغ المدعومة. يتضمن جميع الصيغ التي يدعمها ClickHouse.raw- يجب على المستخدم تحويل ترميز البيانات الخامfull- يمكن للعميل تحويل ترميز البيانات بنفسه ويقبل تدفق بيانات خام-- هذه العملية غير مدعومة في ClickHouse لهذا التنسيق
واجهة برمجة تطبيقات الإدراج
insert(String tableName, InputStream data, ClickHouseFormat format)
يقبل البيانات على شكلInputStream من البايتات بالتنسيق المحدد. ومن المتوقع أن تكون data مُرمَّزةً وفق format.التوقيعاتtableName - اسم الجدول الهدف.data - تدفق إدخال لبيانات مُرمَّزة.format - التنسيق الذي تُرمَّز به البيانات.settings - إعدادات الطلب.القيمة المُعادةمستقبل من نوع InsertResponse - نتيجة العملية ومعلومات إضافية كمقاييس جانب الخادم.أمثلةshowLineNumbers
insert(String tableName, List<?> data, InsertSettings settings)
يُرسل طلب كتابة إلى قاعدة البيانات. يتم تحويل قائمة الكائنات إلى تنسيق فعّال ثم إرسالها إلى الخادم. يجب تسجيل الفئة الخاصة بعناصر القائمة مسبقًا باستخدام الطريقةregister(Class, TableSchema).التوقيعاتtableName - اسم الجدول الهدف.data - كائنات DTO (Data Transfer Object) الخاصة بالمجموعة.settings - إعدادات الطلب.القيمة المُعادةمستقبل من النوع InsertResponse - يمثّل نتيجة العملية ومعلومات إضافية كمقاييس جانب الخادم.أمثلةshowLineNumbers
InsertSettings
خيارات الإعداد لعمليات الإدراج.طرق الإعداداستجابة الإدراج
كائن Response يحتوي على نتيجة عملية الإدراج. لا يكون متاحاً إلا إذا تلقّى الـ Client استجابةً من الـ server.يجب إغلاق هذا الكائن في أقرب وقت ممكن لتحرير الاتصال، إذ لا يمكن إعادة استخدامه حتى تُقرأ جميع بيانات الاستجابة السابقة بالكامل.
واجهة برمجة تطبيقات الاستعلام
query(String sqlQuery)
يُرسلsqlQuery كما هو. يُحدَّد تنسيق الاستجابة من خلال إعدادات الاستعلام. سيحتفظ QueryResponse بمرجع إلى تدفق الاستجابة الذي يجب أن يستهلكه قارئ يدعم التنسيق المحدد.التوقيعاتsqlQuery - عبارة SQL واحدة. يُرسَل الاستعلام كما هو إلى الخادم.settings - إعدادات الطلب.القيمة المُعادةمستقبل من النوع QueryResponse - مجموعة بيانات نتائج ومعلومات إضافية كمقاييس جانب الخادم. يجب إغلاق كائن الاستجابة بعد الانتهاء من استهلاك مجموعة البيانات.أمثلةquery(String sqlQuery, Map<String, Object> queryParams, QuerySettings settings)
يُرسلsqlQuery كما هو. كما يُرسل معاملات الاستعلام لكي يتمكن الخادم من تجميع تعبير SQL.التوقيعاتsqlQuery - تعبير SQL مع العناصر النائبة {}.queryParams - مجموعة من المتغيرات لإكمال تعبير SQL على الخادم.settings - إعدادات الطلب.القيمة المُعادةمستقبل من النوع QueryResponse - مجموعة بيانات نتائج ومعلومات إضافية كمقاييس جانب الخادم. يجب إغلاق كائن الاستجابة بعد الانتهاء من استهلاك مجموعة البيانات.أمثلةshowLineNumbers
queryAll(String sqlQuery)
يُرسل استعلامات للبيانات بتنسيقRowBinaryWithNamesAndTypes. يُعيد النتيجة على شكل مجموعة. أداء القراءة مماثل لأداء القارئ، إلا أنه يتطلب ذاكرة أكبر لاستيعاب مجموعة البيانات بالكامل.التوقيعاتsqlQuery - تعبير SQL للاستعلام عن البيانات من الخادم.القيمة المُعادةمجموعة البيانات الكاملة ممثَّلةً بقائمة من كائنات GenericRecord التي توفر وصولاً على شكل صفوف إلى بيانات النتائج.أمثلةshowLineNumbers
QuerySettings
خيارات التهيئة لعمليات الاستعلام.طرق الإعدادQueryResponse
كائن الاستجابة الذي يحتوي على نتيجة تنفيذ الاستعلام. لا يكون متاحاً إلا إذا تلقّى الـ client استجابةً من الـ server.يجب إغلاق هذا الكائن في أقرب وقت ممكن لتحرير الاتصال، لأن هذا الاتصال لا يمكن إعادة استخدامه حتى تتم قراءة جميع بيانات الاستجابة السابقة بالكامل.
أمثلة
- شيفرة المثال متاحة في المستودع
- التنفيذ المرجعي لخدمة Spring متاح في implementation
واجهة برمجة التطبيقات المشتركة
getTableSchema(String table)
يجلب مخطط الجدول الخاص بـtable.التوقيعاتtable - اسم الجدول الذي سيتم جلب بيانات المخطط الخاصة به.database - قاعدة البيانات التي يُعرَّف فيها الجدول الهدف.القيمة المُعادةيُعيد كائن TableSchema يحتوي على قائمة بأعمدة الجدول.getTableSchemaFromQuery(String sql)
يسترجع المخطط من عبارة SQL.التوقيعاتsql - عبارة SQL من نوع “SELECT” التي سيتم إرجاع مخططها.القيمة المُعادةيُعيد كائن TableSchema يحتوي على أعمدة تتطابق مع تعبير sql.TableSchema
register(Class<?> clazz, TableSchema schema)
يُجمِّع طبقة التسلسل وإلغاء التسلسل لـ Java Class لاستخدامها في كتابة/قراءة البيانات باستخدامschema. ستُنشئ هذه الدالة مُسلسِلاً ومُفككَ تسلسل لزوج getter/setter والعمود المقابل.
يُحدَّد تطابق العمود باستخراج اسمه من اسم الدالة. على سبيل المثال، سيرتبط getFirstName بالعمود first_name أو firstname.التوقيعاتclazz - فئة تمثّل POJO المستخدم لقراءة البيانات وكتابتها.schema - مخطط البيانات المستخدم للمطابقة مع خصائص POJO.أمثلةshowLineNumbers
أمثلة الاستخدام
تجد شيفرة الأمثلة الكاملة في المستودع داخل مجلد ‘example`:- client-v2 - المجموعة الأساسية من الأمثلة.
- demo-service - مثال على كيفية استخدام العميل في تطبيق Spring Boot.
- demo-kotlin-service - مثال على كيفية استخدام العميل في تطبيق Ktor (Kotlin).
قراءة البيانات
ثمة طريقتان شائعتان لقراءة البيانات:- الطريقة
query()التي تُرجع الكائن منخفض المستوىQueryResponse، والذي يحتوي علىInputStreamللبيانات. تُستخدم عادةً معClickHouseBinaryFormatReaderلإجراء عمليات قراءة متدفقة، لكنها يمكن استخدامها أيضًا مع أي تنفيذ مخصص آخر للقارئ. كما يوفّرQueryResponseإمكانية الوصول إلى البيانات الوصفية لمجموعة النتائج والمقاييس. - الطريقة
queryAll()مع استخدامGenericRecordللوصول بسهولة إلى الصفوف. في هذه الحالة، تُحمَّل مجموعة النتائج بالكامل إلى الذاكرة. - الطريقة
queryRecords()التي تُرجعcom.clickhouse.client.api.query.Records- وهو مكرّر لكائناتGenericRecord. تستخدم هذه الطريقة نهجًا متدفقًا (من دون تحميل أي بيانات إلى الذاكرة) وتستفيد منGenericRecordللوصول إلى البيانات.
قراءة المصفوفات
طرقClickHouseBinaryFormatReadergetList(...)- يقرأ أيArray(...)باعتبارهList<T>. خيار افتراضي جيد لعمليات القراءة المرنة المقيّدة بالنوع. يدعم المصفوفات المتداخلة.getByteArray(...),getShortArray(...),getIntArray(...),getLongArray(...),getFloatArray(...),getDoubleArray(...),getBooleanArray(...)- الأفضل للمصفوفات أحادية البعد ذات القيم المتوافقة مع الأنواع الأولية.getStringArray(...)- مخصّص لـArray(String)(وكذلك لقيمenumالممثلة كأسماء).getObjectArray(...)- خيار عام لأي نوع عنصر فيArray(...)، بما في ذلك المصفوفات المتداخلة. استخدمه لقراءة المصفوفات التي تحتوي على قيم يمكن أن تكونNULLوالمصفوفات المتداخلة.
GenericRecordgetList(...)- يقرأ أيArray(...)باعتبارهList<T>. خيار افتراضي جيد لعمليات القراءة المرنة المقيّدة بالأنواع. يدعم المصفوفات المتداخلة.getByteArray(...),getShortArray(...),getIntArray(...),getLongArray(...),getFloatArray(...),getDoubleArray(...),getBooleanArray(...)- الأفضل للمصفوفات أحادية البعد ذات القيم المتوافقة مع الأنواع البدائية.getStringArray(...)- لـArray(String)(وقيمenumالممثلة على شكل أسماء).getObjectArray(...)- خيار عام لأي نوع عنصر فيArray(...)، بما في ذلك المصفوفات المتداخلة. استخدمه لقراءة المصفوفات التي تحتوي على قيم قابلة لأن تكون NULL والمصفوفات المتداخلة.
دليل الترحيل
كان العميل القديم (V1) يستخدمcom.clickhouse.client.ClickHouseClient#builder كنقطة انطلاق. أما العميل الجديد (V2) فيعتمد نمطًا مشابهًا عبر com.clickhouse.client.api.Client.Builder. وأبرز
الفروقات هي:- لا يُستخدم أي service loader لجلب التنفيذ الفعلي. وتمثّل
com.clickhouse.client.api.Clientفئة واجهة لمختلف أنواع التنفيذ مستقبلًا. - عدد مصادر التهيئة أقل: يُمرَّر أحدها إلى الـ builder، ويكون الآخر ضمن إعدادات العملية (
QuerySettings،InsertSettings). كان الإصدار السابق يتضمّن تهيئة لكل عقدة، وكان يقرأ متغيرات البيئة في بعض الحالات.
تطابق معاملات الإعداد
توجد 3 فئات enum مرتبطة بالتهيئة في V1:com.clickhouse.client.config.ClickHouseDefaults- معلمات التهيئة التي يُفترض تعيينها في معظم حالات الاستخدام، مثلUSERوPASSWORD.com.clickhouse.client.config.ClickHouseClientOption- معلمات تهيئة خاصة بالعميل، مثلHEALTH_CHECK_INTERVAL.com.clickhouse.client.http.config.ClickHouseHttpOption- معلمات تهيئة خاصة بواجهة HTTP، مثلRECEIVE_QUERY_PROGRESS.
com.clickhouse.client.config.ClickHouseDefaults#ASYNC وcom.clickhouse.client.config.ClickHouseClientOption#ASYNC؟). يستخدم client الجديد V2 الفئة com.clickhouse.client.api.Client.Builder بوصفها مرجعًا موحدًا لجميع خيارات تهيئة الـ client الممكنة. كما تتوفر الفئة com.clickhouse.client.api.ClientConfigProperties التي تسرد جميع أسماء معاملات التهيئة.يوضح الجدول أدناه الخيارات القديمة المدعومة في الـ client الجديد ومعانيها الجديدة.المفتاح: ✔ = مدعوم، ✗ = مُسقَط- الاتصال والمصادقة
- SSL & الأمان
- خيارات Socket
- ضغط
- بروكسي
- المهلات وإعادة المحاولة
- المنطقة الزمنية
- المخازن المؤقتة & الأداء
- الخيوط & عدم التزامن
- HTTP & الترويسات
- الصيغة & الاستعلام
- اكتشاف العُقد & موازنة الحمل
- متفرقات
الفروق العامة
- يستخدم Client V2 عددًا أقل من الفئات الخاصة لزيادة قابلية النقل. على سبيل المثال، يعمل V2 مع أي تنفيذ لـ
java.io.InputStreamمن أجل كتابة البيانات إلى الخادم. - يكون إعداد
asyncفي Client V2 مضبوطًا علىoffافتراضيًا. وهذا يعني عدم وجود مؤشرات ترابط إضافية وتحكمًا أكبر من التطبيق في العميل. ينبغي أن يكون هذا الإعدادoffفي معظم حالات الاستخدام. سيؤدي تمكينasyncإلى إنشاء مؤشر ترابط منفصل لكل طلب. ولا يكون ذلك منطقيًا إلا عند استخدام منفّذ يتحكم فيه التطبيق (انظرcom.clickhouse.client.api.Client.Builder#setSharedOperationExecutor)
كتابة البيانات
- استخدم أي تنفيذ لـ
java.io.InputStream. الإصدار V1com.clickhouse.data.ClickHouseInputStreamمدعوم، لكنه غير مستحسن. - بمجرد اكتشاف نهاية مجرى الإدخال، ستتم معالجتها وفقًا لذلك. في السابق، كان يجب إغلاق مجرى الإخراج الخاص بالطلب.
- توجد طريقة واحدة فقط لاستدعائها. لا حاجة إلى إنشاء كائن طلب إضافي.
- يُغلَق تدفّق جسم الطلب تلقائيًا عند نسخ جميع البيانات.
- تتوفر واجهة برمجة تطبيقات جديدة منخفضة المستوى
com.clickhouse.client.api.Client#insert(java.lang.String, java.util.List<java.lang.String>, com.clickhouse.client.api.DataStreamWriter, com.clickhouse.data.ClickHouseFormat, com.clickhouse.client.api.insert.InsertSettings). صُمِّمcom.clickhouse.client.api.DataStreamWriterلتطبيق منطق مخصص لكتابة البيانات. على سبيل المثال، لقراءة البيانات من قائمة انتظار.
قراءة البيانات
- تُقرأ البيانات بتنسيق
RowBinaryWithNamesAndTypesافتراضيًا. وحاليًا لا يُدعَم عند الحاجة إلى ربط البيانات سوى هذا التنسيق. - يمكن قراءة البيانات كمجموعة من السجلات باستخدام الأسلوب
List<GenericRecord> com.clickhouse.client.api.Client#queryAll(java.lang.String). يقرأ هذا الأسلوب البيانات إلى الذاكرة ثم يحرّر الاتصال. ولا حاجة إلى أي معالجة إضافية. يتيحGenericRecordالوصول إلى البيانات، ويجري بعض التحويلات.