Якщо використовувати БД часових рядів (timeseries db,
відмова: наведені проблеми стосуються версії InfluxDB 1.7.4.
Чому time series?
Проект полягає у відстеженні транзакцій у різних блокчейнах та відображенні статистики. Саме - дивимося емісію і спалювання стейбл-коїнів (
Під час аналізу транзакцій прийшла ідея: використовувати базу даних тимчасових рядів InfluxDB як основне сховище. Транзакції є точками у часі і модель тимчасового ряду вони добре вписуються.
Ще функції агрегації виглядали дуже зручно — для обробки графіків із великим періодом ідеально підходять. Користувачеві потрібен графік протягом року, а базі лежить набір даних із таймфреймом п'ять хвилин. Усі сто тисяч точок йому відправляти безглуздо — окрім довгої обробки, вони й на екрані не помістяться. Можна написати свою реалізацію збільшення таймфрейму або скористатися вбудованими в Influx функціями агрегації. З їх допомогою можна згрупувати дані по днях і надіслати потрібні 365 пікселів.
Трохи бентежило те, що зазвичай такі бази використовують із метою збирання метрик. Моніторинг серверів, iot-пристрою, все, з чого "ллються" мільйони точок виду: [<час> - <значення метрики>]. Але якщо база добре працює з великим потоком даних, то чому маленький обсяг має викликати проблеми? З цією думкою взяли InfluxDB у роботу.
Що ще зручного в InfluxDB
Окрім згаданих функцій агрегації є ще одна чудова річ. безперервні запити (
Також є політики утримання (
- створити continuous query для агрегації даних до іншої таблиці;
- для першої таблиці визначити політику видалення метрик, які старші за той самий тиждень.
І Influx самостійно зменшуватиме розмір даних і видалятиме непотрібне.
Про збережені дані
Даних зберігається небагато: близько 70 тисяч транзакцій та ще один мільйон крапок із ринковою інформацією. Додавання нових записів – не більше 3000 пікселів на добу. Також є метрики по сайту, але там даних мало, і по retention policy вони зберігаються не більше місяця.
Проблеми
У процесі розробки та подальшого тестування сервісу виникали все більш критичні проблеми при експлуатації InfluxDB.
1. Видалення даних
Є серія даних із транзакціями:
SELECT time, amount, block, symbol FROM transactions WHERE symbol='USDT'
Результат:
Надсилаю команду на видалення даних:
DELETE FROM transactions WHERE symbol=’USDT’
Далі роблю запит на отримання віддалених даних. І Influx замість порожньої відповіді повертає частину даних, які мають бути видалені.
Пробую видалити таблицю повністю:
DROP MEASUREMENT transactions
Перевіряю видалення таблиці:
SHOW MEASUREMENTS
Таблицю у списку не спостерігаю, але новий запит даних все ще повертає той самий набір транзакцій.
Проблема виникла у мене лише один раз, тому що кейс із видаленням — поодинокий випадок. Але така поведінка бази не вписується в рамки «коректної» роботи. Пізніше на github знайшов відкритий
В результаті, допомогло видалення та подальше відновлення всієї бази.
2. Числа з плаваючою точкою
Математичні обчислення під час використання вбудованих у InfluxDB функцій дають помилки точності. Не те щоб це було чимось незвичайним, але неприємно.
У моєму випадку дані мають фінансову складову та обробляти їх хотілося б із високою точністю. Через це у планах відмовитись від continuous queries.
3. Continuous queries не можна адаптувати до різних часових зон
На сервісі є таблиця з денною статистикою з транзакцій. Для кожного дня потрібно згрупувати усі транзакції за цю добу. Але день у кожного користувача буде починатися в різний час, отже, і набір транзакцій різний. За UTC є
У InfluxDB при групуванні за часом можна додатково вказати зсув, наприклад, для московського часу (UTC+3):
SELECT MEAN("supply") FROM transactions GROUP BY symbol, time(1d, 3h) fill(previous)
Але результат запиту буде некоректним. З якоїсь причини згруповані по днях дані будуть починатися аж у 1677 (InfluxDB офіційно підтримує тимчасовий проміжок від цього року):
Для обходу цієї проблеми тимчасово переклали сервіс на UTC+0.
4. Продуктивність
В інтернеті є багато бенчмарків із порівняннями InfluxDB та інших БД. При першому ознайомленні вони виглядали маркетинговими матеріалами, але зараз вважаю, що частка правди у них є.
Розповім свій кейс.
Сервіс надає метод API, який повертає статистику за останню добу. При розрахунках метод запитує базу тричі з такими запитами:
SELECT * FROM coins_info WHERE time <= NOW() GROUP BY symbol ORDER BY time DESC LIMIT 1
SELECT * FROM dominance_info ORDER BY time DESC LIMIT 1
SELECT * FROM transactions WHERE time >= NOW() - 24h ORDER BY time DESC
пояснення:
- У першому запиті отримуємо останні точки для кожної монети з даними ринку. Вісім точок для восьми монет у моєму випадку.
- Другий запит отримує одну нову точку.
- Третій запитує список транзакцій за останню добу, їх може бути кілька сотень.
Уточню, що в InfluxDB за тегами та часом автоматично будується індекс, який прискорює запити. У першому запиті символ - Це тег.
Я провів стрес-тест для цього API. Для 25 RPS сервер демонстрував повне завантаження шести CPU:
При цьому процес NodeJs зовсім не давав навантаження.
Швидкість виконання деградувала вже на 7-10 RPS: якщо один клієнт міг отримати відповідь за 200 мс, то 10 клієнтів мали чекати по секунді. 25 RPS — межа, з якою страждала стабільність, клієнтам поверталися 500 помилок.
З такою продуктивністю використовувати Influx у нашому проекті неможливо. Більше того: у проекті, де моніторинг потрібно демонструвати безлічі клієнтів, можуть з'явитися схожі проблеми і сервер метрик буде перевантажений.
Висновок
Найголовніший висновок з набутого досвіду — не можна брати до проекту невідому технологію без достатнього аналізу. Простий скринінг відкритих тикетів на github міг дати інформацію, щоб не брати InfluxDB як основне сховище даних.
InfluxDB мала добре підійти під завдання мого проекту, але як показала практика, ця БД не відповідає потребам і багато косячить.
У репозиторії проекту вже можна знайти версію 2.0.0-beta, залишається сподіватися, що у другій версії будуть значні покращення. А я поки що піду вивчати документацію TimescaleDB.
Джерело: habr.com