forked from ClickHouse/ClickHouse
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathreference_ru.html
7789 lines (5234 loc) · 653 KB
/
reference_ru.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="utf-8"/>
<title>ClickHouse — руководство</title>
<link rel="shortcut icon" href="favicon.ico"/>
<link rel="stylesheet" href="reference.css"/>
<meta name="description" content="ClickHouse — open-source distributed column-oriented DBMS"/>
<meta name="keywords" content="ClickHouse, DBMS, OLAP, relational, analytics, analytical, big data, open-source, SQL, web-analytics"/>
</head>
<body>
<script type="text/javascript">
function getParams() {
var matches = document.cookie.match(/yandex_login=([\w\-]+)/);
return (matches && matches.length == 2) ? { "login": matches[1] } : {};
}
</script>
<!-- Yandex.Metrika counter -->
<script src="https://mc.yandex.ru/metrika/watch.js" type="text/javascript"></script>
<script type="text/javascript">
try { var yaCounter18343495 = new Ya.Metrika({id:18343495,
webvisor:true,
clickmap:true,
trackLinks:true,
accurateTrackBounce:true,
trackHash:true,
params: getParams()});
} catch(e) { }
</script>
<noscript><div><img src="https://mc.yandex.ru/watch/18343495" style="position:absolute; left:-9999px;" alt="" /></div></noscript>
<!-- /Yandex.Metrika counter -->
<script type="text/javascript" src="https://yandex.st/jquery/1.7.2/jquery.min.js"></script>
<div class="island">
<div style="float: left; margin-right: -100%; margin-top: 3px; margin-left: 3px;">
<a href="/">
<svg xmlns="http://www.w3.org/2000/svg" width="90" height="80" viewBox="0 0 9 8">
<style>
.o{fill:#fc0}
.r{fill:#f00}
</style>
<path class="r" d="M0,7 h1 v1 h-1 z"/>
<path class="o" d="M0,0 h1 v7 h-1 z"/>
<path class="o" d="M2,0 h1 v8 h-1 z"/>
<path class="o" d="M4,0 h1 v8 h-1 z"/>
<path class="o" d="M6,0 h1 v8 h-1 z"/>
<path class="o" d="M8,3.25 h1 v1.5 h-1 z"/>
</svg>
</a>
</div>
<div style="float: right; margin-left: -100%; margin-top: 3px; margin-right: 3px;">
<div style="display: inline-block; width: 50px; text-align: center; margin-right: 2px;">
<a href="reference_ru.html" title="In russian">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 10 6" width="50" height="30" style="border: 1px solid #AAA;">
<rect fill="#fff" width="10" height="3"/>
<rect fill="#d52b1e" y="3" width="10" height="3"/>
<rect fill="#0039a6" y="2" width="10" height="2"/>
</svg>
Russian
</a>
</div>
<div style="display: inline-block; width: 50px; text-align: center; margin-left: 2px;">
<a href="reference_en.html" title="In english">
<svg xmlns="http://www.w3.org/2000/svg" width="50" height="30" viewBox="0,0 25,15" style="border: 1px solid #AAA;">
<rect width="25" height="15" fill="#00247d"/>
<path d="M 0,0 L 25,15 M 25,0 L 0,15" stroke="#fff" stroke-width="3"/>
<path d="M 12.5,0 V 15 M 0,7.5 H 25" stroke="#fff" stroke-width="5"/>
<path d="M 12.5,0 V 15 M 0,7.5 H 25" stroke="#cf142b" stroke-width="3"/>
</svg>
English
</a>
</div>
</div>
<h1 class="title not-for-contents"><a class="title_link" href="/">ClickHouse</a></h1>
<h2 class="subtitle not-for-contents">Руководство</h2>
<div class="signature"> — Алексей Миловидов</div>
</div>
<div class="island">
<h1>Содержание</h1>
<br />
<div id="contents"></div>
</div>
<div class="island">
<h1>Введение</h1>
</div>
<div class="island content">
==Что такое ClickHouse==
ClickHouse - столбцовая СУБД для OLAP (Columnar DBMS).
В обычной, "строковой" СУБД, данные хранятся в таком порядке:
<pre class="text-example" style="white-space: pre; overflow-x: scroll">
5123456789123456789 1 Евробаскет - Греция - Босния и Герцеговина - example.com 1 2011-09-01 01:03:02 6274717 1294101174 11409 612345678912345678 0 33 6 http://www.example.com/basketball/team/123/match/456789.html http://www.example.com/basketball/team/123/match/987654.html 0 1366 768 32 10 3183 0 0 13 0\0 1 1 0 0 2011142 -1 0 0 01321 613 660 2011-09-01 08:01:17 0 0 0 0 utf-8 1466 0 0 0 5678901234567890123 277789954 0 0 0 0 0
5234985259563631958 0 Консалтинг, налогообложение, бухгалтерский учет, право 1 2011-09-01 01:03:02 6320881 2111222333 213 6458937489576391093 0 3 2 http://www.example.ru/ 0 800 600 16 10 2 153.1 0 0 10 63 1 1 0 0 2111678 000 0 588 368 240 2011-09-01 01:03:17 4 0 60310 0 windows-1251 1466 0 000 778899001 0 0 0 0 0
...
</pre>
То есть, значения, относящиеся к одной строке, хранятся рядом.
Примеры строковых СУБД: MySQL, Postgres, MS SQL Server и т. п.
В столбцовых СУБД, данные хранятся в таком порядке:
<pre class="text-example" style="white-space: pre; overflow-x: scroll">
<b>WatchID:</b> 5385521489354350662 5385521490329509958 5385521489953706054 5385521490476781638 5385521490583269446 5385521490218868806 5385521491437850694 5385521491090174022 5385521490792669254 5385521490420695110 5385521491532181574 5385521491559694406 5385521491459625030 5385521492275175494 5385521492781318214 5385521492710027334 5385521492955615302 5385521493708759110 5385521494506434630 5385521493104611398
<b>JavaEnable:</b> 1 0 1 0 0 0 1 0 1 1 1 1 1 1 0 1 0 0 1 1
<b>Title:</b> Yandex Announcements - Investor Relations - Yandex Yandex — Contact us — Moscow Yandex — Mission Ru Yandex — History — History of Yandex Yandex Financial Releases - Investor Relations - Yandex Yandex — Locations Yandex Board of Directors - Corporate Governance - Yandex Yandex — Technologies
<b>GoodEvent:</b> 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
<b>EventTime:</b> 2016-05-18 05:19:20 2016-05-18 08:10:20 2016-05-18 07:38:00 2016-05-18 01:13:08 2016-05-18 00:04:06 2016-05-18 04:21:30 2016-05-18 00:34:16 2016-05-18 07:35:49 2016-05-18 11:41:59 2016-05-18 01:13:32
...
</pre>
В примерах изображён только порядок расположения данных.
То есть, значения из разных столбцов хранятся отдельно, а данные одного столбца - вместе.
Примеры столбцовых СУБД: Vertica, Paraccel (Actian Matrix) (Amazon Redshift), Sybase IQ, Exasol, Infobright, InfiniDB, MonetDB (VectorWise) (Actian Vector), LucidDB, SAP HANA, Google Dremel, Google PowerDrill, Druid, kdb+ и т. п.
Разный порядок хранения данных лучше подходит для разных сценариев работы.
Сценарий работы с данными - это то, какие производятся запросы, как часто и в каком соотношении; сколько читается данных на запросы каждого вида - строк, столбцов, байт; как соотносятся чтения и обновления данных; какой рабочий размер данных и насколько локально он используется; используются ли транзакции и с какой изолированностью; какие требования к дублированию данных и логической целостности; требования к задержкам на выполнение и пропускной способности запросов каждого вида и т. п.
Чем больше нагрузка на систему, тем более важной становится специализация под сценарий работы, и тем более конкретной становится эта специализация. Не существует системы, одинаково хорошо подходящей под существенно различные сценарии работы. Если система подходит под широкое множество сценариев работы, то при достаточно большой нагрузке, система будет справляться со всеми сценариями работы плохо, или справляться хорошо только с одним из сценариев работы.
Будем говорить, что OLAP (онлайн обработка аналитических запросов) сценарий работы - это:
- подавляющее большинство запросов - на чтение;
- данные обновляются достаточно большими пачками (> 1000 строк), а не по одной строке, или не обновляются вообще;
- данные добавляются в БД, но не изменяются;
- при чтении, вынимается достаточно большое количество строк из БД, но только небольшое подмножество столбцов;
- таблицы являются "широкими", то есть, содержат большое количество столбцов;
- запросы идут сравнительно редко (обычно не более сотни в секунду на сервер);
- при выполнении простых запросов, допустимы задержки в районе 50 мс;
- значения в столбцах достаточно мелкие - числа и небольшие строки (пример - 60 байт на URL);
- требуется высокая пропускная способность при обработке одного запроса (до миллиардов строк в секунду на один сервер);
- транзакции отсутствуют;
- низкие требования к консистентности данных;
- в запросе одна большая таблица, все таблицы кроме одной маленькие;
- результат выполнения запроса существенно меньше исходных данных - то есть, данные фильтруются или агрегируются; результат выполнения помещается в оперативку на одном сервере;
Легко видеть, что OLAP сценарий работы существенно отличается от других распространённых сценариев работы (например, OLTP или Key-Value сценариев работы). Таким образом, не имеет никакого смысла пытаться использовать OLTP или Key-Value БД для обработки аналитических запросов, если вы хотите получить приличную производительность ("выше плинтуса"). Например, если вы попытаетесь использовать для аналитики MongoDB или Elliptics - вы получите анекдотически низкую производительность по сравнению с OLAP-СУБД.
Столбцовые СУБД лучше (от 100 раз по скорости обработки большинства запросов) подходят для OLAP сценария работы по следующим причинам:
1. По I/O.
1.1. Для выполнения аналитического запроса, требуется прочитать небольшое количество столбцов таблицы. В столбцовой БД для этого можно читать только нужные данные. Например, если вам требуется только 5 столбцов из 100, то следует рассчитывать на 20-кратное уменьшение ввода-вывода.
1.2. Так как данные читаются пачками, то их проще сжимать. Данные, лежащие по столбцам также лучше сжимаются. За счёт этого, дополнительно уменьшается объём ввода-вывода.
1.3. За счёт уменьшения ввода-вывода, больше данных влезает в системный кэш.
Для примера, для запроса "посчитать количество записей для каждой рекламной системы", требуется прочитать один столбец "идентификатор рекламной системы", который занимает 1 байт в несжатом виде. Если большинство переходов было не с рекламных систем, то можно рассчитывать хотя бы на десятикратное сжатие этого столбца. При использовании быстрого алгоритма сжатия, возможно разжатие данных со скоростью более нескольких гигабайт несжатых данных в секунду. То есть, такой запрос может выполняться со скоростью около нескольких миллиардов строк в секунду на одном сервере. На практике, такая скорость действительно достигается.
<pre class="terminal show-example">
milovidov@████████.yandex.ru:~$ clickhouse-client
ClickHouse client version 0.0.52053.
Connecting to localhost:9000.
Connected to ClickHouse server version 0.0.52053.
:) SELECT CounterID, count() FROM hits GROUP BY CounterID ORDER BY count() DESC LIMIT 20
SELECT
CounterID,
count()
FROM hits
GROUP BY CounterID
ORDER BY count() DESC
LIMIT 20
┌─CounterID─┬──count()─┐
│ 114208 │ 56057344 │
│ 115080 │ 51619590 │
│ 3228 │ 44658301 │
│ 38230 │ 42045932 │
│ 145263 │ 42042158 │
│ 91244 │ 38297270 │
│ 154139 │ 26647572 │
│ 150748 │ 24112755 │
│ 242232 │ 21302571 │
│ 338158 │ 13507087 │
│ 62180 │ 12229491 │
│ 82264 │ 12187441 │
│ 232261 │ 12148031 │
│ 146272 │ 11438516 │
│ 168777 │ 11403636 │
│ 4120072 │ 11227824 │
│ 10938808 │ 10519739 │
│ 74088 │ 9047015 │
│ 115079 │ 8837972 │
│ 337234 │ 8205961 │
└───────────┴──────────┘
20 rows in set. Elapsed: 0.153 sec. Processed 1.00 billion rows, 4.00 GB (6.53 billion rows/s., 26.10 GB/s.)
:)
</pre>
2. По CPU.
Так как для выполнения запроса надо обработать достаточно большое количество строк, становится актуальным диспетчеризовывать все операции не для отдельных строк, а для целых векторов, или реализовать движок выполнения запроса так, чтобы издержки на диспетчеризацию были примерно нулевыми. Если этого не делать, то при любой не слишком плохой дисковой подсистеме, интерпретатор запроса неизбежно упрётся в CPU.
Имеет смысл не только хранить данные по столбцам, но и обрабатывать их, по возможности, тоже по столбцам.
Есть два способа это сделать:
1. Векторный движок. Все операции пишутся не для отдельных значений, а для векторов. То есть, вызывать операции надо достаточно редко, и издержки на диспетчеризацию становятся пренебрежимо маленькими. Код операции содержит в себе хорошо оптимизированный внутренний цикл.
2. Кодогенерация. Для запроса генерируется код, в котором подставлены все косвенные вызовы.
В "обычных" БД этого не делается, так как не имеет смысла при выполнении простых запросов. Хотя есть исключения. Например, в MemSQL кодогенерация используется для уменьшения latency при выполнении SQL запросов. (Для сравнения - в аналитических СУБД, требуется оптимизация throughput, а не latency).
Стоит заметить, что для эффективности по CPU требуется, чтобы язык запросов был декларативным (SQL, MDX) или хотя бы векторным (J, K). То есть, чтобы запрос содержал циклы только в неявном виде, открывая возможности для оптимизации.
==Отличительные возможности ClickHouse==
1. По-настоящему столбцовая СУБД.
2. Сжатие данных.
3. Хранение данных на диске.
4. Параллельная обработка запроса на многих процессорных ядрах.
5. Распределённая обработка запроса на многих серверах.
6. Поддержка SQL.
7. Векторный движок.
8. Обновление данных в реальном времени.
9. Наличие индексов.
10. Подходит для онлайн запросов.
11. Поддержка приближённых вычислений.
12. Поддержка вложенных структур данных. Поддержка массивов в качестве типов данных.
13. Поддержка ограничений на сложность запросов, а также квот.
14. Репликация данных, поддержка целостности данных на репликах.
Рассмотрим некоторые возможности подробнее.
<h3 class="not-for-contents">1. По-настоящему столбцовая СУБД.</h3>
В по-настоящему столбцовой СУБД рядом со значениями не хранится никакого "мусора". Например, должны поддерживаться значения постоянной длины, чтобы не хранить рядом со значениями типа "число" их длины. Для примера, миллиард значений типа UInt8 должен действительно занимать в несжатом виде около 1GB, иначе это сильно ударит по эффективности использования CPU. Очень важно хранить данные компактно (без "мусора") в том числе в несжатом виде, так как скорость разжатия (использование CPU) зависит, в основном, от объёма несжатых данных.
Этот пункт пришлось выделить, так как существуют системы, которые могут хранить значения отдельных столбцов по отдельности, но не могут эффективно выполнять аналитические запросы в силу оптимизации под другой сценарий работы. Примеры: HBase, BigTable, Cassandra, HyperTable. В этих системах вы получите throughput в районе сотен тысяч строк в секунду, но не сотен миллионов строк в секунду.
Также стоит заметить, что ClickHouse является СУБД, а не одной базой данных. То есть, ClickHouse позволяет создавать таблицы и базы данных в runtime, загружать данные и выполнять запросы без переконфигурирования и перезапуска сервера.
<h3 class="not-for-contents">2. Сжатие данных.</h3>
Некоторые столбцовые СУБД (InfiniDB CE, MonetDB) не используют сжатие данных. Но сжатие данных действительно серьёзно увеличивает производительность.
<h3 class="not-for-contents">3. Хранение данных на диске.</h3>
Многие столбцовые СУБД (SAP HANA, Google PowerDrill) могут работать только в оперативке. Но оперативки (даже на тысячах серверах) слишком мало для хранения всех хитов и визитов в Яндекс.Метрике.
<h3 class="not-for-contents">4. Параллельная обработка запроса на многих процессорных ядрах.</h3>
Большие запросы естественным образом распараллеливаются.
<h3 class="not-for-contents">5. Распределённая обработка запроса на многих серверах.</h3>
Почти все перечисленные ранее столбцовые СУБД не поддерживают распределённую обработку запроса.
В ClickHouse данные могут быть расположены на разных шардах. Каждый шард может представлять собой группу реплик, которые используются для отказоустойчивости. Запрос будет выполнен на всех шардах параллельно. Это делается прозрачно для пользователя.
<h3 class="not-for-contents">6. Поддержка SQL.</h3>
Если вы знаете, что такое стандартный SQL, то говорить о поддержке SQL всё-таки нельзя.
Не поддерживаются NULL-ы. Все функции названы по-другому.
Тем не менее, это - декларативный язык запросов на основе SQL и во многих случаях не отличимый от SQL.
Поддерживаются JOIN-ы. Поддерживаются подзапросы в секциях FROM, IN, JOIN, а также скалярные подзапросы.
Зависимые подзапросы не поддерживаются.
<h3 class="not-for-contents">7. Векторный движок.</h3>
Данные не только хранятся по столбцам, но и обрабатываются по векторам - кусочкам столбцов. За счёт этого достигается высокая эффективность по CPU.
<h3 class="not-for-contents">8. Обновление данных в реальном времени.</h3>
ClickHouse поддерживает таблицы с первичным ключом. Для того, чтобы можно было быстро выполнять запросы по диапазону первичного ключа, данные инкрементально сортируются с помощью merge дерева. За счёт этого, поддерживается постоянное добавление данных в таблицу. Блокировки при добавлении данных отсутствуют.
<h3 class="not-for-contents">9. Наличие индексов.</h3>
Наличие первичного ключа позволяет, например, вынимать данные для конкретных клиентов (счётчиков Метрики), для заданного диапазона времени, с низкими задержками - менее десятков миллисекунд.
<h3 class="not-for-contents">10. Подходит для онлайн запросов.</h3>
Это позволяет использовать систему в качестве бэкенда для веб-интерфейса. Низкие задержки позволяют не откладывать выполнение запроса, а выполнять его в момент загрузки страницы интерфейса Яндекс.Метрики. То есть, в режиме онлайн.
<h3 class="not-for-contents">11. Поддержка приближённых вычислений.</h3>
1. Система содержит агрегатные функции для приближённого вычисления количества различных значений, медианы и квантилей.
2. Поддерживается возможность выполнить запрос на основе части (выборки) данных и получить приближённый результат. При этом, с диска будет считано пропорционально меньше данных.
3. Поддерживается возможность выполнить агрегацию не для всех ключей, а для ограниченного количества первых попавшихся ключей. При выполнении некоторых условий на распределение ключей в данных, это позволяет получить достаточно точный результат с использованием меньшего количества ресурсов.
<h3 class="not-for-contents">14. Репликация данных, поддержка целостности данных на репликах.</h3>
Используется асинхронная multimaster репликация. После записи на любую доступную реплику, данные распространяются на все остальные реплики. Система поддерживает полную идентичность данных на разных репликах. Восстановление после сбоя осуществляется автоматически, а в сложных случаях - "по кнопке".
Подробнее смотрите раздел "Репликация данных".
==Особенности ClickHouse, которые могут считаться недостатками==
1. Отсутствие транзакций.
2. Необходимо, чтобы результат выполнения запроса, в случае агрегации, помещался в оперативку на одном сервере.
Объём исходных данных для запроса, при этом, может быть сколь угодно большим.
3. Отсутствие полноценной реализации UPDATE/DELETE.
==Постановка задачи в Яндекс.Метрике==
Нужно получать произвольные отчёты на основе хитов и визитов, с произвольными сегментами, задаваемыми пользователем. Данные для отчётов обновляются в реальном времени. Запросы должны выполняться сразу (в режиме онлайн). Отчёты должно быть возможно строить за произвольный период. Требуется вычислять сложные агрегаты типа количества уникальных посетителей.
На данный момент (апрель 2014), каждый день в Яндекс.Метрику поступает около 12 миллиардов событий (хитов и кликов мыши). Все эти события должны быть сохранены для возможности строить произвольные отчёты. Один запрос может потребовать просканировать сотни миллионов строк за время не более нескольких секунд, или миллионы строк за время не более нескольких сотен миллисекунд.
===Агрегированные и неагрегированные данные===
Существует мнение, что для того, чтобы эффективно считать статистику, данные нужно агрегировать, так как это позволяет уменьшить объём данных.
Но агрегированные данные являются очень ограниченным решением, по следующим причинам:
- вы должны заранее знать перечень отчётов, необходимых пользователю;
- то есть, пользователь не может построить произвольный отчёт;
- при агрегации по большому количеству ключей, объём данных не уменьшается и агрегация бесполезна;
- при большом количестве отчётов, получается слишком много вариантов агрегации (комбинаторный взрыв);
- при агрегации по ключам высокой кардинальности (например, URL) объём данных уменьшается не сильно (менее чем в 2 раза);
- из-за этого, объём данных при агрегации может не уменьшиться, а вырасти;
- пользователи будут смотреть не все отчёты, которые мы для них посчитаем - то есть, большая часть вычислений бесполезна;
- возможно нарушение логической целостности данных для разных агрегаций;
Как видно, если ничего не агрегировать, и работать с неагрегированными данными, то это даже может уменьшить объём вычислений.
Впрочем, при агрегации, существенная часть работы выносится в оффлайне, и её можно делать сравнительно спокойно. Для сравнения, при онлайн вычислениях, вычисления надо делать так быстро, как это возможно, так как именно в момент вычислений пользователь ждёт результата.
В Яндекс.Метрике есть специализированная система для агрегированных данных - Metrage, на основе которой работает большинство отчётов.
Также в Яндекс.Метрике с 2009 года использовалась специализированная OLAP БД для неагрегированных данных - OLAPServer, на основе которой раньше работал конструктор отчётов.
OLAPServer хорошо подходил для неагрегированных данных, но содержал много ограничений, не позволяющих использовать его для всех отчётах так, как хочется: отсутствие поддержки типов данных (только числа), невозможность инкрементального обновления данных в реальном времени (только перезаписью данных за сутки). OLAPServer не является СУБД, а является специализированной БД.
Чтобы снять ограничения OLAPServer-а и решить задачу работы с неагрегированными данными для всех отчётов, разработана СУБД ClickHouse.
==Использование в Яндекс.Метрике и других отделах Яндекса==
В Яндекс.Метрике ClickHouse используется для нескольких задач.
Основная задача - построение отчётов в режиме онлайн по неагрегированным данным. Для решения этой задачи используется кластер из 374 серверов, хранящий более 20,3 триллионов строк в базе данных. Объём сжатых данных, без учёта дублирования и репликации, составляет около 2 ПБ. Объём несжатых данных (в формате tsv) составил бы, приблизительно, 17 ПБ.
Также ClickHouse используется:
- для хранения данных Вебвизора;
- для обработки промежуточных данных;
- для построения глобальных отчётов Аналитиками;
- для выполнения запросов в целях отладки движка Метрики;
- для анализа логов работы API и пользовательского интерфейса.
ClickHouse имеет более десятка инсталляций в других отделах Яндекса: в Вертикальных сервисах, Маркете, Директе, БК, Бизнес аналитике, Мобильной разработке, AdFox, Персональных сервисах и т п.
==Возможные аналоги==
Доступных аналогов нет.
На данный момент (май 2016) не существует доступных (open-source, бесплатных) систем, обладающих всеми перечисленными выше возможностями.
Но эти возможности являются абсолютно строго необходимыми для Яндекс.Метрики.
==Возможные глупые вопросы==
<h3 class="not-for-contents">1. Почему бы не использовать системы типа map-reduce?</h3>
Системами типа map-reduce будем называть системы распределённых вычислений, в которых операция reduce сделана на основе распределённой сортировки. Таким образом, к ним относятся YAMR, <a href="http://hadoop.apache.org/">Hadoop</a>, <a href="https://yandexdataschool.ru/about/conference/program/babenko">YT</a>.
Такие системы не подходят для онлайн запросов в силу слишком большой latency. То есть, не могут быть использованы в качестве бэкенда для веб-интерфейса.
Такие системы не подходят для обновления данных в реальном времени.
Распределённая сортировка не является оптимальным способом выполнения операции reduce, если результат выполнения операции и все промежуточные результаты, при их наличии, помещаются в оперативку на одном сервере, как обычно бывает в запросах, выполняющихся в режиме онлайн. В таком случае, оптимальным способом выполнения операции reduce является хэш-таблица. Частым способом оптимизации map-reduce задач является предагрегация (частичный reduce) с использованием хэш-таблицы в оперативке. Эта оптимизация делается пользователем в ручном режиме.
Распределённая сортировка является основной причиной тормозов при выполнении несложных map-reduce задач.
Системы типа map-reduce позволяют выполнять произвольный код на кластере. Но для OLAP задач лучше подходит декларативный язык запросов, который позволяет быстро проводить исследования. Для примера, для Hadoop существует <a href="https://hive.apache.org/">Hive</a> и <a href="https://pig.apache.org/">Pig</a>. Также смотрите <a href="http://impala.io/">Cloudera Impala</a>, <a href="http://shark.cs.berkeley.edu/">Shark (устаревший)</a> для <a href="http://spark.apache.org/">Spark</a> а также <a href="http://spark.apache.org/sql/">Spark SQL</a>, <a href="https://prestodb.io/">Presto</a>, <a href="https://drill.apache.org/">Apache Drill</a>. Впрочем, производительность при выполнении таких задач является сильно неоптимальной по сравнению со специализированными системами, а сравнительно высокая latency не позволяет использовать эти системы в качестве бэкенда для веб-интерфейса.
YT позволяет хранить группы столбцов по отдельности. Но YT нельзя назвать по-настоящему столбцовой системой, так как в системе отсутствуют типы данных постоянной длины (чтобы можно было эффективно хранить числа без "мусора"), а также за счёт отсутствия векторного движка. Задачи в YT выполняются с помощью произвольного кода в режиме streaming, то есть, не могут быть достаточно оптимизированы (до сотен миллионов строк в секунду на один сервер). В YT в 2014-2016 годах находится в разработке функциональность "динамических сортированных таблиц" с использованием Merge Tree, строгой типизацией значений и языком запросов типа SQL. Динамические сортированные таблицы не подходят для OLAP задач, так как данные в них хранятся по строкам. Разработка языка запросов в YT всё ещё находится в зачаточной стадии, что не позволяет ориентироваться на эту функциональность. Разработчики YT рассматривают динамические сортированные таблицы для применения в OLTP и Key-Value сценариях работы.
==Производительность==
По результатам внутреннего тестирования, ClickHouse обладает наиболее высокой производительностью (как наиболее высоким throughput на длинных запросах, так и наиболее низкой latency на коротких запросах), при соответствующем сценарии работы, среди доступных для тестирования систем подобного класса. Результаты тестирования можно посмотреть <a href="benchmark.html">на отдельной странице</a>.
===Пропускная способность при обработке одного большого запроса===
Пропускную способность можно измерять в строчках в секунду и в мегабайтах в секунду. При условии, что данные помещаются в page cache, не слишком сложный запрос обрабатывается на современном железе со скоростью около 2-10 GB/sec. несжатых данных на одном сервере (в простейшем случае скорость может достигать 30 GB/sec). Если данные не помещаются в page cache, то скорость работы зависит от скорости дисковой подсистемы и коэффициента сжатия данных. Например, если дисковая подсистема позволяет читать данные со скоростью 400 MB/sec., а коэффициент сжатия данных составляет 3, то скорость будет около 1.2GB/sec. Для получения скорости в строчках в секунду, следует поделить скорость в байтах в секунду на суммарный размер используемых в запросе столбцов. Например, если вынимаются столбцы на 10 байт, то скорость будет в районе 100-200 млн. строчек в секунду.
При распределённой обработке запроса, скорость обработки запроса растёт почти линейно, но только при условии, что в результате агрегации или при сортировке получается не слишком большое множество строчек.
===Задержки при обработке коротких запросов.===
Если запрос использует первичный ключ, и выбирает для обработки не слишком большое количество строчек (сотни тысяч), и использует не слишком большое количество столбцов, то вы можете рассчитывать на latency менее 50 миллисекунд (от единиц миллисекунд в лучшем случае), при условии, что данные помещаются в page cache. Иначе latency вычисляется из количества seek-ов. Если вы используйте вращающиеся диски, то на не слишком сильно нагруженной системе, latency вычисляется по формуле: seek time (10 мс.) * количество столбцов в запросе * количество кусков с данными.
===Пропускная способность при обработке большого количества коротких запросов.===
При тех же условиях, ClickHouse может обработать несколько сотен (до нескольких тысяч в лучшем случае) запросов в секунду на одном сервере. Так как такой сценарий работы не является типичным для аналитических СУБД, рекомендуется рассчитывать не более чем на 100 запросов в секунду.
===Производительность при вставке данных.===
Данные рекомендуется вставлять пачками не менее 1000 строк или не более одного запроса в секунду. При вставке в таблицу типа MergeTree из tab-separated дампа, скорость вставки будет в районе 50-200 МБ/сек. Если вставляются строчки размером около 1 КБ, то скорость будет в районе 50 000 - 200 000 строчек в секунду. Если строчки маленькие - производительность в строчках в секунду будет выше (на данных БК - > 500 000 строк в секунду, на данных Graphite - > 1 000 000 строк в секунду). Для увеличения производительности, можно производить несколько запросов INSERT параллельно - при этом производительность растёт линейно.
</div>
<div class="island">
<h1>Начало работы</h1>
</div>
<div class="island content">
==Системные требования==
Система некроссплатформенная. Требуется ОС Linux Ubuntu не более старая, чем Precise (12.04); архитектура x86_64 с поддержкой набора инструкций SSE 4.2.
Для проверки наличия SSE 4.2, выполните:
%%grep -q sse4_2 /proc/cpuinfo && echo "SSE 4.2 supported" || echo "SSE 4.2 not supported"%%
Рекомендуется использовать Ubuntu Trusty или Ubuntu Xenial или Ubuntu Precise.
Терминал должен работать в кодировке UTF-8 (как по умолчанию в Ubuntu).
==Установка==
В целях тестирования и разработки, система может быть установлена на один сервер или на рабочий компьютер.
===Установка из пакетов===
Пропишите в %%/etc/apt/sources.list%% (или в отдельный файл %%/etc/apt/sources.list.d/clickhouse.list%%) репозитории:
На Ubuntu Trusty (14.04):
%%
deb http://repo.yandex.ru/clickhouse/trusty stable main
%%
На других версиях Ubuntu, замените %%trusty%% на %%xenial%% или %%precise%%.
Затем выполните:
%%
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv E0C56BD4 # optional
sudo apt-get update
sudo apt-get install clickhouse-client clickhouse-server-common
%%
Также можно скачать и установить пакеты вручную, отсюда:
<a href="http://repo.yandex.ru/clickhouse/trusty/pool/main/c/clickhouse/">http://repo.yandex.ru/clickhouse/trusty/pool/main/c/clickhouse/</a>,
<a href="http://repo.yandex.ru/clickhouse/trusty/pool/main/c/clickhouse/">http://repo.yandex.ru/clickhouse/xenial/pool/main/c/clickhouse/</a>,
<a href="http://repo.yandex.ru/clickhouse/precise/pool/main/c/clickhouse/">http://repo.yandex.ru/clickhouse/precise/pool/main/c/clickhouse/</a>.
ClickHouse содержит настройки ограничения доступа. Они расположены в файле users.xml (рядом с config.xml).
По умолчанию, разрешён доступ отовсюду для пользователя default без пароля. См. секцию users/default/networks.
Подробнее смотрите в разделе "конфигурационные файлы".
===Установка из исходников===
Для сборки воспользуйтесь инструкцией <a href="https://github.com/yandex/ClickHouse/blob/master/doc/build.md">build.md</a> (для Linux) или <a href="https://github.com/yandex/ClickHouse/blob/master/doc/build_osx.md">build_osx.md</a> (для Mac OS X).
Вы можете собрать пакеты и установить их.
Также вы можете использовать программы без установки пакетов.
Клиент: dbms/src/Client/
Сервер: dbms/src/Server/
Для сервера создаёте директории с данными, например:
%%
/var/lib/clickhouse/data/default/
/var/lib/clickhouse/metadata/default/
%%
(Настраивается в конфиге сервера.)
Сделайте chown под нужного пользователя.
Обратите внимание на путь к логам в конфиге сервера (src/dbms/src/Server/config.xml).
===Другие методы установки===
Docker образ: <a href="https://hub.docker.com/r/yandex/clickhouse-server/">https://hub.docker.com/r/yandex/clickhouse-server/</a>
Gentoo overlay: <a href="https://github.com/kmeaw/clickhouse-overlay">https://github.com/kmeaw/clickhouse-overlay</a>
===Запуск===
Для запуска сервера (в качестве демона), выполните:
<pre class="terminal">
sudo service clickhouse-server start
</pre>
Смотрите логи в директории
%%
/var/log/clickhouse-server/
%%
Если сервер не стартует - проверьте правильность конфигурации в файле
%%
/etc/clickhouse-server/config.xml
%%
Также можно запустить сервер из консоли:
<pre class="terminal">
clickhouse-server --config-file=/etc/clickhouse-server/config.xml
</pre>
При этом, лог будет выводиться в консоль - удобно для разработки.
Если конфигурационный файл лежит в текущей директории, то указывать параметр --config-file не требуется - по умолчанию будет использован файл ./config.xml
Соединиться с сервером можно с помощью клиента командной строки:
<pre class="terminal">
clickhouse-client
</pre>
Параметры по умолчанию обозначают - соединяться с localhost:9000, от имени пользователя default без пароля.
Клиент может быть использован для соединения с удалённым сервером. Пример:
<pre class="terminal">
clickhouse-client --host=example.com
</pre>
Подробнее смотри раздел "Клиент командной строки".
Проверим работоспособность системы:
<pre class="terminal">
milovidov@milovidov-Latitude-E6320:~/work/metrica/src/dbms/src/Client$ ./clickhouse-client
ClickHouse client version 0.0.18749.
Connecting to localhost:9000.
Connected to ClickHouse server version 0.0.18749.
:) SELECT 1
<i class='c15'>SELECT</i> 1
┌─<i class='c15'>1</i>─┐
│ 1 │
└───┘
1 rows in set. Elapsed: 0.003 sec.
:)
</pre>
Поздравляю, система работает!
==Тестовые данные==
Если вы сотрудник Яндекса, вы можете воспользоваться тестовыми данными Яндекс.Метрики для изучения возможностей системы.
Как загрузить тестовые данные, написано <a href='https://github.yandex-team.ru/Metrika/ClickHouse_private/tree/master/tests'>здесь</a>.
Если вы внешний пользователь системы, вы можете воспользоваться использовать общедоступные данные, способы загрузки которых указаны <a href='https://github.com/yandex/ClickHouse/tree/master/doc/example_datasets'>здесь</a>.
==Если возникли вопросы==
Если вы являетесь сотрудником Яндекса, обращайтесь на внутреннюю рассылку по ClickHouse.
Вы можете подписаться на эту рассылку, чтобы получать анонсы, быть в курсе нововведений, а также видеть вопросы, которые возникают у других пользователей.
Иначе вы можете задавать вопросы на <a href='https://stackoverflow.com/questions/tagged/clickhouse'>Stack Overflow</a> или участвовать в обсуждениях на <a href='https://groups.google.com/group/clickhouse'>Google Groups</a>. Также вы можете отправить приватное сообщение для разработчиков по адресу <a href='mailto:[email protected]'>[email protected]</a>.
</div>
<div class="island">
<h1>Интерфейсы</h1>
</div>
<div class="island content">
Для изучения возможностей системы, загрузки данных в таблицы, ручных запросов, используйте программу clickhouse-client.
Для удаленного доступа к ClickHouse пропишите в конфиг сервера:
<pre class="text-example"><listen_host>::</listen_host></pre>
==HTTP интерфейс==
HTTP интерфейс позволяет использовать ClickHouse на любой платформе, из любого языка программирования. У нас он используется для работы из Java и Perl, а также из shell-скриптов. В других отделах, HTTP интерфейс используется из Perl, Python и Go. HTTP интерфейс более ограничен по сравнению с родным интерфейсом, но является более совместимым.
По умолчанию, clickhouse-server слушает HTTP на порту 8123 (это можно изменить в конфиге).
Если запросить GET / без параметров, то вернётся строка "Ok." (с переводом строки на конце). Это может быть использовано в скриптах проверки живости.
<pre class="terminal">
$ curl 'http://localhost:8123/'
Ok.
</pre>
Запрос отправляется в виде параметра URL query. Или POST-ом. Или начало запроса в параметре query, а продолжение POST-ом (зачем это нужно, будет объяснено ниже). Размер URL ограничен 16KB, это следует учитывать при отправке длинных запросов в параметре query.
В случае успеха, вам вернётся код ответа 200 и результат обработки запроса в теле ответа.
В случае ошибки, вам вернётся код ответа 500 и текст с описанием ошибки в теле ответа.
При использовании метода GET, выставляется настройка readonly. То есть, для запросов, модифицирующие данные, можно использовать только метод POST. Сам запрос при этом можно отправлять как в теле POST-а, так и в параметре URL.
Примеры:
<pre class="terminal">
$ curl 'http://localhost:8123/?query=SELECT%201'
1
$ wget -O- -q 'http://localhost:8123/?query=SELECT 1'
1
$ GET 'http://localhost:8123/?query=SELECT 1'
1
$ echo -ne 'GET /?query=SELECT%201 HTTP/1.0\r\n\r\n' | nc localhost 8123
HTTP/1.0 200 OK
Connection: Close
Date: Fri, 16 Nov 2012 19:21:50 GMT
1
</pre>
Как видно, curl немного неудобен тем, что надо экранировать пробелы в URL.
wget экранирует самостоятельно, но его не рекомендуется использовать, так как он плохо работает по HTTP 1.1 при использовании keep-alive и Transfer-Encoding: chunked.
<pre class="terminal">
$ echo 'SELECT 1' | curl 'http://localhost:8123/' --data-binary @-
1
$ echo 'SELECT 1' | curl 'http://localhost:8123/?query=' --data-binary @-
1
$ echo '1' | curl 'http://localhost:8123/?query=SELECT' --data-binary @-
1
</pre>
Если часть запроса отправляется в параметре, а часть POST-ом, то между этими двумя кусками данных ставится перевод строки.
Пример (так работать не будет):
<pre class="terminal">
$ echo 'ECT 1' | curl 'http://localhost:8123/?query=SEL' --data-binary @-
Code: 59, e.displayText() = DB::Exception: Syntax error: failed at position 0: SEL
ECT 1
, expected One of: SHOW TABLES, SHOW DATABASES, SELECT, INSERT, CREATE, ATTACH, RENAME, DROP, DETACH, USE, SET, OPTIMIZE., e.what() = DB::Exception
</pre>
По умолчанию, данные возвращаются в формате TabSeparated (подробнее смотри раздел "Форматы").
Можно попросить любой другой формат - с помощью секции FORMAT запроса.
<pre class="terminal">
$ echo 'SELECT 1 FORMAT Pretty' | curl 'http://localhost:8123/?' --data-binary @-
┏━━━┓
┃ 1 ┃
┡━━━┩
│ 1 │
└───┘
</pre>
Возможность передавать данные POST-ом нужна для INSERT-запросов. В этом случае вы можете написать начало запроса в параметре URL, а вставляемые данные передать POST-ом. Вставляемыми данными может быть, например, tab-separated дамп, полученный из MySQL. Таким образом, запрос INSERT заменяет LOAD DATA LOCAL INFILE из MySQL.
Примеры:
Создаём таблицу:
<pre class="terminal">
echo 'CREATE TABLE t (a UInt8) ENGINE = Memory' | POST 'http://localhost:8123/'
</pre>
Используем привычный запрос INSERT для вставки данных:
<pre class="terminal">
echo 'INSERT INTO t VALUES (1),(2),(3)' | POST 'http://localhost:8123/'
</pre>
Данные можно отправить отдельно от запроса:
<pre class="terminal">
echo '(4),(5),(6)' | POST 'http://localhost:8123/?query=INSERT INTO t VALUES'
</pre>
Можно указать любой формат для данных. Формат Values - то же, что используется при записи INSERT INTO t VALUES:
<pre class="terminal">
echo '(7),(8),(9)' | POST 'http://localhost:8123/?query=INSERT INTO t FORMAT Values'
</pre>
Можно вставить данные из tab-separated дампа, указав соответствующий формат:
<pre class="terminal">
echo -ne '10\n11\n12\n' | POST 'http://localhost:8123/?query=INSERT INTO t FORMAT TabSeparated'
</pre>
Прочитаем содержимое таблицы. Данные выводятся в произвольном порядке из-за параллельной обработки запроса:
<pre class="terminal">
$ GET 'http://localhost:8123/?query=SELECT a FROM t'
7
8
9
10
11
12
1
2
3
4
5
6
</pre>
Удаляем таблицу.
<pre class="terminal">
echo 'DROP TABLE t' | POST 'http://localhost:8123/'
</pre>
Для запросов, которые не возвращают таблицу с данными, в случае успеха, выдаётся пустое тело ответа.
Вы можете использовать сжатие при передаче данных. Формат сжатых данных нестандартный, и вам придётся использовать для работы с ним специальную программу compressor (%%sudo apt-get install clickhouse-compressor%%).
Если вы указали в URL compress=1, то сервер будет сжимать отправляемые вам данные.
Если вы указали в URL decompress=1, то сервер будет разжимать те данные, которые вы передаёте ему POST-ом.
Это может быть использовано для уменьшения трафика по сети при передаче большого количества данных, а также для создания сразу сжатых дампов.
В параметре URL database может быть указана БД по умолчанию.
<pre class="terminal">
$ echo 'SELECT number FROM numbers LIMIT 10' | curl 'http://localhost:8123/?database=system' --data-binary @-
0
1
2
3
4
5
6
7
8
9
</pre>
По умолчанию используется БД, которая прописана в настройках сервера, как БД по умолчанию. По умолчанию, это - БД default. Также вы всегда можете указать БД через точку перед именем таблицы.
Имя пользователя и пароль могут быть указаны в одном из двух вариантов:
1. С использованием HTTP Basic Authentification. Пример:
<pre class="terminal">
echo 'SELECT 1' | curl 'http://user:password@localhost:8123/' -d @-
</pre>
2. В параметрах URL user и password. Пример:
<pre class="terminal">
echo 'SELECT 1' | curl 'http://localhost:8123/?user=user&password=password' -d @-
</pre>
Если имя пользователя не указано, то используется имя пользователя default. Если пароль не указан, то используется пустой пароль.
Также в параметрах URL вы можете указать любые настройки, которые будут использованы для обработки одного запроса, или целые профили настроек. Пример:
%%http://localhost:8123/?profile=web&max_rows_to_read=1000000000&query=SELECT+1%%
Подробнее см. раздел "Настройки".
<pre class="terminal">
$ echo 'SELECT number FROM system.numbers LIMIT 10' | curl 'http://localhost:8123/?' --data-binary @-
0
1
2
3
4
5
6
7
8
9
</pre>
Об остальных параметрах смотри раздел "SET".
В отличие от родного интерфейса, HTTP интерфейс не поддерживает понятие сессии и настройки в пределах сессии, не позволяет (вернее, позволяет лишь в некоторых случаях) прервать выполнение запроса, не показывает прогресс выполнения запроса. Парсинг и форматирование данных производится на стороне сервера и использование сети может быть неэффективным.
Может быть передан необязательный параметр query_id - идентификатор запроса, произвольная строка. Подробнее смотрите раздел "Настройки, replace_running_query".
Может быть передан необязательный параметр quota_key - ключ квоты, произвольная строка. Подробнее смотрите раздел "Квоты".
HTTP интерфейс позволяет передать внешние данные (внешние временные таблицы) для использования запроса. Подробнее смотрите раздел "Внешние данные для обработки запроса"
===Буферизация ответа===
Существует возможность включить буферизацию ответа на стороне сервера. Для этого предусмотрены параметры URL <b>buffer_size</b> и <b>wait_end_of_query</b>.
<b>buffer_size</b> определяет количество байт результата которые будут буферизованы в памяти сервера. Если тело результата больше этого порога, то буфер будет переписан в HTTP канал, а оставшиеся данные будут отправляться в HTTP-канал напрямую.
Чтобы гарантировать буферизацию всего ответа необходимо выставить <b>wait_end_of_query=1</b>. В этом случае данные, не поместившиеся в памяти, будут буферизованы во временном файле сервера.
Пример:
<pre class="terminal">
curl -sS 'http://localhost:8123/?max_result_bytes=4000000&buffer_size=3000000&wait_end_of_query=1' -d 'SELECT toUInt8(number) FROM system.numbers LIMIT 9000000 FORMAT RowBinary'
</pre>
Буферизация позволяет избежать ситуации когда код ответа и HTTP-заголовки были отправлены клиенту, после чего возникла ошибка выполнения запроса. В такой ситуации сообщение об ошибке записывается в конце тела ответа, и на стороне клиента ошибка может быть обнаружена только на этапе парсинга.
==JDBC драйвер==
Для ClickHouse существует официальный JDBC драйвер. Смотрите <a href="https://github.com/yandex/clickhouse-jdbc">здесь</a>.
==Библиотеки от сторонних разработчиков==
Существуют библиотеки для работы с ClickHouse для Python (<a href="https://github.com/Infinidat/infi.clickhouse_orm">1</a>, <a href="https://github.com/cloudflare/sqlalchemy-clickhouse">2</a>), PHP (<a href="https://github.com/8bitov/clickhouse-php-client">1</a>, <a href="https://github.com/SevaCode/PhpClickHouseClient">2</a>, <a href="https://github.com/smi2/phpClickHouse">3</a>), Go (<a href="https://github.com/kshvakov/clickhouse/">1</a>, <a href="https://github.com/roistat/go-clickhouse">2</a>), Node.js (<a href="https://github.com/TimonKK/clickhouse">1</a>, <a href="https://github.com/apla/node-clickhouse">2</a>), Perl (<a href="https://github.com/elcamlost/perl-DBD-ClickHouse">1</a>, <a href="https://metacpan.org/release/HTTP-ClickHouse">2</a>, <a href="https://metacpan.org/release/AnyEvent-ClickHouse">3</a>), Ruby (<a href="https://github.com/archan937/clickhouse">1</a>), R (<a href="https://github.com/hannesmuehleisen/clickhouse-r">1</a>), .NET (<a href="https://github.com/killwort/ClickHouse-Net">1</a>).
Библиотеки не тестировались нами. Порядок перечисления произвольный.
==GUI от сторонних разработчиков==
Существует <a href="https://github.com/smi2/tabix.ui">open source проект Tabix</a> от компании СМИ2, в котором реализован графический веб-интерфейс для работы с ClickHouse.
Ключевые возможности Tabix:
- работа с ClickHouse из браузера напрямую, без установки дополнительного ПО;
- редактор запросов, поддерживающий подсветку SQL-синтаксиса ClickHouse, автодополнения по всем объектам, включая словари, и контекстные подсказки для встроенных функций;
- построение графиков, диаграмм и отображение геокоординат для результатов запросов;
- интерактивный конструктор сводных таблиц (pivot) для результатов запросов;
- графические средства для анализа состояния ClickHouse;
- два цветовых оформления: светлое и темное.
<a href="https://tabix.io/doc/">Документация Tabix</a>
==Родной интерфейс (TCP)==
Родной интерфейс используется в клиенте командной строки clickhouse-client, при межсерверном взаимодействии для распределённой обработки запроса, а также в программах на C++. Будет рассмотрен только клиент командной строки.
==Клиент командной строки==
<pre class="terminal">
$ clickhouse-client
ClickHouse client version 0.0.26176.
Connecting to localhost:9000.
Connected to ClickHouse server version 0.0.26176.
:) SELECT 1
</pre>
Программа clickhouse-client принимает следующие параметры, все из которых являются необязательными:
--host, -h - имя сервера, по умолчанию - localhost.
Вы можете использовать как имя, так и IPv4 или IPv6 адрес.
--port - порт, к которому соединяться, по умолчанию - 9000.
Замечу, что для HTTP и родного интерфейса используются разные порты.
--user, -u - имя пользователя, по умолчанию - default.
--password - пароль, по умолчанию - пустая строка.
--query, -q - запрос для выполнения, при использовании в неинтерактивном режиме.
--database, -d - выбрать текущую БД, по умолчанию - текущая БД из настроек сервера (по умолчанию - БД default).
--multiline, -m - если указано - разрешить многострочные запросы, не отправлять запрос по нажатию Enter.
--multiquery, -n - если указано - разрешить выполнять несколько запросов, разделённых точкой с запятой.
Работает только в неинтерактивном режиме.
--format, -f - использовать указанный формат по умолчанию для вывода результата.
--vertical, -E - если указано, использовать формат Vertical по умолчанию для вывода результата. То же самое, что --format=Vertical. В этом формате каждое значение выводится на отдельной строке, что удобно для отображения широких таблиц.
--time, -t - если указано, в неинтерактивном режиме вывести время выполнения запроса в stderr.
--stacktrace - если указано, в случае исключения, выводить также его стек трейс.
--config-file - имя конфигурационного файла, в котором есть дополнительные настройки или изменены умолчания для настроек, указанных выше.
По умолчанию, ищутся файлы в следующем порядке:
./clickhouse-client.xml
~/.clickhouse-client/config.xml
/etc/clickhouse-client/config.xml
Настройки берутся только из первого найденного файла.
Также вы можете указать любые настройки, которые будут использованы для обработки запросов. Например, %%clickhouse-client --max_threads=1%%. Подробнее см. раздел "Настройки".
Клиент может быть использован в интерактивном и неинтерактивном (batch) режиме.
Чтобы использовать batch режим, укажите параметр query, или отправьте данные в stdin (проверяется, что stdin - не терминал), или и то, и другое.
Аналогично HTTP интерфейсу, при использовании одновременно параметра query и отправке данных в stdin, запрос составляется из конкатенации параметра query, перевода строки, и данных в stdin. Это удобно для больших INSERT запросов.
Примеры использования клиента для вставки данных:
%%
echo -ne "1, 'some text', '2016-08-14 00:00:00'\n2, 'some more text', '2016-08-14 00:00:01'" | clickhouse-client --database=test --query="INSERT INTO test FORMAT CSV";
cat <<_EOF | clickhouse-client --database=test --query="INSERT INTO test FORMAT CSV";
3, 'some text', '2016-08-14 00:00:00'
4, 'some more text', '2016-08-14 00:00:01'
_EOF
cat file.csv | clickhouse-client --database=test --query="INSERT INTO test FORMAT CSV";
%%
В batch режиме в качестве формата данных по умолчанию используется формат TabSeparated. Формат может быть указан в секции FORMAT запроса.
По умолчанию, в batch режиме вы можете выполнить только один запрос. Чтобы выполнить несколько запросов из "скрипта", используйте параметр --multiquery. Это работает для всех запросов кроме INSERT. Результаты запросов выводятся подряд без дополнительных разделителей.
Также, при необходимости выполнить много запросов, вы можете запускать clickhouse-client на каждый запрос. Заметим, что запуск программы clickhouse-client может занимать десятки миллисекунд.
В интерактивном режиме, вы получите командную строку, в которую можно вводить запросы.
Если не указано multiline (по умолчанию):
Чтобы выполнить запрос, нажмите Enter. Точка с запятой на конце запроса не обязательна. Чтобы ввести запрос, состоящий из нескольких строк, перед переводом строки, введите символ обратного слеша: %%\%% - тогда после нажатия Enter, вам предложат ввести следующую строку запроса.
Если указано multiline (многострочный режим):
Чтобы выполнить запрос, завершите его точкой с запятой и нажмите Enter. Если в конце введённой строки не было точки с запятой, то вам предложат ввести следующую строчку запроса.
Исполняется только один запрос, поэтому всё, что введено после точки с запятой, игнорируется.
Вместо или после точки с запятой может быть указано %%\G%%. Это обозначает использование формата Vertical. В этом формате каждое значение выводится на отдельной строке, что удобно для широких таблиц. Столь необычная функциональность добавлена для совместимости с MySQL CLI.
Командная строка сделана на основе readline (и history) (или libedit, или без какой-либо библиотеки, в зависимости от сборки) - то есть, в ней работают привычные сочетания клавиш, а также присутствует история.
История пишется в ~/.clickhouse-client-history.
По умолчанию, в качестве формата, используется формат PrettyCompact (красивые таблички). Вы можете изменить формат с помощью секции FORMAT запроса, или с помощью указания \G на конце запроса, с помощью аргумента командной строки --format или --vertical, или с помощью конфигурационного файла клиента.
Чтобы выйти из клиента, нажмите Ctrl+D (или Ctrl+C), или наберите вместо запроса одно из:
"exit", "quit", "logout", "учше", "йгше", "дщпщге", "exit;", "quit;", "logout;", "учшеж", "йгшеж", "дщпщгеж", "q", "й", "\q", "\Q", ":q", "\й", "\Й", "Жй"
При выполнении запроса, клиент показывает:
1. Прогресс выполнение запроса, который обновляется не чаще, чем 10 раз в секунду (по умолчанию). При быстрых запросах, прогресс может не успеть отобразиться.
2. Отформатированный запрос после его парсинга - для отладки.
3. Результат в заданном формате.
4. Количество строк результата, прошедшее время, а также среднюю скорость выполнения запроса.
Вы можете прервать длинный запрос, нажав Ctrl+C. При этом вам всё равно придётся чуть-чуть подождать, пока сервер остановит запрос. На некоторых стадиях выполнения, запрос невозможно прервать. Если вы не дождётесь и нажмёте Ctrl+C второй раз, то клиент будет завершён.
Клиент командной строки позволяет передать внешние данные (внешние временные таблицы) для использования запроса. Подробнее смотрите раздел "Внешние данные для обработки запроса"
</div>
<div class="island">
<h1>Язык запросов</h1>
</div>
<div class="island content">
==Программа clickhouse-local==
Программа clickhouse-local позволяет выполнять быструю обработку локальных файлов, хранящих таблицы, не прибегая к развертыванию и настройке clickhouse-server ...
==Синтаксис==
В системе есть два вида парсеров: полноценный парсер SQL (recursive descent parser) и парсер форматов данных (быстрый потоковый парсер).
Во всех случаях кроме запроса INSERT, используется только полноценный парсер SQL.
В запросе INSERT используется оба парсера:
%%INSERT INTO t VALUES (1, 'Hello, world'), (2, 'abc'), (3, 'def')%%
Фрагмент %%INSERT INTO t VALUES%% парсится полноценным парсером, а данные %%(1, 'Hello, world'), (2, 'abc'), (3, 'def')%% - быстрым потоковым парсером.
Данные могут иметь любой формат. При получении запроса, сервер заранее считывает в оперативку не более max_query_size байт запроса (по умолчанию, 1МБ), а всё остальное обрабатывается потоково.
Таким образом, в системе нет проблем с большими INSERT запросами, как в MySQL.
При использовании формата Values в INSERT запросе может сложиться иллюзия, что данные парсятся также, как выражения в запросе SELECT, но это не так - формат Values гораздо более ограничен.
Далее пойдёт речь о полноценном парсере. О парсерах форматов, смотри раздел "Форматы".
===Пробелы===
Между синтаксическими конструкциями (в том числе, в начале и конце запроса) может быть расположено произвольное количество пробельных символов. К пробельным символам относятся пробел, таб, перевод строки, CR, form feed.
===Комментарии===
Поддерживаются комментарии в SQL-стиле и C-стиле.
Комментарии в SQL-стиле: от %%--%% до конца строки. Пробел после %%--%% может не ставиться.
Комментарии в C-стиле: от %%/*%% до %%*/%%. Такие комментарии могут быть многострочными. Пробелы тоже не обязательны.
===Ключевые слова===
Ключевые слова (например, SELECT) регистронезависимы. Всё остальное (имена столбцов, функций и т. п.), в отличие от стандарта SQL, регистрозависимо. Ключевые слова не зарезервированы (а всего лишь парсятся как ключевые слова в соответствующем контексте).
===Идентификаторы===
Идентификаторы (имена столбцов, функций, типов данных) могут быть квотированными или не квотированными.
Не квотированные идентификаторы начинаются на букву латинского алфавита или подчёркивание; продолжаются на букву латинского алфавита или подчёркивание или цифру. Короче говоря, должны соответствовать регулярному выражению %%^[a-zA-Z_][0-9a-zA-Z_]*$%%. Примеры: %%x%%, %%_1%%, %%X_y__Z123_%%.
Квотированные идентификаторы расположены в обратных кавычках %%`id`%% (также, как в MySQL), и могут обозначать произвольный (непустой) набор байт. При этом, внутри записи такого идентификатора, символы (например, символ обратной кавычки) могут экранироваться с помощью обратного слеша. Правила экранирования такие же, как в строковых литералах (см. ниже).
Рекомендуется использовать идентификаторы, которые не нужно квотировать.
===Литералы===
Бывают числовые, строковые и составные литералы.
<h4>Числовые литералы</h4>
Числовой литерал пытается распарситься:
- сначала как 64-битное число без знака, с помощью функции strtoull;
- если не получилось - то как 64-битное число со знаком, с помощью функции strtoll;
- если не получилось - то как число с плавающей запятой, с помощью функции strtod;
- иначе - ошибка.
Соответствующее значение будет иметь тип минимального размера, который вмещает значение.
Например, 1 парсится как UInt8, а 256 - как UInt16. Подробнее смотрите "Типы данных".
Примеры: %%1%%, %%18446744073709551615%%, %%0xDEADBEEF%%, %%01%%, %%0.1%%, %%1e100%%, %%-1e-100%%, %%inf%%, %%nan%%.
<h4>Строковые литералы</h4>
Поддерживаются только строковые литералы в одинарных кавычках. Символы внутри могут быть экранированы с помощью обратного слеша. Следующие escape-последовательности имеют соответствующее специальное значение: %%\b%%, %%\f%%, %%\r%%, %%\n%%, %%\t%%, %%\0%%, %%\a%%, %%\v%%, <span class="inline-example">\x<i>HH</i></span>. Во всех остальных случаях, последовательности вида <span class="inline-example">\<i>c</i></span>, где <i>c</i> - любой символ, преобразуется в <i>c</i>. Таким образом, могут быть использованы последовательности %%\'%% и %%\\%%. Значение будет иметь тип String.
Минимальный набор символов, которых вам необходимо экранировать в строковых литералах: %%'%% and %%\%%.
<h4>Составные литералы</h4>