Как стать автором
Обновить

Комментарии 17

Согласны с тем, что Reactive-фреймворки хорошо подходят для программирования интерфейсов в web и мобильных приложениях, и что они просто прекрасны везде, где есть взаимодействие с человеком через UI. Но не на бэкенде! Там это прекращается в боль.


Отнюдь не верное утверждение. Существует множество сетевых решений, построенных на базе реактивного стека, превышающих нагрузку и в 50 тыс. активных соединений. Конечно, порог вхождения куда выше, чем в императивном программировании. А не разобравшись с технологией, и пробовать даже не стоит. Про любую технологию, в неумелых руках, можно сказать, что она для чего-то не подходит.
Спасибо за комментарий. Охотно верю в то, что существует множество решений на базе реактивного стека, и они хорошо масштабируются, и держат большое количество соединений и запросов.

Но есть несколько нюансов:
  • как уже вы сказали, порог вхождения в такие технологии выше, и чтобы овладеть ими на уровне, необходимом для построения надёжных решений, нужно немало ресурсов (время, деньги, люди);
  • насколько я понимаю, реактивный стек более требователен к ресурсам, там гораздо больше слоёв абстракций, и не всегда это хорошо работает, а разбираться с этим тяжеловато;
  • в статье мы честно признаёмся, что у нас нет хороших компетенций по реактивному стеку для backend-разработки, и для нас это боль :)
Вторая проблема — это редкие, но внезапные потери сообщений из Redis. Опыт эксплуатации показал, что Redis растеряйка тот еще: его pub-sub механизм не самый надежный, так как клиент, подписываясь на каналы в Redis’е и получая из них сообщения, не отсылает назад никаких подтверждений, а Redis их не повторяет, что порой приводит к потерям.

тут ничего внезапного нет, redis pub-sub всегда был at-most-once системой :) для гарантий at-least-once в редисе есть стримы, на которых тоже можно организовать pub-sub взаимодействие.
В общем-то да, в потерях сообщений от Redis нет особой внезапности. Но все равно неприятно :)
Про стримы — спасибо за наводку, просмотрел по диагонали. На досуге внимательнее почитаю :)

Немного странно что редис оказался крайним, при том принятые решения кажутся крайни необдуманными. Хранить в редисе связанные данные и пытаться строить там индексы, вообще кто придумал эти rdbms и зачем там “r” в начале…
Если вам нужна гарантированная доставка зачем ругать редис за то что он ее не гарантирует?
Вдумываться в текст я перестал когда вы решили переписать Java/Kotlin сервис на питон для решения проблем с памятью и производительностью…
Субъективно, каждый инструмент создан для решения определенной проблемы, в данном случае если выкинуть Rx из ЦУП (можно даже Котлин и использовать просто Java), использовать обычную rdbms (Postgres, MySQL) и ходить в ЦУП с ретрансляторов через простой http подняв 1-2 дополнительные ноды ЦУПа для того чтобы избежать потери при деплоях/крашах, дало бы вам стабильное и производительное решение для поддержки которого не сложно найти людей с экспертизой.

Интересный комментарий :)

Постараюсь ответить по пунктам.
вообще кто придумал эти rdbms и зачем там “r” в начале…

Ну собственно мы и взяли Tarantool для этого, так как он позволяет хранить в том числе и связанные данные :) Redis — да, не очень продуманное решение было, это был скорее прототип. Сами понимаете, прототипы иногда лепятся на скорую руку без особых раздумий :)
Если вам нужна гарантированная доставка зачем ругать редис за то что он ее не гарантирует?

Ругани в сторону Redis особо нет, просто констатировали факт, что его pubsub — не самое надежное решение. В комментариях выше указали на redis streams — интересная вещь, действительно можно было бы её использовать, но это не сильно облегчило бы нам жизнь.
Вдумываться в текст я перестал когда вы решили переписать Java/Kotlin сервис на питон для решения проблем с памятью и производительностью…

На моей практике именно Java имела проблемы с утечками и требовательностью к памяти, в то время как python в этом плане проявил себя лучше: работая с python, реже приходилось вспоминать о памяти и сборщике мусора. А работая с Java-стеком, мне постоянно приходилось держать в голове эти проблемы. Да и многие коллеги ворчали на Java, не только я.

По поводу производительности здесь надо отметить, что приложение сетевое, его задача — принять пакет из одного сокета, что-то с ним сделать, бросить пакет в другой сокет и переключиться на обработку следующего пакета. И производительности python + asyncio хватило бы за глаза и за уши.

Субъективно, каждый инструмент создан для решения определенной проблемы

Безусловно.

в данном случае если выкинуть Rx из ЦУП (можно даже Котлин и использовать просто Java), использовать обычную rdbms (Postgres, MySQL) и ходить в ЦУП с ретрансляторов через простой http подняв 1-2 дополнительные ноды ЦУПа для того чтобы избежать потери при деплоях/крашах, дало бы вам стабильное и производительное решение для поддержки которого не сложно найти людей с экспертизой.


