Skip to content

Commit 94b8d3e

Browse files
committed
add cluster->setSoftCheck()
1 parent 1c3b9c0 commit 94b8d3e

File tree

2 files changed

+214
-15
lines changed

2 files changed

+214
-15
lines changed

doc/02_article_cluster.md

Lines changed: 194 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,66 @@
1+
# Подключение к кластеру ClickHouse из PHP
2+
3+
* Что такое кластер ?
4+
* Что такое реплики ?
5+
*
6+
7+
8+
(http://uk0.us/2011/01/simple-raw-sql-migrations-for-kohana-3/)
9+
10+
### Вступление. Немного о масштабировании Clickhouse
11+
12+
13+
Сдесь будет очень коротко что такое кластер и репликация+шардирование.
14+
Нет смысла переписывать документацию.
15+
16+
17+
имеется база данных, в которую осуществляется запись и чтение данных.
18+
В динамично растущих системах, объемы данных, как правило, быстро
19+
увеличиваются и рано или поздно можно столкнуться с проблемой,
20+
когда текущих ресурсов машины будет не хватать для нормальной работы.
21+
22+
Для решения этой проблемы применяют масштабирование.
23+
Масштабирование бывает 2-х видов — горизонтальное и вертикальное.
24+
25+
Вертикальное масштабирование — наращивание мощностей одной машины — добавление CPU, RAM, HDD.
26+
Горизонтальное масштабирование — добавление новых машин к существующим и распределение данных между ними.
27+
28+
29+
Второй случай более сложен в конфигурации, но имеет ряд преимуществ:
30+
Теоретически бесконечное масштабирование (машин можно поставить сколько угодно)
31+
Бо́льшая безопасность данных (только при использовании репликации) — машины могут располагаться в разных дата центрах (при падении одной из них, останутся другие)
32+
33+
34+
35+
36+
37+
38+
Для подключения к кластеру используем отдельный класс
39+
40+
41+
# Отправка запросов в кластер, реализация миграций на PHP
42+
43+
44+
45+
46+
47+
48+
49+
### Примеры миграций
50+
51+
Мы используем (mybatis):[http://www.mybatis.org/migrations/]
52+
53+
54+
55+
https://habrahabr.ru/post/315254/
56+
57+
58+
Почему миграции это круто ?
59+
Допустим у вас таблица из 50 колонок , а елси их 200 или 500 ?
60+
Вы ведете отдельную документацию по каждой колонке?
61+
Вы помните когда каждую колонку добавил ?
62+
63+
164

265

366
#### Результат запроса, напрямую в файл
@@ -49,10 +112,32 @@ $curl_opt[CURLOPT_FILE]=$this->resultFileHandle;
49112
stream_filter_append($this->resultFileHandle, 'zlib.deflate', STREAM_FILTER_WRITE, $params);
50113
```
51114

52-
### Кластер
115+
### Некоторые примеры развертки Clickhouse
116+
117+
https://clickhouse.yandex/reference_ru.html#Distributed
118+
Движок Distributed - не хранит данные самостоятельно, а позволяет обрабатывать запросы распределённо, на нескольких серверах.
119+
Чтение автоматически распараллеливается.
120+
121+
122+
https://clickhouse.yandex/reference_ru.html#Репликация данных
123+
124+
Репликация данных - Движок Replicated*
125+
Репликация никак не связана с шардированием. На каждом шарде репликация работает независимо.
126+
Репликация является опциональной возможностью. Для использования репликации, укажите в конфигурационном файле адреса ZooKeeper кластера.
127+
128+
53129

54130
Допустим есть серверный конфиг в ansible который создает кластеры:
55-
```
131+
Не стоит использовать в продакшене кластер: sharovara - это для теста и пример сделан в этом кластере нет репликации, т/е если вылетает одна из нод
132+
вытеряете 1/4 данных.
133+
134+
pulse - это две копии на две шарды
135+
sharovara - это 4е шары
136+
repikator - 4е реплики - максимальная надежность для параноии.
137+
138+
139+
140+
```xml
56141
ansible.cluster1.yml
57142
- name: "pulse"
58143
shards:
@@ -67,18 +152,85 @@ $curl_opt[CURLOPT_FILE]=$this->resultFileHandle;
67152
- name: "repikator"
68153
shards:
69154
- { name: "01", replicas: ["clickhouse63.smi2", "clickhouse64.smi2","clickhouse65.smi2", "clickhouse66.smi2"]}
70-
- name: "sharovara3x"
71-
shards:
72-
- { name: "01", replicas: ["clickhouse64.smi2"]}
73-
- { name: "02", replicas: ["clickhouse65.smi2"]}
74-
- { name: "03", replicas: ["clickhouse66.smi2"]}
75-
- name: "repikator3x"
76-
shards:
77-
- { name: "01", replicas: ["clickhouse64.smi2","clickhouse65.smi2", "clickhouse66.smi2"]}
155+
78156
```
79157

80-
Создаем класс для работы с кластером:
158+
159+
(Засунуть в споллер)
160+
Или конфигрурация в XML :
161+
162+
```xml
163+
164+
<remote_servers>
165+
<repikator>
166+
167+
<shard>
168+
<replica>
169+
<host>clickhouse63.smi2</host>
170+
</replica>
171+
<replica>
172+
<host>clickhouse64.smi2</host>
173+
</replica>
174+
<replica>
175+
<host>clickhouse65.smi2</host>
176+
</replica>
177+
<replica>
178+
<host>clickhouse66.smi2</host>
179+
</replica>
180+
</shard>
181+
</repikator>
182+
<pulse>
183+
<!-- 01 -->
184+
<shard>
185+
<replica>
186+
<host>clickhouse63.smi2</host>
187+
</replica>
188+
<replica>
189+
<host>clickhouse64.smi2</host>
190+
</replica>
191+
</shard>
192+
<!-- 02 -->
193+
<shard>
194+
<replica>
195+
<host>clickhouse65.smi2</host>
196+
</replica>
197+
<replica>
198+
<host>clickhouse66.smi2</host>
199+
</replica>
200+
</shard>
201+
</pulse>
202+
<sharovara>
203+
<!-- 01 -->
204+
<shard>
205+
<replica>
206+
<host>clickhouse63.smi2</host>
207+
</replica>
208+
</shard>
209+
<!-- 02 -->
210+
<shard>
211+
<replica>
212+
<host>clickhouse64.smi2</host>
213+
</replica>
214+
</shard>
215+
<!-- 03 -->
216+
<shard>
217+
<replica>
218+
<host>clickhouse65.smi2</host>
219+
</replica>
220+
</shard>
221+
<!-- 04 -->
222+
<shard>
223+
<replica>
224+
<host>clickhouse66.smi2</host>
225+
</replica>
226+
</shard>
227+
</sharovara>
228+
81229
```
230+
231+
Создаем класс для работы с кластером:
232+
233+
```php
82234
$cl = new ClickHouseDB\Cluster(
83235
['host'=>'allclickhouse.smi2','port'=>'8123','username'=>'x','password'=>'x']
84236
);
@@ -89,18 +241,25 @@ $cl = new ClickHouseDB\Cluster(
89241

90242

91243
Установим время за которое можно подключиться ко всем нодам:
92-
```
244+
```php
93245
$cl->setScanTimeOut(2.5); // 2500 ms
94246
```
95247
Проверяем что состояние рабочее, в данный момент происходит асинхронное подключение ко всем серверам
96-
```
248+
```php
97249
if (!$cl->isReplicasIsOk())
98250
{
99251
throw new Exception('Replica state is bad , error='.$cl->getError());
100252
}
101253
```
102254

255+
Если не запрашивать последние 4 столбца (log_max_index, log_pointer, total_replicas, active_replicas), то таблица работает быстро.
256+
257+
258+
259+
260+
103261
Как работает проверка:
262+
(https://clickhouse.yandex/reference_ru.html#system.replicas)
104263
* Установленно соединение со всеми сервера перечисленным в DNS записи
105264
* Проверка таблицы system.replicas что всё хорошо
106265
* not is_readonly
@@ -114,8 +273,23 @@ if (!$cl->isReplicasIsOk())
114273
* active_replicas < total_replicas
115274

116275

276+
future_parts: количество кусков с данными, которые появятся в результате INSERT-ов или слияний, которых ещё предстоит сделать
277+
parts_to_check: количество кусков с данными в очереди на проверку Кусок помещается в очередь на проверку, если есть подозрение, что он может быть битым.
278+
log_max_index: максимальный номер записи в общем логе действий
279+
log_pointer: максимальный номер записи из общего лога действий, которую реплика скопировала в свою очередь для выполнения, плюс единица
280+
Если log_pointer сильно меньше log_max_index, значит что-то не так.
281+
total_replicas: общее число известных реплик этой таблицы
282+
active_replicas: число реплик этой таблицы, имеющих сессию в ZK; то есть, число работающих реплик
283+
Если запрашивать все столбцы, то таблица может работать слегка медленно, так как на каждую строчку делается несколько чтений из ZK.
284+
Если не запрашивать последние 4 столбца (log_max_index, log_pointer, total_replicas, active_replicas), то таблица работает быстро.
285+
286+
287+
288+
289+
290+
117291
Получаем список всех cluster
118-
```
292+
```php
119293
print_r($cl->getClusterList());
120294
// result
121295
// [0] => pulse
@@ -128,7 +302,7 @@ print_r($cl->getClusterList());
128302

129303
Узнаем список node(ip) и кол-во shard,replica
130304

131-
```
305+
```php
132306
foreach (['pulse','repikator','sharovara','repikator3x','sharovara3x'] as $name)
133307
{
134308
print_r($cl->getClusterNodes($name));
@@ -229,3 +403,8 @@ print_r($statement->rowsAsTree('event_date.site_key'));
229403

230404
```
231405

406+
407+
408+
# Выгружайте сырые данные из Метрики через Logs API
409+
410+

src/Cluster.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,13 @@ class Cluster
5858
*/
5959
private $isScaned = false;
6060

61+
62+
/**
63+
*
64+
* @var bool
65+
*/
66+
private $softCheck = false;
67+
6168
/**
6269
* @var bool
6370
*/
@@ -84,6 +91,14 @@ private function defaultClient()
8491
return $this->defaultClient;
8592
}
8693

94+
/**
95+
* @param $softCheck
96+
*/
97+
public function setSoftCheck($softCheck)
98+
{
99+
$this->softCheck = $softCheck;
100+
}
101+
87102
/**
88103
* @param $scanTimeOut
89104
*/
@@ -207,6 +222,11 @@ public function rescan()
207222

208223
foreach ($this->nodes as $node) {
209224
$this->defaultClient()->setHost($node);
225+
226+
// @todo: Если запрашивать все столбцы, то таблица может работать слегка медленно, так как на каждую строчку делается несколько чтений из ZK.
227+
// @todo: Если не запрашивать последние 4 столбца (log_max_index, log_pointer, total_replicas, active_replicas), то таблица работает быстро.
228+
229+
210230
$statementsReplicas[$node] = $this->defaultClient()->selectAsync('SELECT * FROM system.replicas');
211231
$statementsClusters[$node] = $this->defaultClient()->selectAsync('SELECT * FROM system.clusters');
212232
// пересетапим timeout

0 commit comments

Comments
 (0)