QUEUE_SIZE=5000# Async Queue size# Backend metrics window mode (fixed=fixed-size window, timed=time boxed)backend_metrics_window_mode=fixed# Backend metrics sliding window size for Percentiles, Min, Maxbackend_metrics_window=100# Backend metrics sliding window size for Percentiles, Min, Max# when backend_metrics_window_mode is timed# Setting this value too high can lead to OOM# backend_metrics_large_window=5000# Send interval in second# Defaults to 5 secondsbackend_influxdb.send_interval=5
Batch, batch, batch... увеличиваем размер batch'а
Пусть у нас 1200 rps и копим метрики 60 сек
QUEUE_SIZE=72000# 1200x60, было 5000, Async Queue size
Конфиг для backend_metrics_window_mode=fixed(не очищается):
backend_influxdb.send_interval=60# было 5backend_metrics_window=72000# 1200x60, было 100
Конфиг для backend_metrics_window_mode=timed(очищается ):
backend_influxdb.send_interval=60# было 5backend_metrics_large_window=72000# 1200x60, было 5000
JMeter-сценарий, с медленной статистикой
var plan = scenario.sendHttp(
testId: getTestId(linksCount),
linksCount: linksCount,
nameOfSampler: "web?id=${id} (GET)"//переменная ${id} в имени
);
Получим много тегов в InfluxDB и большой индекс:
web?id=0 (GET)
web?id=1 (GET)
...
web?id=1000000 (GET)
Или вообще ничего не запишем: ERROR org.apache.jmeter.visualizers.backend.influxdb
failed to send data to influxDB server.
Error writing metrics to influxDB Url:
http://influxdb:8086/write?db=jmeter100000,
responseCode: 400, responseBody: {"error": "partial write:
max-values-per-tag limit exceeded (100000/100000):
measurement=\"jmeter\" tag=\"transaction\"
value=\"web?id=19806 (GET)\" dropped=2"}
Error writing metrics to influxDB Url:
http://influxdb:8086/write?db=jmeter100000,
responseCode: 413, responseBody: {"error":"Request Entity Too Large"}
Не используем переменные в имени запроса
var plan = scenario.sendHttp(
testId: getTestId(linksCount),
linksCount: linksCount,
nameOfSampler: "web?id={id} (GET)"//вот так быстрее
);
apiVersion:1datasources:-name:jmeter_cache# Имя DataSource в Grafanatype:influxdb# InfluxQLaccess:proxy# Serverdatabase:jmeter# Имя базы данных в InfluxDBurl:http://nginx:80# Адрес кеширующего сервераjsonData:httpMode:GET# Метод GETbasicAuth:false# Без аутентификации
Важен статический интервал для кеширования
Абсолютный:
Не относительный:
Относительный интервал Last 6 hours UTC:
curl -G 'http://influxdb:8086/query?db=mydb' --data-urlencode \
'q=SELECT * FROM "metrics" \
where time>1655827200000 AND time<1655848800000'
Каждую милисекунду дает новый диапазон:
curl -G 'http://influxdb:8086/query?db=mydb' --data-urlencode \
'q=SELECT * FROM "metrics" \
where time>1655827230023 AND time<1655848830023'#+30023=+30s
А это уже новый URL, новый ключ кеширования
Ссылка в Grafana Text (HTML) для автоматизации
<h2><ahref="/d/${__dashboard}/?from=${__from}&to=${__to}&${db:queryparam}">
Select static time interval
</a></h2>
Мониторинг внутренних метрик InfluxDB из базы данных __internal
Размеры шард InfluxDB
Количество значений тегов
Количество конкурентных запросов к InfluxDB
Мониторинг общесистемных метрик
CPU ~= Количество одновременных query
RAM ~= Размер задействованных shard
Мониторинг внутренних метрик InfluxDB из базы данных __internal
shard : path : size : размеры индексов
database : numSeries : количество значений тегов
httpd : количество и длительность запросов
Размеры shard'ов InfluxDB
Shard — часть индекса, например, за 1 час
CREATE DATABASE "jmeter"
WITH DURATION INF REPLICATION 1
SHARD DURATION 1h NAME "autogen";
ОЗУ ~= Размер shard'ов в памяти (метрики shard)
Размеры shard'ов InfluxDB в памяти из shard
database : numSeries : количество значений тегов
Количество конкурентных запросов к InfluxDB
7. Мониторинг производительности InfluxDB
Мониторинг общесистемных метрик
CPU и память
Нехватка памяти для InfluxDB и перезапуски
Мониторинг внутренних метрик InfluxDB из базы данных __internal
Размеры shard'ов InfluxDB
Количество значений тегов
Количество конкурентных запросов к InfluxDB
Конфигурирование ограничений в InfluxDB по данным мониторинга
8. Конфигурирование сервера InfluxDB
Ограничиваем max-concurrent-queries
Ограничиваем max_conns в nginx upstream
Ограничиваем query-timeout
Ограничиваем max-select-series
Ограничиваем max-select-buckets
Изменение типа индекса с inmem на tsi1
Логирование узких мест c log-queries-after
Ограничиваем max-concurrent-queries
[coordinator]
# The maximum number of concurrent queries # allowed to be executing at one time. # If a query is executed and exceeds this limit, # an error is returned to the caller. # This limit can be disabled by setting it to 0.max-concurrent-queries=5
Ограничиваем query-timeout
[coordinator]
# The maximum time a query will is allowed # to execute before being killed by the system. # This limit can help prevent run away queries. # Setting the value to 0 disables the limit.query-timeout="60s"
Рассчитывайте на 100 МБайт аллокаций в сек
Если памяти 6000 МБайт, то 60s - предел
Ошибка при достижении query-timeout
query-timeout limit exceeded
SELECT mean(avg)
FROM jmeter
WHEREtime>1656242940000000000andtime<1656242940000000000+10m
GROUPBYtime(1m), transaction, statut, testid
Оцениваем предельное количество тегов ответа
Пусть есть:
5000 значений transaction
2 значения statut (ok, ko)
10 000 комбинаций (серий) всего
И мы допускам запросы по всем значениям:
SELECT mean(avg) FROM "jmeter"
В лимитах выставляем 5000 х 2 + чуть-чуть
Ограничиваем max-select-series
[coordinator]
# The maximum number of series a SELECT can run. # A value of 0 will make the maximum series# count unlimited.# max-select-series = 0max-select-series=10100
Ошибка при достижении max-select-series
max-select-series limit exceeded: (10101/10100)
SELECT mean(avg)
FROM "jmeter"
Оцениваем предел группировки по времени
Примерно 11-12 точек
select mean(avg)
from jmeter
wheretime>1656242940000000000andtime<1656242940000000000+10m
groupbytime(1m)
А на мониторе 1920 точек в ширину — больше пользователь не увидит
Ограничиваем max-select-buckets
[coordinator]
# The maxium number of group by # time bucket a SELECT can create.# A value of zero will max the maximum # number of buckets unlimited.# max-select-buckets = 0max-select-buckets=1920
Ошибка при достижении max-select-buckets
select mean(avg)
from jmeter
wheretime>1656242940000000000andtime<1656242940000000000+10m
groupbytime(1ms)
[data]
# The type of shard index to use for new shards. # The default is an in-memory index that is# recreated at startup. # A value of "tsi1" will use a disk based index # that supports higher cardinality datasets.index-version="tsi1"
Логирование узких мест c log-queries-after
[coordinator]
# The time threshold when a query will be # logged as a slow query. # This limit can be set to help# discover slow or resource intensive queries. # Setting the value to 0 disables the slow query logging.log-queries-after="2s"
8. Конфигурирование сервера InfluxDB
Ограничиваем max-concurrent-queries
Ограничиваем max_conns в nginx upstream
Ограничиваем query-timeout
Ограничиваем max-select-series
Ограничиваем max-select-buckets
Изменение типа индекса с inmem на tsi1
Логирование узких мест c log-queries-after
Не ускоряет, но повышает стабильность
Профилирование досок Grafana, анализ запросов к InfluxDB
9. Анализ логов InfluxDB
[coordinator]
# The time threshold when a query will be logged as a slow query. # This limit can be set to help# discover slow or resource intensive queries. # Setting the value to 0 disables the slow query logging.log-queries-after="2s"
Detected slow query:
SELECT top(avg, 3) FROM jmeter
WHERE time >= now() - 1d AND time <= now()
GROUP BY time(1m), application, transaction, statut
(qid: 27, database: jmeter10000, threshold: 2s)
10. Замер длительности ответа на запрос из Grafana в InfluxDB: Access Browser, Method POST
Выявляем медленный и частый запрос
Среднее время отклика за тест
SELECT mean(avg)
FROM jmeter
WHERE
statut ='ok'ANDtime> now()-10d ANDtime< now()
GROUPBY testId, time(1d)
11. Подготовка данных для ответа с помощью Continuous Queries
CREATE
CONTINUOUS QUERY cq_mean_avg_query_1d ON jmeter10000
RESAMPLE EVERY10m FOR1d
BEGINSELECT mean(avg) AS avg
INTO jmeter10000."archive".jmeter_1d
FROM jmeter10000."autogen".jmeter
GROUPBY testId, time(1d, 0s)
END;
Запрос становится быстрее
SELECTlast(avg)
FROM "archive".jmeter_1d
WHEREtime> now()-10d ANDtime< now()
GROUPBY testId, time(1d)
--------------------------------------------------------------------------------SELECT mean(avg)
FROM jmeter
WHERE statut ='ok'ANDtime> now()-10d ANDtime< now()
GROUPBY testId, time(1d);
Сокращайте количество Continuous Queries
CQ не кешируются с nginx
Не нужно делать слишком много CQ
Не нужно делать CQ, которые работают с большими shard'ами (год — много, достаточно дня)
Путь к Continuous Queries
Анализ логов InfluxDB
log-queries-after = "2s"
Замер длительности ответа на запрос из Grafana в InfluxDB
Grafana Datasource: Access Browser, Method POST + WebConsole
Подготовка данных для ответа с помощью Continuous Queries
RESAMPLE EVERY10m FOR1d
Ускорение записи в InfluxDB со стороны источника метрик и альтернативы
Одновременная запись метрик может тормозить
Оптимизируем запись в InfluxDB c Telegraf и MQ
12. Смена БД InfluxDB v1.8, InfluxDB v2, VictoriaMetrics или ClickHouse
InfluxDB v2 использует быстрый движок
VictoriaMetrics кеширует ответы и жмет данные
ClickHouse быстр (при наличии памяти) и удобен
Разгонный потенциал InfluxDB v1.8 огромен
Содержание
Когда оптимизация InfluxDB важна
Разделение данных на разные базы и серверы InfluxDB
«Архивирование» базы InfluxDB в Grafana
Сокращение фильтров по тегам в Grafana
Сокращение метрик из JMeter, Gatling, ...
Кеширование ответов от InfluxDB с nginx
Мониторинг производительности InfluxDB
Конфигурирование сервера InfluxDB
Анализ логов InfluxDB
Замер длительности ответа на запрос из Grafana в InfluxDB
Подготовка данных для ответа с помощью Continuous Queries
Смена БД InfluxDB v1.8, InfluxDB v2, VictoriaMetrics или ClickHouse
Делите, кешируйте, ускоряйте!
https://github.com/polarnik/influxdb-bench
Ускорение InfluxDB, Смирнов Вячеслав, @qa_load
Feedback :
Повышаю качество более десяти лет. Занимаюсь системой дистанционного банковского обслуживания юридических лиц. Основной профиль моей работы — тестирование производительности. Развиваю сообщество инженеров по тестированию производительности, помогая коллегам в telegram чате «QA — Load & Performance».