
ClickHouse Disaster Recovery (DR) yapısı, doğrudan net bir Disaster çözümü yoktur, fakat DR oluşturmak isteniyorsa burada farklı alternatifler kullanılabilir biz burada ilk olarak CLickHouse Keeper üzerinende farklı side da iki farklı clustera table bazlı replikasyon ile bir Disaster çözümü öneriyor olacağız.

Yukarıda Hem production tarafındaki makineler hemde Disaster tarafındaki makineler Active Keeper a yönlendirilmelidir. Unutulmamalıdırki buradaki tüm clusterlar read-write durumdadır, dolayısıyla write işlemleri yanlızca Production tarafında yapılmalıdır, Disaster tarafına eğer ihtiyaç olursa read işlemleri için kullanılabilir.
Observer keeper lar standby modunda çalıştırılır ve o-herhangi bir oylamaya katılmazlar , yani yukarıdaki şekilde 6 adet keeper vardır ancak 3 adet aktif zookeper var olarak oylama yapılacaktır. Sorun anında observer keeperlar devreye alınır, Ve DR side aktif edilerek yola devam edilir
Production Cluster İçin Konfigurasyon
Aşağıdaki İlk Cluster Prodcution (İstanbul) Makinleri
<clickhouse>
<remote_servers>
<mycluster>
<shard>
<internal_replication>true</internal_replication>
<replica><host>pirise01</host><port>9000</port></replica>
<replica><host>pirise02</host><port>9000</port></replica>
</shard>
<shard>
<internal_replication>true</internal_replication>
<replica><host>pirise03</host><port>9000</port></replica>
<replica><host>pirise04</host><port>9000</port></replica>
</shard>
</mycluster>
</remote_servers>
</clickhouse>
Disaster Tarafındaki Makinlerimiz (Ankara) CLuster Konfigurasyonu;
<clickhouse>
<remote_servers>
<drcluster>
<shard>
<internal_replication>true</internal_replication>
<replica><host>tirise01</host><port>9000</port></replica>
<replica><host>tirise02</host><port>9000</port></replica>
</shard>
<shard>
<internal_replication>true</internal_replication>
<replica><host>tirise03</host><port>9000</port></replica>
<replica><host>tirise04</host><port>9000</port></replica>
</shard>
</drcluster>
</remote_servers>
</clickhouse>
Ayrı Ayrı Clusterlar yapılması , distrbuted işlemlerde tek bir site üzerinde işlem yapmayı sağlar buda side lar arası mesafeden kaynaklı gecikmeyi önceleyecektir.
Ancak DDL işlemlerinde her iki side dada tanımlama yapmamak için tek bir side da tanımlama yaparak her iki clsuterda objelerin oluşmasını sağlamak all adında bir cluster tanımı yapılır. Peki ON CLUSTER
…. diyerek cluster belirtiyorduk Tüm Cluster larda objelerin oluşturulmasını sağlayabilmek için ON CLUSTER ALL
ifadesi kullanılır. NOT: birbirinden bağımsız iki farklı cluster tek cluster gibi komut göndermek için versiyonlarının aynı olması gerekmektedir aksi halde (Code: 371. DB::Exception: There are two exactly the same ClickHouse instances tirise01:9000 in cluster all. (INCONSISTENT_CLUSTER_DEFINITION))
hatası alınır.
<clickhouse>
<remote_servers>
<all>
<shard>
<internal_replication>true</internal_replication>
<replica><host>pirise01</host><port>9000</port></replica>
<replica><host>pirise02</host><port>9000</port></replica>
</shard>
<shard>
<internal_replication>true</internal_replication>
<replica><host>pirise03</host><port>9000</port></replica>
<replica><host>pirise04</host><port>9000</port></replica>
</shard>
<shard>
<internal_replication>true</internal_replication>
<replica><host>tirise01</host><port>9000</port></replica>
<replica><host>tirise02</host><port>9000</port></replica>
</shard>
<shard>
<internal_replication>true</internal_replication>
<replica><host>tirise03</host><port>9000</port></replica>
<replica><host>tirise04</host><port>9000</port></replica>
</shard>
</all>
</remote_servers>
</clickhouse>
Kontrollerini yapalım; Burada replikasyonlar için macros.xml kponfigürasyonun doğru yapıldığını düşünerek devamediyoruz.
Prod (İstanbul) için;
clickhouse :) show clusters
SHOW CLUSTERS
Query id: abef32d0-d5bf-4cd9-8f71-6a8630fac350
┌─cluster───┐
│ all │
│ mycluster │
└───────────┘
DR Ankara için;
tirise03 :) show clusters
SHOW CLUSTERS
Query id: a4720f1e-694e-4579-bc58-453d2b5bd4c2
┌─cluster───┐
│ all │
│ drcluster │
└───────────┘
clickhouse :) select cluster,shard_num,replica_num,host_name from system.clusters;
SELECT
cluster,
shard_num,
replica_num,
host_name
FROM system.clusters
Query id: ecaaef67-cd45-4f3e-b1a7-566169e8338f
┌─cluster───┬─shard_num─┬─replica_num─┬─host_name─┐
│ all │ 1 │ 1 │ pirise01 │
│ all │ 1 │ 2 │ pirise02 │
│ all │ 2 │ 1 │ pirise03 │
│ all │ 2 │ 2 │ pirise04 │
│ all │ 3 │ 1 │ tirise01 │
│ all │ 3 │ 2 │ tirise02 │
│ all │ 4 │ 1 │ tirise03 │
│ all │ 4 │ 2 │ tirise04 │
│ mycluster │ 1 │ 1 │ pirise01 │
│ mycluster │ 1 │ 2 │ pirise02 │
│ mycluster │ 2 │ 1 │ pirise03 │
│ mycluster │ 2 │ 2 │ pirise04 │
└───────────┴───────────┴─────────────┴───────────┘
12 rows in set. Elapsed: 0.001 sec.
Herhangi bir node da bir database yaratalım cluster all yapalım;
clickhouse :) create database testall on cluster all;
CREATE DATABASE testall ON CLUSTER `all`
Query id: 4e77d062-0a6b-4dcc-a9a4-9d87b4f885b0
┌─host─────┬─port─┬─status─┬─error─┬─num_hosts_remaining─┬─num_hosts_active─┐
│ pirise03 │ 9000 │ 0 │ │ 7 │ 0 │
│ tirise02 │ 9000 │ 0 │ │ 6 │ 0 │
│ pirise04 │ 9000 │ 0 │ │ 5 │ 0 │
│ pirise01 │ 9000 │ 0 │ │ 4 │ 0 │
│ tirise03 │ 9000 │ 0 │ │ 3 │ 0 │
│ pirise02 │ 9000 │ 0 │ │ 2 │ 0 │
│ tirise04 │ 9000 │ 0 │ │ 1 │ 0 │
│ tirise01 │ 9000 │ 0 │ │ 0 │ 0 │
└──────────┴──────┴────────┴───────┴─────────────────────┴──────────────────┘
8 rows in set. Elapsed: 0.126 sec.
Görüldüğü üzere tüm clusterlar için bu database oluşturulmuş oldu.
Şimdi örnek bir tablo oluşturalım ve kontrollerini sağlayalım;
CREATE TABLE IF NOT EXISTS testall.drtbltest ON CLUSTER `all`
(
`id` UInt32,
`name` String
)
ENGINE = ReplicatedMergeTree('/clickhouse/{cluster}/tables/{shard}/{database}/events_local', '{replica}')
ORDER BY id
Query id: 7e083c88-90e2-47ec-a8d3-db3157afe972
┌─host─────┬─port─┬─status─┬─error─┬─num_hosts_remaining─┬─num_hosts_active─┐
│ pirise03 │ 9000 │ 0 │ │ 7 │ 2 │
│ pirise04 │ 9000 │ 0 │ │ 6 │ 2 │
│ tirise04 │ 9000 │ 0 │ │ 5 │ 2 │
│ tirise01 │ 9000 │ 0 │ │ 4 │ 2 │
│ pirise02 │ 9000 │ 0 │ │ 3 │ 2 │
│ tirise02 │ 9000 │ 0 │ │ 2 │ 2 │
└──────────┴──────┴────────┴───────┴─────────────────────┴──────────────────┘
┌─host─────┬─port─┬─status─┬─error─┬─num_hosts_remaining─┬─num_hosts_active─┐
│ pirise01 │ 9000 │ 0 │ │ 1 │ 0 │
│ tirise03 │ 9000 │ 0 │ │ 0 │ 0 │
└──────────┴──────┴────────┴───────┴─────────────────────┴──────────────────┘
8 rows in set. Elapsed: 0.188 sec.
içerisine biraz kayıt insert edelim;
create table if not exists reptest on cluster all
(
id UInt32,
name String
)
ENGINE = ReplicatedMergeTree ('/clickhouse/all/tables/{shard}/{database}/reptest', '{replica}')
ORDER BY id
İçerisne kayıt ekleyip shard ve nodelara göre replikasyonları kontrol edelim;
--prod 1. nodedan
insert into reptest values (1,'p1,shard1');
prod 2. nodeddan
insert into reptest values (2,'p2,shard1');
prod 3. nodeddan
insert into reptest values (3,'p3,shard2');
prod 4. noddan
insert into reptest values (4,'p4,shard2');
Sorgu sonuçlarına bakıp kontrol edelim;
--Prod ve DR ın 1. ve 2. nod lar için;
select * from reptest;
┌─id─┬─name──────┐
│ 2 │ p2,shard1 │
└────┴───────────┘
┌─id─┬─name──────┐
│ 1 │ p1,shard1 │
└────┴───────────┘
-Prod ve DR ın 3. ve 4. Node lar için
select * from reptest;
┌─id─┬─name──────┐
│ 4 │ p4,shard2 │
└────┴───────────┘
┌─id─┬─name──────┐
│ 3 │ p3,shard2 │
└────┴───────────┘
Replikasyon kısmı yukarıda anlatıldığı gibi uygulanır , bu sayede data yedekliliği sağlanır ancak burada Prodcution Side (İstanbbul) herhangi bir sebep ile kesilidği zaman keeper yedekliliği yoksa bu bir işe yaramayacaktır, bunu sağlamak için adımlarımız nedir? Bu konuya bakıyor olacağız.
Bizim durumumuzda keeper ,le clickhose serverlar aynı makine üzerinde çalışmakta, aşağıda clickhousekeeper konfigürasyon dosyları verilmiştir.
enable-keeper.xml
Burada aynı file sadece server_id ilgili serverı tarif edecek şekilde tüm keeper çalışacak sunucularında konfigüre edilir.
<clickhouse>
<keeper_server>
<tcp_port>9181</tcp_port>
<server_id>1</server_id>
<log_storage_path>/var/lib/clickhouse-keeper/coordination/log</log_storage_path>
<snapshot_storage_path>/var/lib/clickhouse-keeper/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>
<rotate_log_storage_interval>10000</rotate_log_storage_interval>
</coordination_settings>
<raft_configuration>
<server>
<id>1</id>
<hostname>pirise01</hostname>
<port>9234</port>
</server>
<server>
<id>2</id>
<hostname>pirise02</hostname>
<port>9234</port>
</server>
<server>
<id>3</id>
<hostname>pirise03</hostname>
<port>9234</port>
</server>
<server>
<id>4</id>
<hostname>tirise01</hostname>
<port>9234</port>
<can_become_leader>false</can_become_leader>
</server>
<server>
<id>5</id>
<hostname>tirise02</hostname>
<port>9234</port>
<can_become_leader>false</can_become_leader>
</server>
<server>
<id>6</id>
<hostname>tirise03</hostname>
<port>9234</port>
<can_become_leader>false</can_become_leader>
</server>
</raft_configuration>
</keeper_server>
</clickhouse>
keeper olsun olmasın tüm node lar için use-keeper.xml
ise aşağıdaki gibi ayarlanır;
<clickhouse>
<zookeeper>
<node index="1">
<host>pirise01</host>
<port>9181</port>
</node>
<node index="2">
<host>pirise02</host>
<port>9181</port>
</node>
<node index="3">
<host>pirise03</host>
<port>9181</port>
</node>
<node index="4">
<host>tirise01</host>
<port>9181</port>
</node>
<node index="5">
<host>tirise02</host>
<port>9181</port>
</node>
<node index="6">
<host>tirise03</host>
<port>9181</port>
</node>
</zookeeper>
</clickhouse>
Herhangi bir disaster durumunda DR side makinlerindeki <can_become_leader>false</can_become_leader>
flag kaldırılır, ayrıca Production side kısmı xml lerden kaldırılarak DR side yeni production olarak yeniden başlatılır.
Bir yanıt yazın