Вы упустили из виду тот момент, что у нас не было тогда хороших компетенций по Java/Kotlin для backend-разработки, да и не очень мы этот стек любим. С, Lua и Python нам гораздо ближе :)

подняв 1-2 дополнительные ноды ЦУПа

Здесь вот какой нюанс: ЦУП общается с MQTT-брокером, и такова специфика, что он должен держать одно соединение с ним, создавать некоторый постоянный набор подписок, и он же должен отслеживать состояние устройств, которые присылают свою телеметрию в ответ на какие-то команды, и в зависимости от их состояния нужно принимать какие-то решения: посылать куда-то что-то или нет, выдать ошибку.

Если же поднимать несколько узлов ЦУПа, то надо решить следующие вопросы:
  • репликация состояния, устойчивая к помехам;
  • определение того, кто будет мастером, а кто репликой, чтобы соединение с mqtt-держал только мастер;
  • механизм failover, чтобы реплика смогла подхватить эстафету при падении мастера.


Уже того, что перечислено, хватит чтобы глубоко задуматься. На Java есть разные решения, но они местами сложные, с ними довольно муторно разбираться. По той же причине отказались от Python/asyncio, так как по факту, мы бы получили точно такой же черный ящик, который сложно будет исследовать в случае каких-то проблем, и для которого надо всё вот это реализовывать вручную.

В случае с Тарантулом это проще: в нем базовые механизмы для работы с репликацией и failover уже есть. Еще немаловажную роль сыграло то, что к нему можно подключиться в консоли и поисследовать состояние системы. Это вообще жирный плюс :)

использовать обычную rdbms (Postgres, MySQL)
конечно можно взять классическую RDBMS и попытаться на этом что-то построить, но… Проблема опять же, с увеличением количества устройств растёт и трафик, телеметрии приборы посылают больше и весь этот трафик надо уметь обрабатывать очень быстро. И здесь логичнее держать все данные в памяти, с подушкой безопасности в виде WAL и снимков состояний (snapshots).
к нему можно подключиться в консоли и поисследовать состояние системы
Одобрил ваш комментарий, но позвольте полюбопытствовать — что не так? Какую мысль вы хотели донести?
Извините, предыдущий комментарий отправился сам.
Я осторожно пытался донести мысль, что, не умаляя преимуществ Tarantool, перечислены недостатки не самого Redis, а опыта работы с ним. У них на сайте достаточно подробно изложены основы Best Practices, и, если им не следовать, он конечно будет странно себя вести под серьёзной нагрузкой. Как и любая другая система.
Понял, спасибо!

Согласен с тем, что это больше выглядит как недостаток опыта работы с Redis, и недостаток знаний по лучшим практикам. Тем не менее приведу аргумент, который не совсем технический, он больше субъективно-философский.

При сравнении Tarantool и Redis существенным фактором является простота использования. Redis поддерживает широкий спектр различных структур данных и функций, связанных с ними, но, это требует изучения, набивания шишек и нарабатывания какой никакой практики. И это несмотря на первоначальную простоту — установил и пошёл использовать GET'ы и SET'ы (а там и другие структуры и функции), всё вроде бы просто.

С Tarantool приходится немного повозиться в самом начале, но затем его использование становится простым: базис, необходимый для изучения и который пригоден для выполнения 90% задач, довольно небольшой. И имея этот базис, можно повторить практически всё то, что есть в Redis, при этом реализуя это, ты получаешь реальное понимание того, как работает та или иная функция или структура данных. В этом плане Tarantool является более низкоуровневым инструментом, но в то же время весьма эффективным и простым.

И наконец, на базе Redis сложнее строить in-memory computing решения, когда тебе необходимо знать и состояние данных (приходится лезть отдельно в сам Redis через redis-cli), так и состояние программы. Причем это зачастую требуется выяснять на production серверах, а с этим проблематично практически во всех системах программирования, кроме Erlang и Tarantool. Там (в Erlang и Tarantool) можно подключиться к экземпляру сервиса и повыполнять код, с помощью которого можно инспектировать состояние системы.

Подытожу.

Каждый инструмент необходимо знать хорошо, важно уметь с ним работать. Но при выборе инструмента следует учитывать еще и субъективные ощущения от работы с ним, к чему склоняешься больше, что приятнее и что интереснее. Для меня Redis всё же был и остаётся просто навороченным кешом, в котором несколько затруднительно сделать что-то нестандартное, в то время как Tarantool предоставляет мне необходимую свободу действий, так как он позволяет реализовывать всё, что нужно, пусть даже если на это потребуется время.

