
Если использовать БД временных рядов (timeseries db, ) как основное хранилище для сайта со статистикой, то вместо решения задачи можно получить много головной боли. Я работаю над проектом, где используется такая база, и иногда InfluxDB, о которой пойдет речь, преподносила вообще неожиданные сюрпризы.
Shënim ligjor: приведенные проблемы относятся к версии InfluxDB 1.7.4.
Почему time series?
Проект заключается в отслеживании транзакций в различных блокчейнах и отображении статистики. Конкретно — смотрим эмиссию и сжигание стэйбл-коинов (). На основе этих транзакций нужно строить графики и показывать сводные таблицы.
При анализе транзакций пришла идея: использовать базу данных временных рядов InfluxDB как основное хранилище. Транзакции являются точками во времени и в модель временного ряда они хорошо вписываются.
Еще функции агрегации выглядели весьма удобно — для обработки графиков с большим периодом идеально подходят. Пользователю нужен график за год, а в базе лежит набор данных с таймфреймом в пять минут. Все сто тысяч точек ему отправлять бессмысленно — кроме долгой обработки, они и на экране не поместятся. Можно написать свою реализацию увеличения таймфрейма, либо воспользоваться встроенными в Influx функциями агрегации. С их помощью можно сгруппировать данные по дням и отправить нужные 365 точек.
Немного смущало то, что обычно такие базы используют с целью сбора метрик. Мониторинг серверов, iot-устройства, все, с чего «льются» миллионы точек вида: [<время> — <значение метрики>]. Но если база хорошо работает с большим потоком данных, то почему маленький объем должен вызывать проблемы? С этой мыслью взяли InfluxDB в работу.
Что еще удобного в InfluxDB
Кроме упомянутых функций агрегации есть еще одна замечательная вещь — continuous queries (). Это встроенный в БД планировщик, который может обрабатывать данные по расписанию. Например, можно каждые 24 часа группировать все записи за день, считать среднее и записывать одну новую точку в другую таблицу без написания собственных велосипедов.
Po ashtu ka retention policies () — настройка удаления данных после какого-то периода. Полезно, когда например, нужно хранить нагрузку на CPU за неделю с измерениями раз в секунду, а на дистанции в пару месяцев такая точность не нужна. В такой ситуации можно сделать так:
- создать continuous query для агрегации данных в другую таблицу;
- для первой таблицы определить политику удаления метрик, которые старше той самой недели.
И Influx будет самостоятельно уменьшать размер данных и удалять ненужное.
О хранимых данных
Данных хранится не много: около 70 тысяч транзакций и еще один миллион точек с рыночной информацией. Добавление новых записей — не более 3000 точек в сутки. Также есть метрики по сайту, но там данных мало и по retention policy они хранятся не больше месяца.
Problemet
В процессе разработки и последующего тестирования сервиса возникали все более и более критичные проблемы при эксплуатации InfluxDB.
1. Удаление данных
Есть серия данных с транзакциями:
SELECT time, amount, block, symbol FROM transactions WHERE symbol='USDT'Rezultati:

