-
Notifications
You must be signed in to change notification settings - Fork 186
/
Copy pathindex.html
293 lines (253 loc) · 16 KB
/
index.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
<!DOCTYPE html>
<html lang="en">
<head>
<title>Анализ производительности запросов в ClickHouse</title>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="shower/themes/yandex/styles/screen-16x9.css">
</head>
<body class="shower list">
<header class="caption">
<h1>Анализ производительности запросов в ClickHouse</h1>
</header>
<section class="slide" id="cover" style="background: #FFF url('pictures/title.png') no-repeat; background-size: 100%;">
<h1 style="margin-top: 200px; font-size: 32pt;">Анализ производительности<br/>запросов в ClickHouse</h1>
</section>
<section class="slide">
<h2>Обо мне</h2>
<p>Алексей, разработчик ClickHouse.</p>
</section>
<section class="slide">
<h2 style="font-size: 32pt;">Анализ производительности запросов</h2>
<p><ul><li>Достаточно ли быстро работает запрос?</li>
<li>Если нет, то почему?</li>
<li>Можно ли выполнить запрос быстрее?</li></ul></p>
</section>
<section class="slide">
<h2>Тривиальные факты</h2>
<p>... и прописные истины.</p>
</section>
<section class="slide">
<h2 style="font-size: 32pt;">Какие ресурсы используются в системе?</h2>
<p>— процессор;</p>
<p>— память;</p>
<p>— диск;</p>
<p>— сеть.</p>
<p style="font-size: 12pt;">... а ещё программа может упираться в sleep.</p>
</section>
<section class="slide">
<h2 style="font-size: 32pt;">Какие ресурсы используются в системе?</h2>
<p>Утилизация ресурса — агрегированная величина, <br/>которая обычно не даёт полной картины.</p>
<p>Если ресурс утилизирован «на 100%»<br/> — это ещё не значит, что нельзя сделать лучше.</p>
<p>Если ресурс утилизирован менее чем на 100%<br/> — это ещё не значит, что можно сделать лучше.</p>
</section>
<section class="slide">
<h2>Пример 1, CPU</h2>
<p>Смотрим утилизацию CPU в <b>top</b>, <b>htop</b>, etc.</p>
<p>Если показывают, что ядро CPU загружено на 100%, значит процессор выполняет инструкции, но:</p>
<p>— процессор может выполнять разное количество инструкций за такт;</p>
<p>— процессор может ожидать загрузки данных из памяти или из кэша,<br/> но это время тоже учитывается как утилизация CPU (<b>perf record</b>);</p>
<p>— процессор может работать на пониженной частоте (<b>turbostat</b>, <b>dmesg</b>);</p>
</section>
<section class="slide">
<h2>Пример 1, CPU</h2>
<p>Если показывают, что суммарно CPU загружен на 50%:</p>
<p>— возможно, что больше не имеет смысла,<br/> если на вашем коде Hyper-Threading даёт мало профита;</p>
<p>— возможно, что вы смотрите усреднённую величину, тогда как<br/> в отдельные моменты времени, процессор загружен полностью.</p>
</section>
<section class="slide">
<h2 style="font-size: 24pt;">Чем занят CPU? Во что упирается запрос?</h2>
<img style="margin-top: -30px;" src="pictures/random_set_query.png"/>
<img src="pictures/perf.png"/>
</section>
<section class="slide">
<h2>Пример 2, диски</h2>
<p>... или SSD.</p>
<p>Программа тратит всё время на чтение с дисков, но <b>iostat</b> показывает утилизацию меньше 100%:<br/>
— у вас RAID-массив, но вы читаете с недостаточным размером буфера<br/>
с O_DIRECT или без readahead — диски используются<br/>
не все параллельно;<br/>
— у вас RAID-10, но вы создали его с <b>near</b>, а не <b>far</b> layout в mdadm;<br/>
— у вас RAID-5/6, но установлен неправильный <b>stripe cache size</b>;<br/>
— вы делаете случайные чтения с недостаточной степенью<br/> параллелизма
(для SSD используйте только AIO (<b>io_submit</b>)<br/>
для случайных чтений).</p>
<p><b>И ещё</b>: всегда сжимайте данные, хранящиеся на диске.</p>
</section>
<section class="slide">
<video style="height: 90%"><source src="video/iostat_bad.ogv" type="video/ogg"></video>
</section>
<section class="slide">
<video style="height: 90%"><source src="video/iostat_good.ogv" type="video/ogg"></video>
</section>
<section class="slide">
<h2>Бонус</h2>
<p>Если вы не уверены, стоит ли сжимать данные, хранящиеся на диске,<br/>
смотрите доклад HighLoad++ Siberia 2018 «<b>Как ускорить разжатие LZ4</b>»:<br/>
<br/><a href="https://www.youtube.com/watch?v=V2CqQBICt7M">https://youtu.be/V2CqQBICt7M</a>
</p>
</section>
<section class="slide">
<h2>Пример 3, память</h2>
<p>Linux показывает, что в системе почти нет свободной памяти:<br/>
— не смотрите на free память: <a href="https://www.linuxatemyram.com/">https://www.linuxatemyram.com/</a>.</p>
<p>Top показывает, что процесс занял памяти больше, чем есть:<br/>
— не смотрите на VIRT память у процесса (большой размер адресного пространства — это нормально, смотрите на RSS).</p>
<p>На графиках видно, что процесс не освобождает память:<br/>
— современные аллокаторы (почти) не отдают память системе напрямую.</p>
<p><b>И ещё</b>: не включайте swap;</p>
</section>
<section class="slide">
<h2>Пример 4, сеть</h2>
<p>Программа тратит всё время на передачу данных по сети,<br/>но сеть не утилизирована:</p>
<p>— возможно, вы создаёте новые TCP соединения<br/>на каждую передачу данных;</p>
<p>— возможно, вы используете одно TCP соединение<br/>для передачи файлов в сети с существенной потерей пакетов;</p>
<p>— возможно, вы отправляете данные маленькими кусочками<br/>с TCP_NODELAY.</p>
<p><b>И ещё</b>: всегда сжимайте данные, передаваемые по сети.</p>
</section>
<section class="slide" style="background: #FFF url('pictures/linux_observability_tools.png') center no-repeat; background-size: 75%;">
</section>
<section class="slide">
<h2>Базовый набор</h2>
<p><b>top</b>, <b>htop</b>: CPU, память по процессам;</p>
<p><b>dstat</b>: IO, сеть, ...;</p>
<p><b>iostat</b>: IO по устройствам;</p>
<p><b>iotop</b>: IO по процессам;</p>
<p><b>iftop</b>: сеть по хостам;</p>
<p><b>perf top</b>: CPU по функциям в процессах;</p>
</section>
<section class="slide">
<h2>Пример: top по потокам</h2>
</section>
<section class="slide">
<video style="height: 90%"><source src="video/top.ogv" type="video/ogg"></video>
</section>
<section class="slide">
<h2 style="font-size: 32pt;">Пример: clickhouse-benchmark + perf top</h2>
</section>
<section class="slide">
<video style="height: 90%"><source src="video/benchmark_perf.ogv" type="video/ogg"></video>
</section>
<section class="slide">
<h2 style="font-size: 32pt;">Потребление ресурсов внутри ClickHouse</h2>
</section>
<section class="slide">
<h2 style="font-size: 32pt;">Что происходит прямо сейчас?</h2>
<p>
<code>SHOW PROCESSLIST</code>
</p><p>
Или <code>SELECT * FROM system.processes</code>
</p><p>
<code>SELECT * FROM system.merges</code>
</p><p>
«clickhouse top»:<br/>
<code style="line-height: 1.5; font-size: 16pt;">watch -n1 'clickhouse-client --query="SHOW PROCESSLIST"'</code>
</p>
</section>
<section class="slide">
<video style="height: 90%"><source src="video/clickhouse_top.ogv" type="video/ogg"></video>
</section>
<section class="slide">
<h2 style="font-size: 32pt;">Что происходило раньше?</h2>
<p><b>system.query_log</b><br/>
— включается глобально, на пользователя, на сессию или на запрос;<br/>
— настройка <b>log_queries</b> = 1;<br/>
— запросы логгируются дважды: в начале и в конце выполнения.</p>
<p><b>system.part_log</b><br/>
— включается глобально в config.xml;<br/>
— логгируются все операции с данными MergeTree.</p>
<p>Запись в системные таблицы производится асинхронно.<br>
(раз в 7 секунд). <b>SYSTEM FLUSH LOGS</b> для принудительного сброса.</p>
</section>
<section class="slide">
<h2 style="font-size: 32pt;">Что можно с query_log?</h2>
<p>— выгрузить ленту запросов<br/>и нагрузить с помощью <b>clickhouse-benchmark</b>:</p>
<p><code style="display: block; white-space: pre;">clickhouse-client --query="
SELECT query FROM system.query_log
WHERE type = 2 AND event_date = today()
" > queries.tsv</code></p>
<p><code>clickhouse-benchmark < queries.tsv</code></p>
<p>— найти первый запрос, после которого всё стало плохо;</p>
<p>— посмотреть разбивку ресурсов по пользователям.</p>
</section>
<section class="slide">
<h2 style="font-size: 32pt;">Трассировка запросов</h2>
<p><code>SET <b>send_logs_level</b> = 'trace'</code></p>
<p>— логи отправляются со всех серверов,<br/> участвующих в обработке запроса<br/>
(распределённая трассировка);</p>
</section>
<section class="slide">
<video style="height: 90%"><source src="video/trace.ogv" type="video/ogg"></video>
</section>
<section class="slide">
<h2 style="font-size: 32pt;">Счётчики ресурсов</h2>
<p>Глобальные:<br/>
— system.<b>events</b>;<br/>
— system.<b>metrics</b>;<br/>
— system.<b>asynchronous_metrics</b>.</p>
<p>На каждый запрос:<br/>
— system.<b>processes</b>;<br/>
— system.<b>query_log</b>.</p>
<p>На каждый поток выполнения запроса:<br/>
— system.<b>query_thread_log</b>.</p>
</section>
<section class="slide">
<h2 style="font-size: 32pt;">Счётчики ресурсов</h2>
<p><b>User-space</b>:<br/>
— FileOpen;<br/>
— NetworkReceiveElapsedMicroseconds;<br/>
— ReadBufferFromFileDescriptorReadBytes...</p>
<p><b>Kernel-space</b>:<br/>
— OSReadChars;<br/>
— OSReadBytes;<br/>
— OSIOWaitMicroseconds;<br/>
— OSCPUWaitMicroseconds;<br/>
— UserTimeMicroseconds;<br/>
— SoftPageFaults...</p>
</section>
<section class="slide">
<video style="height: 90%; margin-left: -50px;"><source src="video/page_cache.ogv" type="video/ogg"></video>
</section>
<section class="slide">
<video style="height: 90%; margin-left: -50px;"><source src="video/query_stats.ogv" type="video/ogg"></video>
</section>
<section class="slide">
<h2 style="font-size: 32pt;">Счётчики ресурсов на запрос</h2>
<p><table style="line-height: 1.5;">
<tr><th>Метрика</th><th>Первый запуск</th><th>Второй запуск</th></tr>
<tr><td>Общее время</td><td>6.7 сек</td><td style="color: green;">1.3 сек</td></tr>
<tr><td>...FileDescriptorReadBytes</td><td>2.56 GiB</td><td>2.56 GiB</td></tr>
<tr><td>ReadChars</td><td>2.56 GiB</td><td>2.56 GiB</td></tr>
<tr><td>ReadBytes</td><td>3.23 GiB</td><td style="color: green;">3.13 MiB</td></tr>
<tr><td>IOWait</td><td>87.3 сек</td><td style="color: green;">0.023 сек</td></tr>
<tr><td>CPUWait</td><td>0.027 сек</td><td>0.045 сек</td></tr>
<tr><td>UserTime</td><td>9.9 сек</td><td>13.4 сек</td></tr>
<tr><td>SystemTime</td><td>2.4 сек</td><td>2.2 сек</td></tr>
</table>
</section>
<section class="slide">
<video style="height: 90%; margin-left: -50px;"><source src="video/thread_stats.ogv" type="video/ogg"></video>
</section>
<section class="slide">
<h2>Сообщество</h2>
<p>Сайт: <a href="https://clickhouse.com/">https://clickhouse.com/</a></p>
<p>Google groups: <a href="https://groups.google.com/forum/#!forum/clickhouse">https://groups.google.com/forum/#!forum/clickhouse</a></p>
<p>Рассылка: [email protected]</p>
<p>Telegram чат: <a href="https://telegram.me/clickhouse_en">https://telegram.me/clickhouse_en</a> и <a href="https://telegram.me/clickhouse_ru">https://telegram.me/clickhouse_ru</a> (уже 2000 участников)</p>
<p>GitHub: <a href="https://github.com/ClickHouse/ClickHouse/">https://github.com/ClickHouse/ClickHouse/</a> (уже 5300 звёзд)</p>
<p>+ встречи. Следующая в <b>Амстердаме 15 ноября</b>!<br/>
<a href="https://events.yandex.com/events/meetings/15-11-2018/">https://events.yandex.com/events/meetings/15-11-2018/</a></p>
</section>
<section class="slide">
<h2>Спасибо!</h2>
</section>
<div class="progress"></div>
<script src="shower/shower.min.js"></script>
<!--Video plugin-->
<link rel="stylesheet" href="shower/shower-video.css">
<script src="shower/shower-video.js"></script>
<!--/Video plugin-->
</body>
</html>