Надеюсь, мне удалось прояснить свою позицию в этом вопросе :)
Извините, не соглашусь, но не для поспорить или навязать, а для прояснить истину, поскольку для меня это довольно актуальная тема. Чуть менее года назад пришлось покопаться во всех высокоскоростных базах (Redis, Tarantool, Aerospike, VoltDB) для «горячей зоны» собственного проекта, я до сих пор не уверен в правильности выбора и пока фарш ещё можно провернуть назад.
Мне кажется, ровно наоборот: Redis гораздо ближе к «продолжению кодовой базы» на уровне примитивов, чем остальные, ощущается, как если-бы вы использовали модули кэша на уровне приложения.
Из серьёзных плюсов:
на нём (частично) работает очень много супер высоконагруженных систем, включая Твиттер и Инстаграмм, и они охотно делились своими конфигурациями.
По нему очень много информации и уже решённых проблем на SO.
У него есть очень продвинутые дополнительные модули.
Совсем не обязательно работать через cli, прокидываете через туннель соединение с продакшен и используете RedisInsight.
Просто сравните размеры сообществ и количество каналов связи с профессионалами.
Я ещё штук 10 плюсов могу накидать, но я не уверен, что оно вам нужно, раз вы уже с него съехали на Тарантул. Да и остальные я пробовал не так основательно, в основном по литературе, докладам и бенчмаркам, без реального жамканья руками и сравнений по схожим нагрузкам.
Согласен с тем, что позиция Redis'а на рынке сильная, но это уже больше из области брендинга и маркетинга: большая поддержка сообщества, много наработок, крупные компании международного уровня. Но с технической стороной это соотносится постольку-поскольку.

Tarantool'у тоже есть что сказать :)
Его сообщество не такое конечно большое, но оно развивается и растёт. Чем больше людей интересуется и пробует, тем больше всяких разных вопросов возникает, больше исправлений, больше отдачи, больше наработок.
По поводу поддержки со стороны компаний — Mail.ru ведь большая компания, и она поддерживает этот продукт и использует :) И Tarantool используется не только в mail.ru.

Мне кажется, ровно наоборот: Redis гораздо ближе к «продолжению кодовой базы» на уровне примитивов, чем остальные, ощущается, как если-бы вы использовали модули кэша на уровне приложения.


Если требуется построить систему на выбранном языке (Go/Pyton/Java/whatever) и использовать Redis как полностью внешний агент, то наверное да, с учётом поддержки его в разных ЯП, это вполне обосновано, действительно можно использовать как модуль для кеширования без особых заморочек.

Но в нашем случае у нас построена система, где вычисления производятся рядом с данными, нет издержек на обмен по сети между сервисом и хранилищем, и это не совсем укладывается в схему, где in-memory система используется как незаметный кеш. Tarantool в этом случае подходит больше. Более того, модель данных в Tarantool близка к реляционной, и там есть возможность строить индексы по значениям, и это сильно удобнее, чем городить массу ключей и структур в Redis, чтобы связать все данные (о чём и написано было в статье). А нам приходится связывать данные между собой, их структура не совсем простая :)

То есть, здесь я акцентирую внимание ещё на том, что мы используем Tarantool как сервер приложений с in-memory БД, а не чисто как внешнее хранилище в памяти.

Совсем не обязательно работать через cli, прокидываете через туннель соединение с продакшен и используете RedisInsight.

Здесь я имел в виду общее удобство работы с системой. Совершенно неважно, GUI или CLI это, важен другой аспект: возможность отладки и залезания прямо в процесс самого сервиса, и всё это в одной связке — и данные и код. То есть, цикл разработки и отладки такой получается: «вижу проблему» -> «подключаюсь к процессу сервиса» -> «смотрю состояние кода, выполняю некоторый Lua-код прямо в консоли, смотрю данные» -> «нахожу проблемное место, исправляю данные и состояние, пробую» -> «оцениваю результат» -> «заношу исправление в репозиторий с кодом». Как то так получается. Даже если мы берём RedisInsight, то во первых, мы вынуждены будем прыгать между RedisInsight, отладчиком и чем то там ещё; а во вторых — нет возможности «исправить» проблему тут же, на месте, надо вносить изменения в код, потом пересобирать, перезапускать, и так далее. Это не для production-использования, для production весь доступ к данным в режиме отладки конечно же readonly, но для отладки кода при разработке это очень удобно.

И напоследок, хотелось бы поинтересоваться…
я до сих пор не уверен в правильности выбора и пока фарш ещё можно провернуть назад.

А какими критериями при выборе in-memory решения вы руководствуетесь?
А какими критериями при выборе in-memory решения вы руководствуетесь?

В порядке убывания важности:

  1. Мнением адвайзера — главного DB архитектора нескольких огромных высоконагруженныз систем (знание тонкостей и валидность прогнозов достигается только многими годами узкой специализации)
  2. Быстродействием (это всего лишь реплика горячей части данных, консистентность важна меньше)
  3. Горизонтальной расширяемостью (решается по разному)
  4. Распространённостью применения (и, соответственно, массой готовых решений)
  5. Базой типовых «лучших практик» для каждой задачи
  6. Доступом к профессионалам с многолетним опытом (у остальных по 2 канала связи и спецов на рынке, ну типа нет вообще)
  7. Отсутствием статуса монополиста у производителя и его возможности с этим играться

Было серьёзное искушение плюнуть на все соображения и использовать VoltDB, но я сварщик не настоящий для такого лихачества.
s/прекращается в боль/превращается в боль/
Спасибо, исправил!
Спасибо, подправил!
Зарегистрируйтесь на Хабре, чтобы оставить комментарий