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

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

Согласны с тем, что 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, и, если им не следовать, он конечно будет странно себя вести под серьёзной нагрузкой. Как и любая другая система.
s/прекращается в боль/превращается в боль/
Спасибо, исправил!
Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.