Comments 42
Очень интересно. Но что-то мне говорит, что в реальном мире это не так радужно
Каков overhead предвычислений тысяч кверей, если мы не знаем, какие понадобятся?
ну все кунгфу и заключается в нахождении баланса и сдерживании роста количества этих "кверей", иначе да - разрастутся до тысяч. И там проблема уже не перформанс будет- а то что никто не знает обо всех этих сотнях кверей и их логике, и соответственно при требовании нового расчета вместо того чтобы понять что можно использовать уже имеющийся "квери", будут появлятся новые, дублирующие - что в итоге заканчивается все одинаково, ситуацией "проще это всё выкинуть и с нуля написать"
Но для online OLAP должно зайти
ну я не встречал еще ни одной online OLAP базы. Видимо не так-то это просто
Clickhouse позиционирует себя как OLAP)
а где там онлайн??? Что там есть сохраненные запросы которые сами обновляются в реал-тайме???? (Да и с аналитическими запросами там все очень плохо - хуже чем у любой класической субд), так что ни онлайна, ни олапа. Просто фактически быстрый кэш для уже рассчитанных витрин.
Так-то такой онлайн как тут описано - это только кафка-стримс
инкрементальный апдейт материализованых представлений. Существует в природе уже лет 20, и примерно столько же лет нормально не работает
вообще процес построения инкрементального обновления витрин давно известен, прост и используется чуть больше чем везде (где это нужно). Все эти запросы хранятся уже расчитанные в таблицах, а для обновления надо просто выбрать ключ обновления, например день, кастомер, продукт и т.д. и обновлять только изменившиеся данные (при изменениях в сорсах), что на порядки быстрее чем полный пересчет и в 99% случаев вполне рабочий вариант
А это своя СУБД или надстройка над существующей?
До боли напоминает "регистры" в 1С
Под каждый запрос храни Многа Многа. А где потоки в SQL, я так и не нашел.
Мне платят 19000$ в месяц за то что я первый начал шилить и внедрять стриминговые движки в РФ, в сложный сайтах у которых JOIN происходит на клиенте или partical join в api gateway - отклик повысился в разы, "скачки" сайтов при загрузки сведены к нулю, а продажи подросли в разы.
Стриминговые движки это будущие для больших данных. Всем советую начать изучать сейчас, это будущие. А все кто игнорирует это останутся просто "программистами".
А можно тогда чуть подробностей про самое главное, что в статье не упомянуто почему- то: это типа расширения материализованных вьюх, или вообще обновляются запросы которые сейчас в кэше? Как определяется какие запросы обновляемые, какие нет?
Потоковый SQL-движок обеспечивает, чтобы результаты SQL-запросов всегда оставались актуальны, и их не приходилось пересчитывать. Даже в тех случаях, когда меняются данные, на которых основан запрос.
Т.е. движок должен знать ВСЕ запросы которые ему придется выполнять?
А если агрегатная функция не дифференцируема по своему определению? Например, нам нужно не количество людей, а их медианный возраст.
Судя по документации, не поддерживается: https://docs.epsio.io/sql-support/built-in-functions/
Для того чтобы вычислять медиану есть и потоковые подходы, в том же кликхаусе они и применяются по умолчанию и это очень многих устраивает.
Для точного вычисления медианы я потоковых подходов не знаю. По ссылке речь о приблизительном вычислении. Для нормального распределения, при незначительной дисперсии и отсутствии сезонной составляющей, такой подход может быть приемлем. Но уже для логнормального распределения такой подход может давать существенные искажения.
Пример:
Да, всё так, но много кого такие данные утраивают
И у меня есть данные, где устраивает. Но так как такие данные, нередко, в тех же записях, но других колонках, где не устраивает - пользуемся ClickHouse. Который даже точную медиану считает очень быстро. За что его разработчикам премного благодарен )
Описание похоже на timescaledb
Почитал доки. И опыт говорит, что лучше это в проде не использовать. Почему так думаю: пару лет назад я руководил продуктом, где мы создали свой потоково-аггрегационный костыль, чтобы на лету считать аггрегаты над 15ТБ базой в постгресе, куда за день вставлялось 2 млрд строк. Работало не то, чтобы очевидно - при вызове data api на модификацию данных динамически генерировался огромный SQL запрос, который и вставлял сырые данные, и обновлял аггрегаты одной транзакцией. Понятно, что data api старались дергать большими батчами, и понятно, что ряд операторов (например, argmax) не реализовывали из-за страха перед вычислительной сложностью или объёмом состояния, ибо эта штуковина блокировала всю систему. Но, зато, работало, как часы.
Потом же, захотелось чего-то более гибкого. Чтобы и операторы можно было с O(N) сложностью внедрять, и, чтобы любой джун-говнокодер мог свой аггрегат написать и не увалить систему, когда там окажется O(N^2).
Так что, когда один умный чел посмотрел на все это, и сказал, мол, не страдайте херней, и берите debezium, то это выглядело, как священный грааль. Слить с него в кафку, а там уже, в параллель ставь хоть 100 аггрегаторов, каждый со своим хранилищем и в своём контейнере. И, главное, все это гарантированно консистентно (сливать в кафку с data api была плохая идея, ведь была вероятность, что из-за нештатной ситуации состояние кафки и бд рассинхронизируются).
Попробовали. На тестовой базе все круто. На проде под указанной выше нагрузкой debezium тупо не работает стабильно. Сколько девопсы не плясали с бубном, как мы не пытались его зашардировать и в много инстансов работать заставить. Поговорил с другими счастливыми пользователями - проблема не только у меня. А решение ведь куда более проверенное временем, чем этот стартапчик, основанный год назад.
Более того, ок, предположим, что они сотворили чудо, и научились парсить WAL стабильно. Чтобы не улететь по памяти, или не получить неконтролируемое отставание от риалтайма, надо вывести кучу ручек для обслуживающего девопса, чтобы он мог тонко это все настроить и, главное, задать стратегию работы с проблемными представлениями, ибо с их портфелем поддерживаемых операторов устроить комбинаторный взрыв очень легко. В доке как-то это все не просматривается (да и не пишется за один год)
Мне могут возразить, что я наваливаю кейсы серьёзного хайлоада, а это решение для тех, у кого сотня юзеров в день. Но прикол в том, что им эта приблуда и не нужна. Даже, если они уже выросли с того, чтобы дергать оперативную базу на аггрегации на каждый чих. И с делания этого на реплике выросли тоже, можно near real-time лить в clickhouse/Redshift, и дергать уже их. Да, не О(1), но грубая сила скоростных olap движков свое дело сделает. А вот, когда уже и этого не хватит, то привет все радости жизни из предыдущего абзаца
Работало не то, чтобы очевидно - при вызове data api на модификацию данных динамически генерировался огромный SQL запрос, который и вставлял сырые данные, и обновлял аггрегаты одной транзакцией.
А чем не устроил вариант с триггерами на таблицах для обновления этих агрегатов? Тоже было-бы одной транзакцией и выглядело-бы не слишком страшно.
Хороший вопрос. Не факт, что вспомню прямо все причины сейчас.
Но, кажется, основной причиной была моя личная непереносимость наличия исполняемого кода в БД. SQL запросы на 1000 строк норм, но вот наличие в БД исполняемой логики уже нет. Очень не люблю размазывание логики между репозиторием и БД. Да, оно синхронизируется на этапе миграции, но слишком много нюансов возникает. Команде было бы сложно продать мне наличие триггеров или хранимок;)
Кроме этого, там была масса плюшек уровня целостной системы. Например, data api после обработки батча получал в ответ скрипта итоговые значения всех обновленных аггрегатов, и сразу же плевался ими в кафку, что позволяло системе быть реактивной и масштабируемой. Или, там была очень интересная система управления дневными партициями, чтобы при удалении партиции не считать все заново, а лишь переагрегировать агрегаты дней. Можно было принудительно забутстрапить новый агрегат из аналитического хранилища. Кажется, ещё что-то было из приколов, которые требовали больше контроля наружу
Понятно, спасибо. С одной стороны согласен, помню когда-то давно работал с одним большим проектом, где вся бизнес логика была в хранимках, это было больно по многим причинам.
С другой стороны, агрегаты можно рассматривать не как бизнес-логику, а как денормализацию данных. То есть это все те-же данные, просто представленные в ином виде. В таком случае триггеры будут вполне оправданы, если не увлекаться и не тащить в них бизнес-логику. Ну и все также можно генерить запросы, которые будут и менять данные, и забирать данные из агрегатов все одним запросом.
рассчет агрегатов это и есть логика, а триггеры очень сложны для отладки. Ну и перформанс у них не ахти, батч режим-то не применишь, чтобы не каждый инсерт отрабатывать, а сразу большую пачку. Ну и триггеры с апдейтами - лучший способ получения дедлоков!
батч режим-то не применишь, чтобы не каждый инсерт отрабатывать, а сразу большую пачку
В postgresql AFTER STATEMENT триггеры
Примерчик в конце
https://www.postgresql.org/docs/current/plpgsql-trigger.html
даст большую фору логике в приложении
например,
SELECT count(*) FROM humans
. Обычному SQL-движку <...>
требовалось бы заново пересматривать все отдельные экземплярыhumans
при каждом выполнении такого запроса.
что-то мне кажется, что это неправда. Звёздные запросы по-идее должны сразу поле size у столбца забирать, а не пробегать по записям. Вот был бы там какой-нибудь DISTINCT, тогда б было понятно.
Есть ещё ksqldb https://ksqldb.io/. Однако опыт использования показал 3 вещи:
Иногда ты упираешься в тупик и дальше никак
Непонятно как это работает и будет ли работать быстро всегда. Вернее лично ты можешь разобраться, но если ты уволишься не факт, что твоя работа будет легко подтянута.
Некоторые вещи лучше сделать на атомарных счётчиках в Redis. А некоторые специальными движками в ClickHouse.
Не совсем понял. В начале где добавляли Еву к Адаму. Сперва удалили 1. Потом сказали что нужно к результату прибавить 1 и получили 2 человека. Вопрос если 1 удалили, где тогда содержалась удаленная единица чтобы к ней прибавить 1? Получилось, что мы к none прибавили 1 и получили 2 ?
Человек изобрел регистры накоплений 1С. Мои поздравления.
Как был создан потоковый SQL-движок