Skip to content
Mikhail f. Shiryaev edited this page May 11, 2021 · 15 revisions

Table of Contents

Параметры соединения с ClickHouse

В адрес clickhouse.url можно вписать любые параметры соединения, логин и пароль пользователя:

[clickhouse]
url = "http://graphite:qwerty@localhost:8123/?max_query_size=2097152&readonly=2&log_queries=1"

Наиболее полезные параметры:

  • readonly=2 - Просто на всякий случай
  • max_query_size=2097152
  • max_ast_elements=1000000
  • max_execution_time=60
  • max_rows_to_read=200000000 - Полезно чтобы избежать выполнения ну очень больших запросов (на большое количество метрик и длительный промежуток времени)
  • log_queries=1 - Логировать запросы, полезно для анализа быстродействия

Параметры graphite-web

Параметры указаны для graphite-web 1.1.2. В более ранних версиях они назывались по другому

CLUSTER_SERVERS = ['127.0.0.1:9090']
# Не отключать хождение в graphite-clickhouse при ошибках или таймаутах
REMOTE_RETRY_DELAY = 0
# Увеличить таймауты
FETCH_TIMEOUT = 60
FIND_TIMEOUT = 10

Параметры carbonapi

С параметрами по-умолчанию carbonapi может разрезать один большой запрос на много маленьких. Это очень плохо работает с ClickHouse. Надо обязательно выставлять параметры:

sendGlobsAsIs: true
maxBatchSize: 100000000

Но даже с этими параметрами carbonapi делает лишний запрос к /metrics/find/ перед /render/. Сейчас можно отключить только патчем (в будущем появится возможность сделать это и через конфиг):

diff -Naur carbonapi/http_handlers.go carbonapi-render-find/http_handlers.go
--- carbonapi/http_handlers.go	2018-02-26 11:59:25.996573711 +0300
+++ carbonapi-render-find/http_handlers.go	2018-02-26 21:17:35.676513385 +0300
@@ -297,7 +297,7 @@

 			if haveCacheData {
 				apiMetrics.FindCacheHits.Add(1)
-			} else {
+			} else if false {
 				apiMetrics.FindCacheMisses.Add(1)
 				var err error
 				apiMetrics.FindRequests.Add(1)

mtail

Замечен в том, что отправляет в графит точки со старыми таймстемпами. Видимо для счетчиков, которые давно перестали изменяться. ClickHouse очень сильно деградирует если запись ведется в несколько партиций одновременно. Варианты решения:

  • запатчить mtail
  • рестартить mtail при смене активной партиции (например, 1-го числа каждого месяца при дефолтном партиционировании)
  • ???

chunk-interval

Настройка data.chunk-interval в carbon-clickhouse одна из важнейших настроек системы. Она отвечает за то как часто данные отправляются в ClickHouse. Если выставить слишком большее значение, то данные будут появляться на графиках с заметной задержкой. А при слишком маленьком будет создаваться излишняя нагрузка на ClickHouse.

Под высокой нагрузкой в часы пик ClickHouse может начать тратить слишком много ресурсов на обработку запросов, перестает успевать мерджить данные на диске, из-за большего количества несмердженных данных начинает еще больше ресурсов тратить на обработку запросов и тд. по кругу. В результате практически перестает принимать новые данные и они начинают копиться на диске. Помогает только ручное увеличение chunk-interval.

Для автоматизации увеличения chunk-interval с версии 0.8.0 в carbon-clickhouse появилась опция chunk-auto-interval:

# Auto-increase chunk interval if the number of unprocessed files is grown
# Sample, set chunk interval to 10 if unhandled files count >= 5 and set to 60s if unhandled files count >= 20:
# chunk-auto-interval = "5:10s,20:60s"
chunk-auto-interval = ""

Удаление старых партиций

Пример команды на удаление данных старше 70 дней из таблицы graphite60 базы default при дефолтном партиционировании по месяцам:

/usr/bin/clickhouse-client -q "SELECT partition FROM system.parts 
WHERE database = 'default' AND table = 'graphite60' AND active = 1 
GROUP by partition HAVING max(max_date) < today() - 70;" | xargs -r -l1 -IPARTNAME \
/usr/bin/clickhouse-client -q "ALTER TABLE default.graphite60 DROP PARTITION 'PARTNAME';"

Удаление старых метрик из поддерева

Удалить из поддерева PREFIX.* все метрики, которые не получали уже дольше недели

INSERT INTO graphite_tree
SELECT
    Date,
    Level,
    Path,
    1 AS Deleted,
    toUInt32(now()) AS Version
FROM graphite_tree
WHERE Path IN
(
    SELECT Path
    FROM graphite_tree
    WHERE (Path LIKE 'PREFIX.%')
    GROUP BY Path
    HAVING max(Version) < toUInt32(toDateTime(today() - 7))
);

Скопировать данные из таблицы point в таблицу points-reverse

INSERT INTO graphite_reverse
    (Path, Value, Time, Date, Timestamp)
SELECT
    if(Path LIKE '%?%', Path, arrayStringConcat(arrayMap(x->reverse(x), splitByChar('.', reverse(Path))), '.')) as Path,
    Value, Time, Date, Timestamp
FROM graphite
WHERE Date >= '2018-05-01' AND Date <= '2018-05-31';

Скопировать данные из таблицы series в таблицу series-reverse

INSERT INTO graphite_series_reverse
    (Date, Level, Path, Deleted, Version)
SELECT 
    Date,
    Level,
    arrayStringConcat(arrayMap(x->reverse(x), splitByChar('.', reverse(Path))), '.') as Path,
    Deleted,
    Version
FROM graphite_series
WHERE Date = '2018-03-21'

Распределение времени выполнения запросов по табличкам

graphite-clickhouse шлет имя запрашиваемой таблицы в user-agent-е. Это позволяет более удобно анализировать суммарное время запросов к разным табличкам:

SELECT toStartOfMinute(query_start_time) AS tm,
       sum(query_duration_ms) AS value,
       extract(http_user_agent, 'table:([^;)]+)') AS table
FROM system.query_log
WHERE event_date = today()
  AND http_user_agent LIKE 'graphite-clickhouse/%'
  AND type == 2
GROUP BY tm, table

Разные retention-ы в разных таблицах

!!Неактуально при использовании internal-aggregation = true!!

Если необходимо читать из графита большое количество метрик за длительные периоды и при этом хочется сложные правила rollup-а, то имеет смысл задуматься над тем чтобы точки с разным прореживанием хранить в разных таблицах. Например, есть необходимость хранить данные с правилами прореживания:

  • точку каждые 10 секунд в течение 14 дней
  • точку в минуту в течение 60 дней
  • точку в час для данных старше

При запросе за 365 дней из такой таблицы придет 194520 точек на каждую метрику:

6*60*24*14 + 60*24*(60-14) + 24*(365-60) = 194520

При этом данные в graphite-clickhouse проредятся до 8760 точек (24*365). При наличии отдельных таблиц на разные ретеншены можно сразу селектить из таблички с почасовыми точками, что в приведенном примере в 20 раз уменьшит потребление памяти и ускорит выполнение запроса. @TODO: дописать