يوفّر ClickHouse Keeper نظام التنسيق اللازم للنسخ المتماثل للبيانات وتنفيذ استعلامات replication وdistributed DDL. كما أن ClickHouse Keeper متوافق مع ZooKeeper.
تفاصيل التنفيذ
يُعد ZooKeeper من أوائل أنظمة التنسيق المفتوحة المصدر المعروفة على نطاق واسع. وهو مكتوب بلغة Java ويعتمد نموذج بيانات بسيطًا وقويًا. ولا توفّر خوارزمية التنسيق في ZooKeeper، وهي ZooKeeper Atomic Broadcast (ZAB)، ضمانات الاتساق الخطي لعمليات القراءة، لأن كل عقدة في ZooKeeper تخدم عمليات القراءة محليًا. وعلى عكس ZooKeeper، فإن ClickHouse Keeper مكتوب بلغة C++ ويستخدم تنفيذًا لخوارزمية RAFT. وتتيح هذه الخوارزمية الاتساق الخطي لعمليات القراءة والكتابة، كما تتوفر لها عدة تطبيقات مفتوحة المصدر بلغات مختلفة.
يوفّر ClickHouse Keeper افتراضيًا الضمانات نفسها التي يوفّرها ZooKeeper: كتابات متسقة خطيًا وقراءات غير متسقة خطيًا. كما أنه يوفّر بروتوكول عميل-خادم متوافقًا، لذا يمكن استخدام أي عميل ZooKeeper قياسي للتفاعل مع ClickHouse Keeper. وتستخدم اللقطات والسجلات تنسيقًا غير متوافق مع ZooKeeper، لكن أداة clickhouse-keeper-converter تتيح تحويل بيانات ZooKeeper إلى لقطات ClickHouse Keeper. كذلك فإن بروتوكول الاتصال بين الخوادم في ClickHouse Keeper غير متوافق مع ZooKeeper، لذلك يستحيل وجود عنقود مختلط من ZooKeeper / ClickHouse Keeper.
يدعم ClickHouse Keeper قوائم التحكم في الوصول (ACLs) بالطريقة نفسها التي يدعمها ZooKeeper. ويدعم ClickHouse Keeper المجموعة نفسها من الأذونات، كما يوفّر آليات built-in المطابقة نفسها: world وauth وdigest. وتستخدم آلية المصادقة digest الزوج username:password، وتُرمَّز كلمة المرور بترميز Base64.
التهيئة
يمكن استخدام ClickHouse Keeper كبديل مستقل لـ ZooKeeper أو كجزء داخلي من ClickHouse server. وفي كلتا الحالتين، تكون التهيئة في ملف .xml متطابقة تقريبًا.
إعدادات تهيئة Keeper
وسم التهيئة الرئيسي لـ ClickHouse Keeper هو <keeper_server>، ويتضمن المعلمات التالية:
| Parameter | Description | Default |
|---|---|---|
tcp_port |
المنفذ الذي يتصل من خلاله العميل. | 2181 |
tcp_port_secure |
منفذ آمن لاتصال SSL بين العميل وkeeper-server. | - |
server_id |
معرّف server فريد؛ ويجب أن يكون لكل مشارك في ClickHouse Keeper عنقود رقم فريد (1، 2، 3…). | - |
log_storage_path |
path إلى logs الخاصة بـ coordination. وكما هو الحال في ZooKeeper، من الأفضل تخزين السجلات على عقد غير مثقلة بالعمل. | - |
snapshot_storage_path |
path إلى لقطات الخاصة بـ coordination. | - |
enable_reconfiguration |
تمكين reconfiguration الديناميكية للـ عنقود عبر reconfig. |
False |
max_memory_usage_soft_limit |
soft limit بالبايت للحد الأقصى من memory usage في Keeper. | max_memory_usage_soft_limit_ratio * physical_memory_amount |
max_memory_usage_soft_limit_ratio |
إذا لم يتم تعيين max_memory_usage_soft_limit أو تم تعيينه إلى الصفر، تُستخدم هذه القيمة لتحديد soft limit الافتراضي. |
0.9 |
cgroups_memory_observer_wait_time |
إذا لم يتم تعيين max_memory_usage_soft_limit أو تم تعيينه إلى 0، نستخدم هذا interval لمراقبة حجم الذاكرة الفعلية. وعند تغيّر حجم الذاكرة، نعيد حساب soft limit لذاكرة Keeper باستخدام max_memory_usage_soft_limit_ratio. |
15 |
http_control |
تهيئة واجهة HTTP control. | - |
digest_enabled |
تمكين التحقق من اتساق البيانات في الوقت الفعلي | True |
create_snapshot_on_exit |
إنشاء لقطة عند إيقاف التشغيل | - |
hostname_checks_enabled |
تمكين عمليات التحقق من صحة hostname لتهيئة عنقود (على سبيل المثال، عند استخدام localhost مع endpoints بعيدة) | True |
four_letter_word_white_list |
white list لأوامر 4lw. | conf, cons, crst, envi, ruok, srst, srvr, stat, wchs, dirs, mntr, isro, rcvr, apiv, csnp, lgif, rqld, ydld |
enable_ipv6 |
تمكين IPv6 | True |
تُورَّث المعلمات الشائعة الأخرى من config الخاص بـ ClickHouse server (listen_host وlogger وما إلى ذلك).
إعدادات التنسيق الداخلية
توجد إعدادات التنسيق الداخلية في القسم <keeper_server>.<coordination_settings>، وتتضمن المعلمات التالية:
| المعلمة | الوصف | القيمة الافتراضية |
|---|---|---|
operation_timeout_ms |
مهلة عملية واحدة للعميل (مللي ثانية) | 10000 |
min_session_timeout_ms |
الحد الأدنى لمهلة جلسة العميل (مللي ثانية) | 10000 |
session_timeout_ms |
الحد الأقصى لمهلة جلسة العميل (مللي ثانية) | 100000 |
dead_session_check_period_ms |
مدى تكرار تحقّق ClickHouse Keeper من الجلسات المنتهية وإزالتها (مللي ثانية) | 500 |
heart_beat_interval_ms |
مدى تكرار إرسال قائد ClickHouse Keeper إشارات نبض إلى العُقد التابعة (مللي ثانية) | 500 |
election_timeout_lower_bound_ms |
إذا لم تستقبل العقدة التابعة إشارة نبض من القائد خلال هذه الفترة، فيمكنها بدء انتخاب القائد. يجب أن تكون هذه القيمة أقل من أو مساوية لـ election_timeout_upper_bound_ms. ومن الأفضل ألّا تكونا متساويتين. |
1000 |
election_timeout_upper_bound_ms |
إذا لم تستقبل العقدة التابعة إشارة نبض من القائد خلال هذه الفترة، فيجب عليها بدء انتخاب القائد. | 2000 |
rotate_log_storage_interval |
عدد سجلات Log التي تُخزَّن في ملف واحد. | 100000 |
reserved_log_items |
عدد سجلات التنسيق التي تُحفَظ قبل إجراء compaction. | 100000 |
snapshot_distance |
مدى تكرار إنشاء ClickHouse Keeper لقطات جديدة (بحسب عدد السجلات في الـ logs). | 100000 |
snapshots_to_keep |
عدد اللقطات المطلوب الاحتفاظ بها. | 3 |
stale_log_gap |
العتبة التي عندها يعتبر القائد العقدة التابعة stale ويرسل إليها لقطة بدلًا من logs. | 10000 |
fresh_log_gap |
الفجوة التي عندها تُعدّ العقدة محدَّثة. | 200 |
max_requests_batch_size |
الحد الأقصى لحجم Batch محسوبًا بعدد الطلبات قبل إرسالها إلى RAFT. | 100 |
force_sync |
استدعاء fsync عند كل عملية كتابة في سجل التنسيق. |
true |
quorum_reads |
تنفيذ طلبات القراءة كطلبات كتابة عبر توافق RAFT بالكامل وبسرعة مماثلة. | false |
raft_logs_level |
مستوى Logging النصي الخاص بالتنسيق (مثل trace وdebug وغير ذلك). | system default |
auto_forwarding |
السماح بإعادة توجيه طلبات الكتابة من العُقد التابعة إلى القائد. | true |
shutdown_timeout |
انتظار اكتمال الاتصالات الداخلية ثم إيقاف التشغيل (مللي ثانية). | 5000 |
startup_timeout |
إذا لم يتصل server ببقية المشاركين في النصاب خلال المهلة المحددة، فسينهي عمله (مللي ثانية). | 30000 |
async_replication |
تمكين replication غير المتزامن. تُحفَظ جميع ضمانات الكتابة والقراءة مع تحقيق أداء أفضل. هذا الإعداد معطّل افتراضيًا حتى لا يخلّ بالتوافق مع الإصدارات السابقة | false |
latest_logs_cache_size_threshold |
الحد الأقصى للحجم الإجمالي لذاكرة التخزين المؤقت داخل الذاكرة لأحدث log entries | 1GiB |
commit_logs_cache_size_threshold |
مهمل. يُستخدم مع log_readahead_commit_window_bytes إذا لم يكن هذا الإعداد مضبوطًا بحد ذاته. |
- |
commit_logs_cache_entry_count_threshold |
مهمل، ليس له أي تأثير. استخدم log_readahead_commit_window_bytes بدلًا منه. |
- |
log_readahead_enabled |
تمكين القراءة الاستباقية المفككة لكل peer لقراءات catch-up الخاصة بـ changelog (replication للعقدة التابعة). | false |
log_readahead_window_bytes |
الحد الأقصى لبايتات الإدخالات المفككة المخزنة مؤقتًا لكل قارئ peer. يجب أن يكون بحجم Batch نموذجي من append-entries على الأقل. | 64MiB |
log_readahead_max_peer_readers |
الحد الأقصى لعدد قرّاء القراءة الاستباقية المتزامنين لكل peer. | 8 |
log_readahead_eviction_timeout_ms |
مهلة الخمول التي بعدها يُزال قارئ قراءة استباقية غير نشط لكل peer، أو قارئ commit، من cache (وتُنشئه عملية إخفاق لاحقة من جديد). | 30000 |
log_readahead_pool_threads |
عدد threads في thread pool المخصص للقراءة الاستباقية. تستمد القيمة 0 من log_readahead_max_peer_readers. |
0 |
log_readahead_serve_wait_timeout_ms |
الحد الأقصى لوقت انتظار تعبئة القراءة الاستباقية في Background قبل الرجوع إلى قراءة مباشرة. | 200 |
log_readahead_chunk_size |
عدد إدخالات Log التي تُفك شفرتها لكل фрагмент في مهمة ملء القراءة الاستباقية. | 16 |
log_readahead_commit_window_bytes |
الحد الأقصى للحجم الإجمالي لإدخالات Log المفككة الشيفرة والمخزنة مؤقتًا مسبقًا أمام خيط تنفيذ commit. تُعطّل 0 القراءة الاستباقية لعملية commit (تقرأ commit الإدخالات من القرص واحدًا تلو الآخر). |
500MiB |
log_startup_read_max_streams |
الحد الأقصى لعدد ملفات changelog التي تُقرأ بالتزامن عند بدء تشغيل Keeper. 0 = استخدام عدد أنوية CPU تلقائيًا. 1 = استخدام قراءة بدء التشغيل التسلسلية (قبل التوازي). يُقيَّد التوازي الفعلي بعدد ملفات changelog المطلوب قراءتها؛ فكّر في خفضه عند استخدام تخزين مقيّد بعمليات seek (HDD، ووحدات التخزين المقيّدة بـ IOPS). |
0 |
log_startup_read_buffer_size |
حجم مخزن القراءة المؤقت لكل stream (بالبايت) المستخدم عند قراءة changelogs أثناء بدء تشغيل Keeper. يجب أن يكون أكبر من 0. كما يُقيَّد المخزن المؤقت بحجم الملف. |
8MiB |
disk_move_retries_wait_ms |
مدة الانتظار بين retries بعد حدوث فشل أثناء نقل ملف بين disks | 1000 |
disk_move_retries_during_init |
عدد retries بعد حدوث فشل أثناء نقل ملف بين disks خلال التهيئة | 100 |
experimental_use_rocksdb |
استخدام rocksdb كتخزين خلفي | 0 |
يوجد تهيئة النصاب في القسم <keeper_server>.<raft_configuration>، ويحتوي على وصف الخوادم.
المعلمة الوحيدة للنصاب بأكمله هي secure، الذي يفعّل اتصالًا مشفّرًا للتواصل بين المشاركين في النصاب. يمكن ضبط المعلمة على true إذا كان اتصال SSL مطلوبًا للتواصل الداخلي بين العقد، أو تركه غير محدد بخلاف ذلك.
المعلمات الرئيسية لكل <server> هي:
id— معرّف الخادم ضمن نصاب.hostname— hostname الذي يوجد عليه هذا الخادم.port— المنفذ الذي يستمع عليه هذا الخادم للاتصالات.can_become_leader— اضبطه علىfalseلتهيئة الخادم كـlearner. وإذا لم يُذكر، تكون القيمةtrue.
يمكن العثور على أمثلة لتهيئات نصاب بثلاث عقد في اختبارات التكامل التي تحمل البادئة test_keeper_. وفيما يلي مثال على تهيئة الخادم رقم 1:
<keeper_server>
<tcp_port>2181</tcp_port>
<server_id>1</server_id>
<log_storage_path>/var/lib/clickhouse/coordination/log</log_storage_path>
<snapshot_storage_path>/var/lib/clickhouse/coordination/snapshots</snapshot_storage_path>
<coordination_settings>
<operation_timeout_ms>10000</operation_timeout_ms>
<session_timeout_ms>30000</session_timeout_ms>
<raft_logs_level>trace</raft_logs_level>
</coordination_settings>
<raft_configuration>
<server>
<id>1</id>
<hostname>zoo1</hostname>
<port>9234</port>
</server>
<server>
<id>2</id>
<hostname>zoo2</hostname>
<port>9234</port>
</server>
<server>
<id>3</id>
<hostname>zoo3</hostname>
<port>9234</port>
</server>
</raft_configuration>
</keeper_server>كيفية التشغيل
يأتي ClickHouse Keeper مضمّنًا في حزمة ClickHouse server؛ ما عليك سوى إضافة إعدادات <keeper_server> إلى /etc/your_path_to_config/clickhouse-server/config.xml وتشغيل ClickHouse server كالمعتاد. وإذا أردت تشغيل standalone ClickHouse Keeper، فيمكنك تشغيله بطريقة مماثلة باستخدام:
clickhouse-keeper --config /etc/your_path_to_config/config.xmlإذا لم يكن لديك الرابط الرمزي (clickhouse-keeper)، يمكنك إنشاؤه أو تحديد keeper كوسيطة لـ clickhouse:
clickhouse keeper --config /etc/your_path_to_config/config.xmlأوامر الكلمات ذات الأحرف الأربعة
يوفّر ClickHouse Keeper أيضًا أوامر 4lw، وهي تكاد تكون مماثلة للأوامر الموجودة في ZooKeeper. يتكوّن كل أمر من أربعة أحرف، مثل mntr وstat وما إلى ذلك. وهناك بعض الأوامر اللافتة الأخرى: يوفّر stat معلومات عامة عن الخادم والعملاء المتصلين، ويقدّم srvr تفاصيل موسّعة عن الخادم، ويقدّم cons تفاصيل موسّعة عن الاتصالات.
تتضمن أوامر 4lw إعداد قائمة بيضاء باسم four_letter_word_white_list، وتكون قيمته الافتراضية conf,cons,crst,envi,ruok,srst,srvr,stat,wchs,dirs,mntr,isro,rcvr,apiv,csnp,lgif,rqld,ydld.
يمكنك إرسال هذه الأوامر إلى ClickHouse Keeper عبر telnet أو nc، من خلال منفذ العميل.
echo mntr | nc localhost 9181فيما يلي أوامر 4lw بالتفصيل:
ruok: يختبر ما إذا كان الخادم قيد التشغيل وفي حالة سليمة. سيردّ الخادم بـimokإذا كان قيد التشغيل. وإلا فلن يردّ إطلاقًا. ولا تعني استجابةimokبالضرورة أن الخادم قد انضم إلى النصاب، وإنما تعني فقط أن عملية الخادم نشطة ومرتبطة بمنفذ العميل المحدد. استخدم "stat" للحصول على تفاصيل عن الحالة فيما يتعلق بالنصاب ومعلومات اتصال العميل.
imokmntr: يعرض قائمة بالمتغيرات التي يمكن استخدامها لمراقبة حالة العنقود.
zk_version v21.11.1.1-prestable-7a4a0b0edef0ad6e0aa662cd3b90c3f4acf796e7
zk_avg_latency 0
zk_max_latency 0
zk_min_latency 0
zk_packets_received 68
zk_packets_sent 68
zk_num_alive_connections 1
zk_outstanding_requests 0
zk_server_state leader
zk_znode_count 4
zk_watch_count 1
zk_ephemerals_count 0
zk_approximate_data_size 723
zk_open_file_descriptor_count 310
zk_max_file_descriptor_count 10240
zk_leader_uptime 1234
zk_sum_leader_unavailable_time 1234
zk_cnt_leader_unavailable_time 1
zk_sum_election_time 1234
zk_cnt_election_time 1
zk_followers 0
zk_synced_followers 0zk_sum_leader_unavailable_time وzk_cnt_leader_unavailable_time وzk_sum_election_time وzk_cnt_election_time هي مقاييس تراكمية خاصة بالقائد فقط. وهي ملاحظات لكل خادم، وليست قياسات للتوافر على مستوى العنقود: يبدأ التتبع عندما يتوقف ذلك الخادم عن رصد قائد نشط. أثناء تقسيم الشبكة، قد يشمل ذلك وقتًا يظل فيه قائد سابق نشطًا في قسم آخر. ولا تسجل مقاييس الانتخاب إلا انتخابًا ناجحًا يلي نافذة محلية مرصودة لغياب القائد؛ ولا يُحتسب عمدًا نقل القيادة الذي لا يكشف عن حالة غياب قائد مأخوذة كعينة.
يأخذ Keeper عينة من حالة قائد NuRaft المحلية مرة كل heart_beat_interval_ms، ولكن ليس بمعدل يزيد على مرة كل 100 مللي ثانية. قد يختلف كل حد من حدود النافذة عن انتقال الحالة المحلية بما يصل إلى الفترة الفعلية، وقد لا تُرصد النوافذ الأقصر من تلك الفترة. يسجل Keeper اكتمال الانتخاب المحلي عند NuRaft BecomeLeader. يعيد srst تعيين القيم الأربع جميعًا.
تُصدَّر أيضًا مدة أحدث نافذة مرصودة محليًا من كل نوع إلى system.asynchronous_metrics باسمَي KeeperLastLeaderElectionTime وKeeperLastLeaderUnavailableTime، بالمللي ثانية. يتبع KeeperLastLeaderElectionTime تعريف نافذة غياب القائد نفسه المستخدم في zk_sum_election_time. وكلاهما خاص بالقائد فقط أيضًا: تُبلغ العقدة التي ليست القائد النشط، أو التي لم تُكمل نافذة بعد، عن 0. يعيد srst تعيينهما مع العدادات التراكمية.
srvr: يعرض التفاصيل الكاملة للخادم.
ClickHouse Keeper version: v21.11.1.1-prestable-7a4a0b0edef0ad6e0aa662cd3b90c3f4acf796e7
Latency min/avg/max: 0/0/0
Received: 2
Sent : 2
Connections: 1
Outstanding: 0
Zxid: 34
Mode: leader
Node count: 4stat: يعرض تفاصيل موجزة عن الخادم والعملاء المتصلين.
ClickHouse Keeper version: v21.11.1.1-prestable-7a4a0b0edef0ad6e0aa662cd3b90c3f4acf796e7
Clients:
192.168.1.1:52852(recved=0,sent=0)
192.168.1.1:52042(recved=24,sent=48)
Latency min/avg/max: 0/0/0
Received: 4
Sent : 4
Connections: 1
Outstanding: 0
Zxid: 36
Mode: leader
Node count: 4srst: إعادة ضبط إحصاءات الخادم. يؤثر الأمر في نتائجsrvrوmntrوstat.
Server stats reset.conf: اطبع تفاصيل تهيئة الخدمة.
server_id=1
tcp_port=2181
four_letter_word_white_list=*
log_storage_path=./coordination/logs
snapshot_storage_path=./coordination/snapshots
max_requests_batch_size=100
session_timeout_ms=30000
operation_timeout_ms=10000
dead_session_check_period_ms=500
heart_beat_interval_ms=500
election_timeout_lower_bound_ms=1000
election_timeout_upper_bound_ms=2000
reserved_log_items=1000000000000000
snapshot_distance=10000
auto_forwarding=true
shutdown_timeout=5000
startup_timeout=240000
raft_logs_level=information
snapshots_to_keep=3
rotate_log_storage_interval=100000
stale_log_gap=10000
fresh_log_gap=200
max_requests_batch_size=100
quorum_reads=false
force_sync=false
compress_logs=true
compress_snapshots_with_zstd_format=true
configuration_change_tries_count=20cons: يعرض تفاصيل الاتصال/الجلسة الكاملة لجميع العملاء المتصلين بهذا الخادم. ويتضمن معلومات عن عدد الحزم المستلمة/المرسلة، ومعرّف الجلسة، وزمن استجابة العمليات، وآخر عملية نُفِّذت، إلخ…
192.168.1.1:52163(recved=0,sent=0,sid=0xffffffffffffffff,lop=NA,est=1636454787393,to=30000,lzxid=0xffffffffffffffff,lresp=0,llat=0,minlat=0,avglat=0,maxlat=0)
192.168.1.1:52042(recved=9,sent=18,sid=0x0000000000000001,lop=List,est=1636454739887,to=30000,lcxid=0x0000000000000005,lzxid=0x0000000000000005,lresp=1636454739892,llat=0,minlat=0,avglat=0,maxlat=0)crst: إعادة ضبط إحصاءات الاتصال/الجلسة لجميع الاتصالات.
Connection stats reset.envi: اطبع تفاصيل بيئة التشغيل
Environment:
clickhouse.keeper.version=v21.11.1.1-prestable-7a4a0b0edef0ad6e0aa662cd3b90c3f4acf796e7
host.name=ZBMAC-C02D4054M.local
os.name=Darwin
os.arch=x86_64
os.version=19.6.0
cpu.count=12
user.name=root
user.home=/Users/JackyWoo/
user.dir=/Users/JackyWoo/project/jd/clickhouse/cmake-build-debug/programs/
user.tmp=/var/folders/b4/smbq5mfj7578f2jzwn602tt40000gn/T/dirs: يعرض الحجم الإجمالي لملفات اللقطات وملفات السجل، بالبايت
snapshot_dir_size: 0
log_dir_size: 3875isro: يختبر ما إذا كان الخادم يعمل بوضع القراءة فقط. يستجيب الخادم بـroإذا كان في وضع القراءة فقط، أو بـrwإذا لم يكن كذلك.
rwwchs: يعرض معلومات موجزة عن المراقِبات على الخادم.
1 connections watching 1 paths
Total watches:1wchc: يسرد معلومات تفصيلية عن الـ مراقِبات على الخادم بحسب الجلسة. ويُخرج هذا قائمة بالجلسات (الاتصالات) مع الـ مراقِبات (المسارات) المرتبطة بها. لاحظ أنه، وفقًا لعدد الـ مراقِبات، قد تكون هذه العملية مكلفة (وقد تؤثر في أداء الخادم)، لذا استخدمها بحذر.
0x0000000000000001
/clickhouse/task_queue/ddlwchp: يسرد معلومات تفصيلية عن عمليات مراقبات على الخادم بحسب المسار. ويعرض هذا الأمر قائمة بالمسارات (znodes) والجلسات المرتبطة بها. لاحظ أنه، وبحسب عدد عمليات مراقبات، قد تكون هذه العملية مكلفة (أي قد تؤثر في أداء الخادم)، لذا استخدمها بحذر.
/clickhouse/task_queue/ddl
0x0000000000000001dump: يعرض الجلسات المعلّقة والعُقد المؤقتة. لا يعمل هذا إلا على العقدة القائدة.
Sessions dump (2):
0x0000000000000001
0x0000000000000002
Sessions with Ephemerals (1):
0x0000000000000001
/clickhouse/task_queue/ddlcsnp: جدولة مهمة لإنشاء لقطة. يُرجِع آخر فهرس سجل مُلتزَم للّقطة المُجدولة عند النجاح، أوFailed to schedule snapshot creation task.عند الفشل. ويمكن أن يساعدك الأمرlgifفي تحديد ما إذا كانت اللقطة قد اكتملت.
100lgif: معلومات سجل Keeper.first_log_idx: أول فهرس سجل لديّ في مخزن السجل؛first_log_term: أول مُدة سجل لديّ؛last_log_idx: آخر فهرس سجل لديّ في مخزن السجل؛last_log_term: آخر مُدة سجل لديّ؛last_committed_log_idx: آخر فهرس سجل مُعتمَد لديّ في آلة الحالات؛leader_committed_log_idx: فهرس السجل المُعتمَد لدى القائد من وجهة نظري؛target_committed_log_idx: فهرس السجل المستهدف الذي ينبغي اعتماده؛last_snapshot_idx: أكبر فهرس سجل مُعتمَد في آخر لقطة.
first_log_idx 1
first_log_term 1
last_log_idx 101
last_log_term 1
last_committed_log_idx 100
leader_committed_log_idx 101
target_committed_log_idx 101
last_snapshot_idx 50rqld: طلب أن تصبح العقدة القائد الجديد. يُرجعSent leadership request to leader.إذا أُرسل الطلب، أوFailed to send leadership request to leader.إذا لم يُرسل. إذا كانت العقدة هي القائد بالفعل، تكون النتيجة مماثلة لحالة إرسال الطلب.
Sent leadership request to leader.ftfl: يعرض جميع علامات الميزة وما إذا كانت enabled لمثيل Keeper.
filtered_list 1
multi_read 1
check_not_exists 0ydld: طلب التخلي عن القيادة والتحول إلى تابع. إذا كان الخادم الذي يتلقى الطلب هو القائد، فسيُوقف عمليات الكتابة مؤقتًا أولًا، وينتظر حتى يُنهي الخلف (لا يمكن للقائد الحالي أن يكون الخلف أبدًا) استدراك أحدث سجل، ثم يتنحى. سيُختار الخلف تلقائيًا. يُرجعSent yield leadership request to leader.إذا أُرسل الطلب، أوFailed to send yield leadership request to leader.إذا لم يُرسل. وإذا كانت العقدة تابعًا بالفعل، تكون النتيجة مماثلة لنتيجة إرسال الطلب.
Sent yield leadership request to leader.pfev: يُرجِع قيم جميع الأحداث المجمّعة. ولكل حدث، يُرجِع اسم الحدث وقيمته ووصفه.
FileOpen 62 Number of files opened.
Seek 4 Number of times the 'lseek' function was called.
ReadBufferFromFileDescriptorRead 126 Number of reads (read/pread) from a file descriptor. Does not include sockets.
ReadBufferFromFileDescriptorReadFailed 0 Number of times the read (read/pread) from a file descriptor have failed.
ReadBufferFromFileDescriptorReadBytes 178846 Number of bytes read from file descriptors. If the file is compressed, this will show the compressed data size.
WriteBufferFromFileDescriptorWrite 7 Number of writes (write/pwrite) to a file descriptor. Does not include sockets.
WriteBufferFromFileDescriptorWriteFailed 0 Number of times the write (write/pwrite) to a file descriptor have failed.
WriteBufferFromFileDescriptorWriteBytes 153 Number of bytes written to file descriptors. If the file is compressed, this will show compressed data size.
FileSync 2 Number of times the F_FULLFSYNC/fsync/fdatasync function was called for files.
DirectorySync 0 Number of times the F_FULLFSYNC/fsync/fdatasync function was called for directories.
FileSyncElapsedMicroseconds 12756 Total time spent waiting for F_FULLFSYNC/fsync/fdatasync syscall for files.
DirectorySyncElapsedMicroseconds 0 Total time spent waiting for F_FULLFSYNC/fsync/fdatasync syscall for directories.
ReadCompressedBytes 0 Number of bytes (the number of bytes before decompression) read from compressed sources (files, network).
CompressedReadBufferBlocks 0 Number of compressed blocks (the blocks of data that are compressed independent of each other) read from compressed sources (files, network).
CompressedReadBufferBytes 0 Number of uncompressed bytes (the number of bytes after decompression) read from compressed sources (files, network).
AIOWrite 0 Number of writes with Linux or FreeBSD AIO interface
AIOWriteBytes 0 Number of bytes written with Linux or FreeBSD AIO interface
...HTTP control
يوفّر ClickHouse Keeper واجهة HTTP للتحقق مما إذا كانت النسخة المتماثلة جاهزة لاستقبال حركة المرور. ويمكن استخدام ذلك في البيئات السحابية، مثل Kubernetes.
مثال على تهيئة تفعّل نقطة النهاية /ready:
<clickhouse>
<keeper_server>
<http_control>
<port>9182</port>
<readiness>
<endpoint>/ready</endpoint>
</readiness>
</http_control>
</keeper_server>
</clickhouse>علامات الميزات
يتوافق Keeper توافقًا كاملًا مع ZooKeeper وعملائه، لكنه يقدّم أيضًا بعض الميزات وأنواع الطلبات الفريدة التي يمكن لعميل ClickHouse استخدامها.
ولأن هذه الميزات قد تؤدي إلى تغييرات غير متوافقة مع الإصدارات السابقة، فإن معظمها يكون معطّلًا افتراضيًا، ويمكن تمكينها باستخدام إعداد keeper_server.feature_flags.
كما يمكن تعطيل جميع الميزات صراحةً.
إذا كنت تريد تمكين ميزة جديدة في عنقود Keeper لديك، فنوصيك أولًا بتحديث جميع مثيلات Keeper في العنقود إلى إصدار يدعم هذه الميزة، ثم تمكين الميزة نفسها.
مثال على إعداد لعلامة ميزة يعطّل multi_read ويمكّن check_not_exists:
<clickhouse>
<keeper_server>
<feature_flags>
<multi_read>0</multi_read>
<check_not_exists>1</check_not_exists>
</feature_flags>
</keeper_server>
</clickhouse>الميزات التالية متاحة:
| Feature | Description | Default |
|---|---|---|
multi_read |
دعم طلبات قراءة متعددة | 1 |
filtered_list |
دعم طلب سرد يرشّح النتائج حسب نوع العقدة (مؤقتة أو دائمة) | 1 |
check_not_exists |
دعم طلب CheckNotExists، الذي يتحقق من أن العقدة غير موجودة |
1 |
create_if_not_exists |
دعم طلب CreateIfNotExists، الذي يحاول إنشاء عقدة إذا لم تكن موجودة. وإذا كانت موجودة، فلن تُطبَّق أي تغييرات وسيُعاد ZOK |
1 |
remove_recursive |
دعم طلب RemoveRecursive، الذي يزيل العقدة مع الشجرة الفرعية التابعة لها |
1 |
الترحيل من ZooKeeper
لا يمكن إجراء ترحيل سلس من ZooKeeper إلى ClickHouse Keeper. يجب عليك إيقاف عنقود ZooKeeper، وتحويل البيانات، ثم تشغيل ClickHouse Keeper. تحوّل أداة clickhouse-keeper-converter السجلات ولقطات الخاصة بـ ZooKeeper إلى لقطة لـ ClickHouse Keeper. وتتطلب ZooKeeper 3.4 أو إصدارًا أحدث.
التحضير قبل الترحيل
يتطلّب الترحيل إيقاف استيعاب البيانات. حدّد فترة صيانة قبل البدء.
قبل إيقاف ZooKeeper، أوقِف مهام ClickHouse الخلفية التي تعدّل البيانات الوصفية الخاصة بالتنسيق. على سبيل المثال:
SYSTEM STOP MERGES;سجّل مقاييس المقارنة قبل الترحيل حتى تتمكن من التحقق من الاتساق لاحقًا.
خطوات الترحيل
-
أوقف استيعاب البيانات إلى جميع عقد ClickHouse.
-
أوقف جميع المهام الخلفية على جميع عقد ClickHouse (راجع أعلاه).
-
أوقف جميع عقد ZooKeeper.
-
اختياري، لكنه مُوصى به: حدِّد العقدة القائدة في ZooKeeper، ثم شغّلها وأوقفها مرة أخرى. يُجبر ذلك ZooKeeper على كتابة لقطة متسقة على القرص قبل التحويل.
-
شغّل
clickhouse-keeper-converterعلى العقدة القائدة. إذا كان لديك الملف التنفيذي الكامل لـ ClickHouse مثبّتًا، فاستخدم الأمر الفرعيkeeper-converterبدلًا من ذلك (clickhouse keeper-converter). إذا لم يكن أيٌّ منهما متاحًا، نزّل الملف التنفيذي.
clickhouse-keeper-converter \
--zookeeper-logs-dir /var/lib/zookeeper/version-2 \
--zookeeper-snapshots-dir /var/lib/zookeeper/version-2 \
--output-dir /path/to/clickhouse/keeper/snapshots-
انسخ اللقطة إلى جميع عُقد ClickHouse Keeper. يجب أن تكون اللقطة موجودة على كل عقدة قبل بدء أي عقدة — فإذا بدأت عقدة من دون لقطة، فقد تنتخب نفسها قائدًا بحالة فارغة.
-
حدّث إعدادات ClickHouse لديك لتشير إلى عنقود Keeper الجديد.
-
ابدأ ClickHouse Keeper على جميع العقد، ثم أعد تشغيل ClickHouse.
-
قارِن المقاييس بخط الأساس قبل الترحيل للتحقق من الاتساق.
-
استأنف المهام الخلفية، وأعد تشغيل استيعاب البيانات.
دمج عدة عناقيد ZooKeeper
إذا كنت تشغّل عدة عناقيد ZooKeeper — على سبيل المثال، مجموعة واحدة لكل مجموعة shard — فيمكنك دمجها في عنقود ClickHouse Keeper واحد. لا تدعم أداة clickhouse-keeper-converter الرسمية سوى التحويلات من واحد إلى واحد (عنقود ZooKeeper واحد إلى لقطة Keeper واحدة)، لذلك يتطلب الدمج تعديل الشيفرة المصدرية للمحوّل لدمج عدة لقطات:
- شغّل
clickhouse-keeper-converterبشكل منفصل على كل عنقود ZooKeeper، واكتب كل ناتج في دليل منفصل. - ألغِ تسلسل ملفات اللقطات بالتتابع. وعند الدمج، أعد حساب قيم
numChildrenلتجنّب تعارض معرّفات العقد بين مساحات الأسماء القادمة من عناقيد المصدر المختلفة. - اكتب الناتج المدمج في دليل لقطات ClickHouse Keeper الهدف.
التعامل مع التشفير وقوائم ACL
يدعم ClickHouse Keeper مخططات ACL نفسها التي يدعمها ZooKeeper (world, auth, digest). وتعتمد طريقة التعامل مع قوائم ACL أثناء التحويل على إعداد ZooKeeper لديك:
- مشفَّر بالكامل أو غير مشفَّر بالكامل: حوِّل مباشرةً. يحافظ المحوِّل على معلومات ACL الحالية.
- مشفَّر جزئيًا: قبل التحويل، امنح حساب مسؤول فائق الصلاحيات وامسح قوائم ACL باستخدام
setAcl -Rعلى المسارات المتأثرة. حوِّل، ثم أعد تمكين التشفير في ClickHouse Keeper إذا لزم الأمر.
التحقق من الترحيل
بعد تشغيل ClickHouse Keeper وإعادة تشغيل ClickHouse، قارن المقاييس الرئيسية لديك بخط الأساس السابق للترحيل للتأكد من نجاح الترحيل.
عند دمج عدة عناقيد ZooKeeper، ميّز بين:
- المسارات المشتركة: المسارات الموجودة في عدة عناقيد مصدر وتحمل البيانات نفسها — يجب إزالة التكرار منها في المخرجات المدمجة.
- المسارات المتمايزة: المسارات التي لا توجد إلا ضمن عناقيد محددة (على سبيل المثال، تحت
/clickhouse/tablesلكل مجموعة shard) — يجب الحفاظ عليها من المصدر الصحيح.
تجنّب استعراض أشجار ZooKeeper الكبيرة مباشرةً لأغراض المقارنة. وبدلاً من ذلك، اطبع جميع المسارات المحوّلة إلى ملف أثناء التحويل.
الضبط بعد الترحيل
بعد الترحيل، فكّر في ضبط هذه الإعدادات للمجموعات العنقودية الأكبر أو لتحقيق إنتاجية أعلى:
| الإعداد | الافتراضي | الموصى به | ملاحظات |
|---|---|---|---|
max_requests_batch_size |
100 |
10000 |
زِد هذه القيمة للمجموعات العنقودية ذات الأعداد الكبيرة من الأجزاء أو التي تضم عددًا كبيرًا من الشظايا |
force_sync |
true |
false |
تُحسّن عمليات كتابة السجلات غير المتزامنة الإنتاجية |
compress_logs |
false |
true |
يضغط ملفات سجلات Raft لتقليل عمليات الإدخال/الإخراج على القرص |
compress_snapshots_with_zstd_format |
true |
— | مفعّل بالفعل افتراضيًا؛ ويضغط اللقطات باستخدام zstd |
تُضبط هذه الإعدادات ضمن coordination_settings في تهيئة Keeper.
الاستعادة بعد فقدان النصاب
نظرًا لأن ClickHouse Keeper يستخدم Raft، فإنه يستطيع تحمّل عدد معيّن من تعطل العُقد بحسب حجم العنقود. فعلى سبيل المثال، في عنقود مكوّن من 3 عُقد، سيواصل العمل بشكل صحيح إذا تعطلت عقدة واحدة فقط.
يمكن إعادة ضبط إعدادات العنقود ديناميكيًا، لكن هناك بعض القيود. تعتمد إعادة التهيئة أيضًا على Raft، لذا فإن إضافة عقدة إلى العنقود أو إزالتها منه تتطلب توفر نصاب. وإذا فقدت عددًا كبيرًا جدًا من العُقد في عنقودك في الوقت نفسه، من دون أي إمكانية لإعادة تشغيلها، فسيتوقف Raft عن العمل ولن يسمح لك بإعادة تهيئة عنقودك بالطريقة المعتادة.
ومع ذلك، يوفّر ClickHouse Keeper وضع استعادة يتيح لك فرض إعادة تهيئة عنقودك باستخدام عقدة واحدة فقط. ولا ينبغي اللجوء إلى ذلك إلا كحل أخير إذا تعذّر عليك إعادة تشغيل العُقد، أو تشغيل مثيل جديد على نقطة النهاية نفسها.
أمور مهمة يجب الانتباه إليها قبل المتابعة:
- تأكد من أن العُقد المتعطلة لا يمكنها الاتصال بالعنقود مرة أخرى.
- لا تبدأ تشغيل أي من العُقد الجديدة حتى يُذكر ذلك صراحةً في الخطوات.
بعد التأكد من صحة ما سبق، عليك القيام بما يلي:
- اختر عقدة Keeper واحدة لتكون القائد الجديد. انتبه إلى أن بيانات هذه العقدة ستُستخدم للعنقود بأكمله، لذلك نوصي باستخدام عقدة تحتوي على أحدث حالة ممكنة.
- قبل القيام بأي شيء آخر، أنشئ نسخة احتياطية من المجلدين
log_storage_pathوsnapshot_storage_pathفي العقدة التي اخترتها. - أعد تهيئة العنقود على جميع العُقد التي تريد استخدامها.
- أرسل الأمر المكوّن من أربعة أحرف
rcvrإلى العقدة التي اخترتها، مما سينقل العقدة إلى وضع الاستعادة، أو أوقف مثيل Keeper على العقدة المختارة ثم أعد تشغيله باستخدام الوسيط--force-recovery. - شغّل مثيلات Keeper على العُقد الجديدة واحدًا تلو الآخر، مع التأكد من أن
mntrيعيدfollowerفيzk_server_stateقبل تشغيل العقدة التالية. - أثناء وضع الاستعادة، سترجع عقدة القائد رسالة خطأ للأمر
mntrإلى أن تحقق النصاب مع العُقد الجديدة، كما سترفض أي طلبات من العميل ومن الـ التوابع. - بعد تحقيق النصاب، ستعود عقدة القائد إلى وضع التشغيل العادي، وتبدأ في قبول جميع الطلبات باستخدام Raft — ويمكنك التحقق من ذلك عبر
mntr، إذ ينبغي أن يعيدleaderفيzk_server_state.
استخدام الأقراص مع Keeper
يدعم Keeper مجموعة فرعية من الأقراص الخارجية لتخزين اللقطات وملفات السجل وملف الحالة.
أنواع الأقراص المدعومة هي:
- s3_plain
- s3
- local
فيما يلي مثال على تعريفات الأقراص الواردة داخل ملف إعداد.
<clickhouse>
<storage_configuration>
<disks>
<log_local>
<type>local</type>
<path>/var/lib/clickhouse/coordination/logs/</path>
</log_local>
<log_s3_plain>
<type>s3_plain</type>
<endpoint>https://some_s3_endpoint/logs/</endpoint>
<access_key_id>ACCESS_KEY</access_key_id>
<secret_access_key>SECRET_KEY</secret_access_key>
</log_s3_plain>
<snapshot_local>
<type>local</type>
<path>/var/lib/clickhouse/coordination/snapshots/</path>
</snapshot_local>
<snapshot_s3_plain>
<type>s3_plain</type>
<endpoint>https://some_s3_endpoint/snapshots/</endpoint>
<access_key_id>ACCESS_KEY</access_key_id>
<secret_access_key>SECRET_KEY</secret_access_key>
</snapshot_s3_plain>
<state_s3_plain>
<type>s3_plain</type>
<endpoint>https://some_s3_endpoint/state/</endpoint>
<access_key_id>ACCESS_KEY</access_key_id>
<secret_access_key>SECRET_KEY</secret_access_key>
</state_s3_plain>
</disks>
</storage_configuration>
</clickhouse>لاستخدام قرص للسجلات، يجب ضبط الإعداد keeper_server.log_storage_disk على اسم القرص.
لاستخدام قرص للقطات، يجب ضبط الإعداد keeper_server.snapshot_storage_disk على اسم القرص.
بالإضافة إلى ذلك، يمكن استخدام keeper_server.latest_log_storage_disk لأحدث السجلات وkeeper_server.latest_snapshot_storage_disk لأحدث اللقطات.
في هذه الحالة، سينقل Keeper الملفات تلقائيًا إلى الأقراص الصحيحة عند إنشاء سجلات أو لقطات جديدة.
لاستخدام قرص لملف الحالة، يجب ضبط الإعداد keeper_server.state_storage_disk على اسم القرص.
يُعد نقل الملفات بين الأقراص آمنًا، ولا توجد أي مخاطر لفقدان البيانات إذا توقف Keeper في منتصف عملية النقل. وإلى أن يُنقل الملف بالكامل إلى القرص الجديد، فلن يُحذف من القرص القديم.
لا يمكن لـ Keeper عند ضبط keeper_server.coordination_settings.force_sync على true (والقيمة الافتراضية هي true) تلبية بعض الضمانات لجميع أنواع الأقراص.
في الوقت الحالي، لا تدعم المزامنة الدائمة إلا الأقراص من النوع local.
إذا استُخدم force_sync، فيجب أن يكون log_storage_disk قرصًا من النوع local إذا لم يُستخدم latest_log_storage_disk.
أما إذا استُخدم latest_log_storage_disk، فيجب أن يكون دائمًا قرصًا من النوع local.
إذا كان force_sync معطّلًا، فيمكن استخدام الأقراص من جميع الأنواع في أي إعداد.
يمكن أن يبدو إعداد تخزين محتمل لمثيل Keeper كما يلي:
<clickhouse>
<keeper_server>
<log_storage_disk>log_s3_plain</log_storage_disk>
<latest_log_storage_disk>log_local</latest_log_storage_disk>
<snapshot_storage_disk>snapshot_s3_plain</snapshot_storage_disk>
<latest_snapshot_storage_disk>snapshot_local</latest_snapshot_storage_disk>
</keeper_server>
</clickhouse>سيخزّن هذا المثيل جميع السجلات ما عدا أحدث السجلات على القرص log_s3_plain، بينما سيُحفَظ أحدث سجل على القرص log_local.
وينطبق المنطق نفسه على اللقطات؛ إذ ستُخزَّن جميع اللقطات ما عدا أحدث اللقطات على snapshot_s3_plain، بينما سيُحفَظ أحدث لقطة على القرص snapshot_local.
تغيير إعداد الأقراص
إذا كان قد جرى تعريف إعداد أقراص متدرّج (باستخدام أقراص منفصلة لأحدث الملفات)، فسيحاول Keeper نقل الملفات تلقائيًا إلى الأقراص الصحيحة عند بدء التشغيل. وينطبق الضمان نفسه كما في السابق؛ فإلى أن يُنقَل الملف بالكامل إلى القرص الجديد، لن يُحذَف من القرص القديم، لذا يمكن إجراء عمليات إعادة تشغيل متعددة بأمان.
إذا كان من الضروري نقل الملفات إلى قرص جديد بالكامل (أو الانتقال من إعداد ذي قرصين إلى إعداد ذي قرص واحد)، فيمكن استخدام تعريفات متعددة لـ keeper_server.old_snapshot_storage_disk و keeper_server.old_log_storage_disk.
يوضح التكوين التالي كيف يمكننا الانتقال من إعداد القرصين السابق إلى إعداد جديد بالكامل ذي قرص واحد:
<clickhouse>
<keeper_server>
<old_log_storage_disk>log_local</old_log_storage_disk>
<old_log_storage_disk>log_s3_plain</old_log_storage_disk>
<log_storage_disk>log_local2</log_storage_disk>
<old_snapshot_storage_disk>snapshot_s3_plain</old_snapshot_storage_disk>
<old_snapshot_storage_disk>snapshot_local</old_snapshot_storage_disk>
<snapshot_storage_disk>snapshot_local2</snapshot_storage_disk>
</keeper_server>
</clickhouse>عند بدء التشغيل، ستُنقل جميع ملفات السجل من log_local وlog_s3_plain إلى القرص log_local2.
كما ستُنقل جميع ملفات اللقطات من snapshot_local وsnapshot_s3_plain إلى القرص snapshot_local2.
تهيئة ذاكرة التخزين المؤقت للسجلات
لتقليل كمية البيانات المقروءة من القرص، يخزّن Keeper إدخالات السجل مؤقتًا في الذاكرة. إذا كانت الطلبات كبيرة، ستستهلك إدخالات السجل قدرًا كبيرًا من الذاكرة، لذا يُفرض حدّ على كمية السجلات المخزنة مؤقتًا. يُتحكَّم في حدّ ذاكرة التخزين المؤقت لأحدث السجلات بواسطة:
latest_logs_cache_size_threshold- الحجم الإجمالي لأحدث السجلات المخزنة مؤقتًا
إذا كانت القيمة الافتراضية كبيرة جدًا، يمكنك تقليل استخدام الذاكرة بتقليل هذا الإعداد.
تُقدَّم إدخالات السجل اللازمة لاحقًا لإجراء الالتزام بواسطة قارئ استباقي يفكّ الترميز، ويُحدَّد حجمه بواسطة
log_readahead_commit_window_bytes (تؤدي القيمة 0 إلى تعطيل القراءة الاستباقية للالتزام). يحل هذا الإعداد محل الإعدادين
المهملين commit_logs_cache_size_threshold وcommit_logs_cache_entry_count_threshold،
اللذين يُحتفظ بهما فقط للتوافق مع الإعدادات (لا يزال الأول يُعيَّن إلى log_readahead_commit_window_bytes إذا
لم يُضبط؛ أما الثاني فلا تأثير له). وتخدم آلية القراءة الاستباقية نفسها أيضًا قراءات استدراك النسخ المتماثل
للعُقد التابعة عندما تكون قيمة log_readahead_enabled هي true؛ راجع
log_readahead_window_bytes وlog_readahead_max_peer_readers وlog_readahead_eviction_timeout_ms،
وlog_readahead_pool_threads وlog_readahead_serve_wait_timeout_ms وlog_readahead_chunk_size
في إعدادات التنسيق الداخلية لمعرفة خيارات الضبط
الخاصة بجانب النظير.
Prometheus
يمكن لـ Keeper كشف بيانات المقاييس ليتمكّن Prometheus من سحبها.
الإعدادات:
endpoint– نقطة نهاية HTTP لسحب المقاييس بواسطة خادم Prometheus. ابدأ من '/'.port– المنفذ الخاص بـendpoint.metrics– خيار يحدد كشف المقاييس من جدول system.metrics.events– خيار يحدد كشف المقاييس من جدول system.events.asynchronous_metrics– خيار يحدد كشف قيم المقاييس الحالية من جدول system.asynchronous_metrics.
مثال
<clickhouse>
<listen_host>0.0.0.0</listen_host>
<http_port>8123</http_port>
<tcp_port>9000</tcp_port>
<prometheus>
<endpoint>/metrics</endpoint>
<port>9363</port>
<metrics>true</metrics>
<events>true</events>
<asynchronous_metrics>true</asynchronous_metrics>
</prometheus>
</clickhouse>تحقّق (استبدل 127.0.0.1 بعنوان IP أو اسم المضيف لخادم ClickHouse لديك):
curl 127.0.0.1:9363/metricsراجع أيضًا تكامل Prometheus في ClickHouse Cloud.
دليل المستخدم لـ ClickHouse Keeper
يوفّر هذا الدليل إعدادات بسيطة ومختصرة لتهيئة ClickHouse Keeper، مع مثال يوضّح كيفية اختبار العمليات الموزعة. يُنفَّذ هذا المثال باستخدام 3 عقد على Linux.
هيِّئ العقد باستخدام إعدادات Keeper
-
ثبّت 3 مثيلات ClickHouse على 3 مضيفات (
chnode1,chnode2,chnode3). (راجع Quick Start للحصول على تفاصيل حول تثبيت ClickHouse.) -
على كل عقدة، أضِف السطر التالي للسماح بالاتصال الخارجي عبر واجهة الشبكة.
<listen_host>0.0.0.0</listen_host> -
أضف إعداد ClickHouse Keeper التالي إلى الخوادم الثلاثة، مع تحديث إعداد
<server_id>لكل خادم؛ ففيchnode1تكون القيمة1، وفيchnode2تكون2، وهكذا.<keeper_server> <tcp_port>9181</tcp_port> <server_id>1</server_id> <log_storage_path>/var/lib/clickhouse/coordination/log</log_storage_path> <snapshot_storage_path>/var/lib/clickhouse/coordination/snapshots</snapshot_storage_path> <coordination_settings> <operation_timeout_ms>10000</operation_timeout_ms> <session_timeout_ms>30000</session_timeout_ms> <raft_logs_level>warning</raft_logs_level> </coordination_settings> <raft_configuration> <server> <id>1</id> <hostname>chnode1.domain.com</hostname> <port>9234</port> </server> <server> <id>2</id> <hostname>chnode2.domain.com</hostname> <port>9234</port> </server> <server> <id>3</id> <hostname>chnode3.domain.com</hostname> <port>9234</port> </server> </raft_configuration> </keeper_server>فيما يلي الإعدادات الأساسية المستخدمة أعلاه:
المعلمة الوصف مثال tcp_port المنفذ الذي سيستخدمه عملاء Keeper 9181، وهو المكافئ الافتراضي لـ 2181 كما في ZooKeeper server_id المعرّف الخاص بكل خادم ClickHouse Keeper والمستخدم في تهيئة raft 1 coordination_settings قسم خاص بمعلمات مثل المهل الزمنية timeouts: 10000, log level: trace server تعريف الخادم المشارك قائمة بتعريف كل خادم raft_configuration إعدادات كل خادم في عنقود Keeper الخادم والإعدادات الخاصة بكل خادم id المعرّف الرقمي للخادم في خدمات Keeper 1 hostname اسم المضيف أو عنوان IP أو FQDN لكل خادم في عنقود Keeper chnode1.domain.comport المنفذ الذي يستمع عليه لاتصالات Keeper بين الخوادم 9234 -
فعِّل مكوّن Zookeeper. سيستخدم محرّك ClickHouse Keeper:
<zookeeper> <node> <host>chnode1.domain.com</host> <port>9181</port> </node> <node> <host>chnode2.domain.com</host> <port>9181</port> </node> <node> <host>chnode3.domain.com</host> <port>9181</port> </node> </zookeeper>فيما يلي الإعدادات الأساسية المستخدمة أعلاه:
المعلمة الوصف مثال node قائمة بالعُقد الخاصة باتصالات ClickHouse Keeper إدخال في الإعدادات لكل خادم host اسم المضيف أو عنوان IP أو الاسم المؤهل بالكامل (FQDN) لكل عقدة ClickHouse Keeper chnode1.domain.comport منفذ العميل لـ ClickHouse Keeper 9181 -
أعد تشغيل ClickHouse وتأكد من أن كل مثيل من Keeper يعمل. نفّذ الأمر التالي على كل خادم. يُرجع الأمر
ruokالقيمةimokإذا كان Keeper يعمل وبحالة سليمة:# echo ruok | nc localhost 9181; echo imok -
تحتوي قاعدة البيانات
systemعلى جدول باسمzookeeperيتضمن تفاصيل مثيلات ClickHouse Keeper لديك. لنعرض هذا الجدول:SELECT * FROM system.zookeeper WHERE path IN ('/', '/clickhouse')يظهر الجدول كما يلي:
┌─name───────┬─value─┬─czxid─┬─mzxid─┬───────────────ctime─┬───────────────mtime─┬─version─┬─cversion─┬─aversion─┬─ephemeralOwner─┬─dataLength─┬─numChildren─┬─pzxid─┬─path────────┐ │ clickhouse │ │ 124 │ 124 │ 2022-03-07 00:49:34 │ 2022-03-07 00:49:34 │ 0 │ 2 │ 0 │ 0 │ 0 │ 2 │ 5693 │ / │ │ task_queue │ │ 125 │ 125 │ 2022-03-07 00:49:34 │ 2022-03-07 00:49:34 │ 0 │ 1 │ 0 │ 0 │ 0 │ 1 │ 126 │ /clickhouse │ │ tables │ │ 5693 │ 5693 │ 2022-03-07 00:49:34 │ 2022-03-07 00:49:34 │ 0 │ 3 │ 0 │ 0 │ 0 │ 3 │ 6461 │ /clickhouse │ └────────────┴───────┴───────┴───────┴─────────────────────┴─────────────────────┴─────────┴──────────┴──────────┴────────────────┴────────────┴─────────────┴───────┴─────────────┘
إعداد عنقود في ClickHouse
-
لنُعِدّ عنقودًا بسيطًا يتكوّن من shardَين ونسخة replica واحدة فقط على عقدتين من العُقد. ستُستخدم العقدة الثالثة لتحقيق النصاب المطلوب في ClickHouse Keeper. حدّث الإعداد على
chnode1وchnode2. يعرّف العنقود التالي shard واحدة على كل عقدة، ليصبح المجموع shardَين من دون replication. في هذا المثال، سيكون جزء من البيانات على إحدى العقد، والجزء الآخر على العقدة الثانية:<remote_servers> <cluster_2S_1R> <shard> <replica> <host>chnode1.domain.com</host> <port>9000</port> <user>default</user> <password>ClickHouse123!</password> </replica> </shard> <shard> <replica> <host>chnode2.domain.com</host> <port>9000</port> <user>default</user> <password>ClickHouse123!</password> </replica> </shard> </cluster_2S_1R> </remote_servers>Parameter Description Example shard قائمة بالنسخ replicas في تعريف العنقود قائمة بالنسخ replicas لكل shard replica قائمة بالإعدادات الخاصة بكل replica إدخالات الإعدادات لكل replica host اسم المضيف أو عنوان IP أو الاسم المؤهل بالكامل (FQDN) للخادم الذي سيستضيف shard replica chnode1.domain.comport المنفذ المستخدم للتواصل عبر بروتوكول TCP الأصلي 9000 user اسم المستخدم الذي سيُستخدم للمصادقة على مثيلات العنقود default password كلمة مرور المستخدم المعرّف للسماح بالاتصال بمثيلات العنقود ClickHouse123! -
أعد تشغيل ClickHouse وتحقّق من إنشاء العنقود:
SHOW clusters;ينبغي أن ترى عنقودك:
┌─cluster───────┐ │ cluster_2S_1R │ └───────────────┘
إنشاء جدول موزّع واختباره
-
أنشئ قاعدة بيانات جديدة على العنقود الجديد باستخدام عميل ClickHouse على
chnode1. تؤدي عبارةON CLUSTERتلقائيًا إلى إنشاء قاعدة البيانات على كلتا العقدتين.CREATE DATABASE db1 ON CLUSTER 'cluster_2S_1R'; -
أنشئ جدولًا جديدًا في قاعدة البيانات
db1. ومرة أخرى، يؤديON CLUSTERإلى إنشاء الجدول على كلتا العقدتين.CREATE TABLE db1.table1 on cluster 'cluster_2S_1R' ( `id` UInt64, `column1` String ) ENGINE = MergeTree ORDER BY column1 -
على العقدة
chnode1، أضِف صفّين:INSERT INTO db1.table1 (id, column1) VALUES (1, 'abc'), (2, 'def') -
أضِف صفّين على العقدة
chnode2:INSERT INTO db1.table1 (id, column1) VALUES (3, 'ghi'), (4, 'jkl') -
لاحظ أن تشغيل عبارة
SELECTعلى كل عقدة لا يُظهر إلا البيانات الموجودة على تلك العقدة. على سبيل المثال، علىchnode1:SELECT * FROM db1.table1Query id: 7ef1edbc-df25-462b-a9d4-3fe6f9cb0b6d ┌─id─┬─column1─┐ │ 1 │ abc │ │ 2 │ def │ └────┴─────────┘ 2 rows in set. Elapsed: 0.006 sec.على
chnode2: -
SELECT * FROM db1.table1Query id: c43763cc-c69c-4bcc-afbe-50e764adfcbf ┌─id─┬─column1─┐ │ 3 │ ghi │ │ 4 │ jkl │ └────┴─────────┘ -
يمكنك إنشاء جدول
Distributedلتمثيل البيانات على الجزأين. الجداول التي تستخدم محرّك الجداولDistributedلا تخزّن أي بيانات خاصة بها، لكنها تتيح معالجة الاستعلامات الموزعة عبر عدة خوادم. تصل عمليات القراءة إلى جميع الأجزاء، ويمكن توزيع عمليات الكتابة عبر الأجزاء. شغّل الاستعلام التالي علىchnode1:CREATE TABLE db1.dist_table ( id UInt64, column1 String ) ENGINE = Distributed(cluster_2S_1R,db1,table1) -
لاحظ أن الاستعلام عن
dist_tableيُرجع صفوف البيانات الأربعة كلها من الجزأين:SELECT * FROM db1.dist_tableQuery id: 495bffa0-f849-4a0c-aeea-d7115a54747a ┌─id─┬─column1─┐ │ 1 │ abc │ │ 2 │ def │ └────┴─────────┘ ┌─id─┬─column1─┐ │ 3 │ ghi │ │ 4 │ jkl │ └────┴─────────┘ 4 rows in set. Elapsed: 0.018 sec.
الملخص
يشرح هذا الدليل كيفية إعداد عنقود باستخدام ClickHouse Keeper. وباستخدام ClickHouse Keeper، يمكنك تهيئة العناقيد وتعريف الجداول الموزعة التي يمكن نسخها متماثلًا عبر الشوارد.
تهيئة ClickHouse Keeper بمسارات فريدة
الوصف
تشرح هذه المقالة كيفية استخدام إعداد الماكرو المضمّن {uuid}
لإنشاء إدخالات فريدة في ClickHouse Keeper أو ZooKeeper. وتفيد
المسارات الفريدة عند إنشاء الجداول وحذفها بشكل متكرر، لأن
ذلك يجنّبك الاضطرار إلى الانتظار عدة دقائق حتى يزيل جمع المهملات في Keeper
إدخالات المسارات، إذ يُستخدم uuid جديد في ذلك المسار
في كل مرة يُنشأ فيها مسار؛ ولا يُعاد استخدام المسارات مطلقًا.
بيئة مثال
عنقود مكوّن من ثلاث عقد سيُهيَّأ بحيث يعمل ClickHouse Keeper على العقد الثلاث جميعها، ويعمل ClickHouse على عقدتين منها. يوفّر هذا لـ ClickHouse Keeper ثلاث عقد (بما في ذلك عقدة فكّ التعادل)، و شارد واحدًا لـ ClickHouse مكوّنًا من نسختين متماثلتين.
| node | الوصف |
|---|---|
chnode1.marsnet.local |
عقدة بيانات - عنقود cluster_1S_2R |
chnode2.marsnet.local |
عقدة بيانات - عنقود cluster_1S_2R |
chnode3.marsnet.local |
عقدة فكّ التعادل لـ ClickHouse Keeper |
مثال على إعداد العنقود:
<remote_servers>
<cluster_1S_2R>
<shard>
<replica>
<host>chnode1.marsnet.local</host>
<port>9440</port>
<user>default</user>
<password>ClickHouse123!</password>
<secure>1</secure>
</replica>
<replica>
<host>chnode2.marsnet.local</host>
<port>9440</port>
<user>default</user>
<password>ClickHouse123!</password>
<secure>1</secure>
</replica>
</shard>
</cluster_1S_2R>
</remote_servers>إجراءات إعداد الجداول لاستخدام {uuid}
- اضبط وحدات الماكرو على كل خادم مثال على الخادم 1:
<macros>
<shard>1</shard>
<replica>replica_1</replica>
</macros>- أنشئ قاعدة بيانات
CREATE DATABASE db_uuid
ON CLUSTER 'cluster_1S_2R'
ENGINE Atomic;CREATE DATABASE db_uuid ON CLUSTER cluster_1S_2R
ENGINE = Atomic
Query id: 07fb7e65-beb4-4c30-b3ef-bd303e5c42b5
┌─host──────────────────┬─port─┬─status─┬─error─┬─num_hosts_remaining─┬─num_hosts_active─┐
│ chnode2.marsnet.local │ 9440 │ 0 │ │ 1 │ 0 │
│ chnode1.marsnet.local │ 9440 │ 0 │ │ 0 │ 0 │
└───────────────────────┴──────┴────────┴───────┴─────────────────────┴──────────────────┘- أنشئ جدولًا في العنقود باستخدام وحدات الماكرو و
{uuid}
CREATE TABLE db_uuid.uuid_table1 ON CLUSTER 'cluster_1S_2R'
(
id UInt64,
column1 String
)
ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/db_uuid/{uuid}', '{replica}' )
ORDER BY (id);CREATE TABLE db_uuid.uuid_table1 ON CLUSTER cluster_1S_2R
(
`id` UInt64,
`column1` String
)
ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/db_uuid/{uuid}', '{replica}')
ORDER BY id
Query id: 8f542664-4548-4a02-bd2a-6f2c973d0dc4
┌─host──────────────────┬─port─┬─status─┬─error─┬─num_hosts_remaining─┬─num_hosts_active─┐
│ chnode1.marsnet.local │ 9440 │ 0 │ │ 1 │ 0 │
│ chnode2.marsnet.local │ 9440 │ 0 │ │ 0 │ 0 │
└───────────────────────┴──────┴────────┴───────┴─────────────────────┴──────────────────┘- أنشئ جدولًا موزعًا
CREATE TABLE db_uuid.dist_uuid_table1 ON CLUSTER 'cluster_1S_2R'
(
id UInt64,
column1 String
)
ENGINE = Distributed('cluster_1S_2R', 'db_uuid', 'uuid_table1' );CREATE TABLE db_uuid.dist_uuid_table1 ON CLUSTER cluster_1S_2R
(
`id` UInt64,
`column1` String
)
ENGINE = Distributed('cluster_1S_2R', 'db_uuid', 'uuid_table1')
Query id: 3bc7f339-ab74-4c7d-a752-1ffe54219c0e
┌─host──────────────────┬─port─┬─status─┬─error─┬─num_hosts_remaining─┬─num_hosts_active─┐
│ chnode2.marsnet.local │ 9440 │ 0 │ │ 1 │ 0 │
│ chnode1.marsnet.local │ 9440 │ 0 │ │ 0 │ 0 │
└───────────────────────┴──────┴────────┴───────┴─────────────────────┴──────────────────┘الاختبار
- أدرِج البيانات في العقدة الأولى (مثل
chnode1)
INSERT INTO db_uuid.uuid_table1
( id, column1)
VALUES
( 1, 'abc');INSERT INTO db_uuid.uuid_table1 (id, column1) FORMAT Values
Query id: 0f178db7-50a6-48e2-9a1b-52ed14e6e0f9
Ok.
1 row in set. Elapsed: 0.033 sec.- أدرِج البيانات في العقدة الثانية (على سبيل المثال،
chnode2)
INSERT INTO db_uuid.uuid_table1
( id, column1)
VALUES
( 2, 'def');INSERT INTO db_uuid.uuid_table1 (id, column1) FORMAT Values
Query id: edc6f999-3e7d-40a0-8a29-3137e97e3607
Ok.
1 row in set. Elapsed: 0.529 sec.- اعرض السجلات باستخدام جدول موزّع
SELECT * FROM db_uuid.dist_uuid_table1;SELECT *
FROM db_uuid.dist_uuid_table1
Query id: 6cbab449-9e7f-40fe-b8c2-62d46ba9f5c8
┌─id─┬─column1─┐
│ 1 │ abc │
└────┴─────────┘
┌─id─┬─column1─┐
│ 2 │ def │
└────┴─────────┘
2 rows in set. Elapsed: 0.007 sec.بدائل
يمكن تحديد مسار النسخ المتماثل الافتراضي مسبقًا باستخدام وحدات الماكرو و{uuid} أيضًا
- عيّن الإعداد الافتراضي للجداول على كل عقدة
<default_replica_path>/clickhouse/tables/{shard}/db_uuid/{uuid}</default_replica_path>
<default_replica_name>{replica}</default_replica_name>- أنشئ جدولًا بدون معلمات صريحة:
CREATE TABLE db_uuid.uuid_table1 ON CLUSTER 'cluster_1S_2R'
(
id UInt64,
column1 String
)
ENGINE = ReplicatedMergeTree
ORDER BY (id);CREATE TABLE db_uuid.uuid_table1 ON CLUSTER cluster_1S_2R
(
`id` UInt64,
`column1` String
)
ENGINE = ReplicatedMergeTree
ORDER BY id
Query id: ab68cda9-ae41-4d6d-8d3b-20d8255774ee
┌─host──────────────────┬─port─┬─status─┬─error─┬─num_hosts_remaining─┬─num_hosts_active─┐
│ chnode2.marsnet.local │ 9440 │ 0 │ │ 1 │ 0 │
│ chnode1.marsnet.local │ 9440 │ 0 │ │ 0 │ 0 │
└───────────────────────┴──────┴────────┴───────┴─────────────────────┴──────────────────┘
2 rows in set. Elapsed: 1.175 sec.- تحقّق من أنه استخدم الإعدادات نفسها المستخدمة في التهيئة الافتراضية
SHOW CREATE TABLE db_uuid.uuid_table1;SHOW CREATE TABLE db_uuid.uuid_table1
CREATE TABLE db_uuid.uuid_table1
(
`id` UInt64,
`column1` String
)
ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/db_uuid/{uuid}', '{replica}')
ORDER BY id
1 row in set. Elapsed: 0.003 sec.استكشاف الأخطاء وإصلاحها
مثال لأمر يعرض معلومات الجدول ومعرّف UUID الخاص به:
SELECT * FROM system.tables
WHERE database = 'db_uuid' AND name = 'uuid_table1';مثال على أمر للحصول على معلومات عن الجدول في ZooKeeper باستخدام معرّف UUID الخاص بالجدول أعلاه
SELECT * FROM system.zookeeper
WHERE path = '/clickhouse/tables/1/db_uuid/9e8a3cc2-0dec-4438-81a7-c3e63ce2a1cf/replicas';للتحقّق:
على سبيل المثال،
SELECT name, engine FROM system.databases WHERE name = 'db_uuid';SELECT
name,
engine
FROM system.databases
WHERE name = 'db_uuid'
Query id: b047d459-a1d2-4016-bcf9-3e97e30e49c2
┌─name────┬─engine─┐
│ db_uuid │ Atomic │
└─────────┴────────┘
1 row in set. Elapsed: 0.004 sec.إعادة التهيئة الديناميكية لـ ClickHouse Keeper
الوصف
يدعم ClickHouse Keeper جزئيًا أمر ZooKeeper reconfig
لإعادة تهيئة العنقود ديناميكيًا إذا كان keeper_server.enable_reconfiguration مفعّلًا.
تحتوي العقدة الافتراضية /keeper/config على آخر تهيئة معتمدة للعنقود بالتنسيق التالي:
server.id = server_host:server_port[;server_type][;server_priority]
server.id2 = ...
...- يُفصل كل إدخال خادم بسطر جديد.
- تكون قيمة
server_typeإماparticipantأوlearner(learner لا يشارك في انتخابات القائد). server_priorityهو عدد صحيح غير سالب يحدد العُقد التي ينبغي إعطاؤها أولوية في انتخابات القائد. وتعني الأولوية 0 أن الخادم لن يكون القائد مطلقًا.
مثال:
:) get /keeper/config
server.1=zoo1:9234;participant;1
server.2=zoo2:9234;participant;1
server.3=zoo3:9234;participant;1يمكنك استخدام الأمر reconfig لإضافة خوادم جديدة، وإزالة الخوادم الموجودة، وتغيير أولويات الخوادم الحالية،
وفيما يلي أمثلة (باستخدام clickhouse-keeper-client):
# Add two new servers
reconfig add "server.5=localhost:123,server.6=localhost:234;learner"
# Remove two other servers
reconfig remove "3,4"
# Change existing server priority to 8
reconfig add "server.5=localhost:5123;participant;8"وفيما يلي أمثلة على kazoo:
# Add two new servers, remove two other servers
reconfig(joining="server.5=localhost:123,server.6=localhost:234;learner", leaving="3,4")
# Change existing server priority to 8
reconfig(joining="server.5=localhost:5123;participant;8", leaving=None)يجب أن تكون الخوادم في joining بتنسيق الخادم الموضّح أعلاه. ويجب فصل مُدخلات الخوادم بفواصل.
عند إضافة خوادم جديدة، يمكنك إغفال server_priority (القيمة الافتراضية هي 1) وserver_type (القيمة الافتراضية
هي participant).
إذا كنت تريد تغيير أولوية خادم موجود، فأضِفه إلى joining مع الأولوية المستهدفة.
يجب أن يتطابق مضيف الخادم والمنفذ والنوع مع تهيئة الخادم الحالية.
تُضاف الخوادم وتُزال وفقًا لترتيب ظهورها في joining وleaving.
تُعالَج جميع التحديثات الواردة من joining قبل التحديثات الواردة من leaving.
هناك بعض الملاحظات المهمة المتعلقة بتنفيذ إعادة تهيئة Keeper:
-
لا تُدعَم إلا إعادة التهيئة التدريجية. وتُرفض الطلبات التي تحتوي على
new_membersغير فارغ.يعتمد تنفيذ ClickHouse Keeper على واجهة برمجة تطبيقات NuRaft لتغيير العضوية ديناميكيًا. ويوفّر NuRaft طريقة لإضافة خادم واحد أو إزالة خادم واحد في كل مرة. وهذا يعني أن كل تغيير في التهيئة (كل جزء من
joining، وكل جزء منleaving) يجب البتّ فيه على حدة. لذلك لا تتوفر إعادة تهيئة مجمّعة، لأن ذلك قد يكون مضللًا للمستخدمين النهائيين.كما أن تغيير نوع الخادم (participant/learner) غير ممكن لأنه غير مدعوم من NuRaft، والطريقة الوحيدة لذلك هي إزالة الخادم ثم إضافته من جديد، وهو ما سيكون مضللًا أيضًا.
-
لا يمكنك استخدام القيمة المُعادة
znodestat. -
لا يُستخدم الحقل
from_version. وتُرفض جميع الطلبات التي تم تعيينfrom_versionفيها. ويرجع ذلك إلى أن/keeper/configعقدة افتراضية، ما يعني أنها لا تُخزَّن في التخزين الدائم، بل تُولَّد آنيًا باستخدام تهيئة العقدة المحددة لكل طلب. وقد اتُّخذ هذا القرار لتجنّب تكرار البيانات لأن NuRaft يخزّن هذه التهيئة بالفعل. -
بخلاف ZooKeeper، لا توجد طريقة لانتظار إعادة تهيئة العنقود عبر إرسال أمر
sync. سيُطبَّق الضبط الجديد في نهاية المطاف ولكن من دون أي ضمانات زمنية. -
قد يفشل الأمر
reconfigلأسباب مختلفة. يمكنك التحقق من حالة العنقود ومعرفة ما إذا كان التحديث قد طُبِّق.
تحويل Keeper أحادي العقدة إلى عنقود
أحيانًا تكون هناك حاجة إلى توسيع عقدة Keeper تجريبية لتصبح عنقودًا. فيما يلي مخطط يوضح كيفية القيام بذلك خطوة بخطوة لعنقود من 3 عقد:
- مهم: يجب إضافة العقد الجديدة على دفعات أصغر من النصاب الحالي، وإلا فستنتخب قائدًا من بينها. في هذا المثال، تُضاف العقد واحدة تلو الأخرى.
- يجب أن تكون قيمة parameter الإعداد
keeper_server.enable_reconfigurationمفعّلة على عقدة Keeper الحالية. - ابدأ عقدة ثانية باستخدام الإعداد الكامل الجديد لعنقود Keeper.
- بعد تشغيلها، أضِفها إلى العقدة 1 باستخدام
reconfig. - الآن، ابدأ عقدة ثالثة وأضِفها باستخدام
reconfig. - حدِّث إعداد
clickhouse-serverبإضافة عقدة Keeper الجديدة إليه، ثم أعد تشغيله لتطبيق التغييرات. - حدِّث إعداد raft للعقدة 1، وأعد تشغيلها اختياريًا.
ولفهم العملية عمليًا بشكل أفضل، إليك sandbox repository.
الميزات غير المدعومة
مع أن ClickHouse Keeper يهدف إلى تحقيق توافق كامل مع ZooKeeper، فلا تزال هناك بعض الميزات غير المُنفَّذة حتى الآن (مع استمرار العمل على تطويرها):
createلا يدعم إرجاع الكائنStatcreateلا يدعم TTLaddWatchلا يعمل مع watches من النوعPERSISTENTremoveWatchوremoveAllWatchesغير مدعومينsetWatchesغير مدعوم- لا يدعم إنشاء znodes من النوع
CONTAINER SASL authenticationغير مدعوم