Посылаю команду на удаление данных:
DELETE FROM transactions WHERE symbol=’USDT’Далее делаю запрос на получение уже удаленных данных. И Influx вместо пустого ответа возвращает часть данных, которые должны быть удалены.
Пробую удалить таблицу целиком:
DROP MEASUREMENT transactionsПроверяю удаление таблицы:
SHOW MEASUREMENTSТаблицу в списке не наблюдаю, но новый запрос данных все еще возвращает тот же набор транзакций.
Проблема возникла у меня лишь один раз, так как кейс с удалением — единичный случай. Но такое поведение базы явно не вписывается в рамки «корректной» работы. Позже на github нашел открытый почти годовой давности на эту тему.
В результате, помогло удаление и последующее восстановление всей базы.
2. Числа с плавающей точкой
Математические вычисления при использовании встроенных в InfluxDB функций дают ошибки точности. Не то, чтобы это было чем-то необычным, но неприятно.
В моем случае данные имеют финансовую составляющую и обрабатывать их хотелось бы с высокой точностью. Из-за этого в планах отказаться от continuous queries.
3. Continuous queries нельзя адаптировать к разным временным зонам
На сервисе есть таблица с дневной статистикой по транзакциям. Для каждого дня нужно сгруппировать все транзакции за эти сутки. Но день у каждого пользователя будет начинаться в разное время, следовательно и набор транзакций разный. По UTC есть сдвига, для которых нужно агрегировать данные.
Në InfluxDB, kur gruponi sipas kohës, mund të specifikoni gjithashtu një zhvendosje, për shembull për kohën e Moskës (UTC+3):
SELECT MEAN("supply") FROM transactions GROUP BY symbol, time(1d, 3h) fill(previous)Por rezultati i kërkesës do të jetë i pasaktë. Për një arsye, të dhënat e grupuara sipas ditëve do të fillojnë madje në vitin 1677 (InfluxDB zyrtarisht mbështet një interval kohor nga ky vit):

Për të anashkaluar këtë problem, shërbimi u kalua përkohësisht në UTC+0.
4. Performanca
Në internet ka shumë benchmark-e që krahasojnë InfluxDB me të tjera BD. Në fillim shiheshin si materiale marketingu, por tani mendoj se ka një përqindje të së vërtetës në to.
Do të tregoj rastin tim.
Shërbimi ofron një metodë API që kthen statistikën për 24 orët e fundit. Gjatë llogaritjeve, metoda bën tre kërkesa në bazë me këto pyetje:
SELECT * FROM coins_info WHERE time <= NOW() GROUP BY symbol ORDER BY time DESC LIMIT 1SELECT * FROM dominance_info ORDER BY time DESC LIMIT 1SELECT * FROM transactions WHERE time >= NOW() - 24h ORDER BY time DESCShpjegimi:
- Në kërkesën e parë, marim pikat më të fundit për çdo monedhë me të dhëna rreth tregut. Tetë pika për tetë monedha në rastin tim.
- Kërkesa e dytë merr një pikë më të re.
- E treta kërkon listën e transaksioneve për 24 orët e fundit, mund të ketë disa qindra.
Dua të sqaroj se në InfluxDB automatikisht ndërtohet një indeks sipas etiketave dhe kohës, i cili shpejton kërkesat. Në kërkesën e parë symbol — është një etiketë.
Kam realizuar një test stresi për këtë metodë API. Për 25 RPS, serveri tregonte ngarkesë të plotë të gjashtë CPU-ve:

Në të njëjtën kohë, procesi NodeJs nuk e ngarkonte fare.
Shpejtësia e ekzekutimit filloi të degradojë që në 7-10 RPS: nëse një klient mund të merrte një përgjigje për 200 ms, atëherë 10 klientë duhej të prisnin një sekondë. 25 RPS – është kufiri, ku stabiliteti vuante, klientët merrnin 500 gabime.
Me një performancë të tillë, është e pamundur të përdorim Influx në projektin tonë. Më shumë se kaq: në një projekt, ku monitorimi duhet të demonstrohet për shumë klientë – mund të shfaqen probleme të ngjashme dhe serveri i matjeve do të mbingarkohet.
Përfundim
Mësimi më i rëndësishëm nga kjo përvojë është se nuk duhet të marrim në projekt një teknologji të panjohur pa një analizë të mjaftueshme. Një shqyrtim i thjeshtë i bileta të hapura në github mund të kishte ofruar informacione për të mos marrë InfluxDB si një depo të dhënash kryesore.
InfluxDB duhet të kishte përmbushur detyrat e projektit tim, por siç e tregoi praktika, kjo BD nuk përmbush nevojat dhe ka shumë probleme.
Në depozitën e projektit tashmë është e mundur të gjeni versionin 2.0.0-beta, shpresoj që në versionin e dytë do të ketë përmirësime të rëndësishme. Ndërkohë, do të shkoj të studioj dokumentacionin e TimescaleDB.
Burimi: habr.com
