All streams
Search
Write a publication
Pull to refresh
20
0
Иван Банников @bit_10

Разработчик

Send message

Интересное наблюдение.

Я сперва подумал, как же тогда находить правильные балансы? Вроде как противоречие: если на определённом уровне абстракции хорошо, когда количество связей между компонентами внутри очерченных областей большое, а количество связей между областями - малое, то на другом уровне (увеличивая или уменьшая) - всё может меняться на противоположное. Что делать?

Но потом я пришёл к такой мысли. Выделим, к примеру, уровни классов, компонентов и сервисов. Тогда: внутри компонента его внутренние классы тесно общаются между собой, но среди этих классов должны быть еще особые, пограничные классы, которые общаются с внешним (с точки зрения компонента) миром. Их то число и должно быть минимальным.

На уровне сервисов то же самое: связи между внутренними компонентами сервиса должны быть плотными, но при этом, сами сервисы должны общаться между собой только через свои пограничные компоненты.

Как будто получается, что принципы связанности и прочности (опираясь на приведённое в статье соглашение по терминам) никак не меняются в зависимости от уровня абстракции или компонентизации, тут важно не приравнивать связи уровня X связям уровня X-1 или X+1 :) Тогда никаких противоречий при смене уровней.

Но наблюдение интересное, с точки зрения анализа связей, если рассматривать всё, начиная с некоторого уровня.

Как то так я понял статью :)

Здравствуйте!

Отвечаю по пунктам :)

  1. Для важных топиков - QoS = 1, для части топиков QoS = 0.

  2. На тот момент кластеризация EMQX не имела ни малейшего смысла, так как количество устройств было небольшим. Кластеризовать его ради того, чтобы он выдерживал всплески подключений - дорого (машины денег стоят).

  3. На тех версиях, что были на тот момент, эти правила работали довольно плохо. Да и потом, проблема не в наплыве лишних клиентов, а в том, что они разом набрасывались и делали массовые подписки. Enterprise же, как упоминалось в статье, стоил тогда как космолёт.

По моему мнению, на текущий момент ёмкость небольшая. В будущем, возможно, будет больше.

Попробую порассуждать (но не факт, что получится :)).

Для того, чтобы на автономные системы был хороший спрос, нужно много разных вещей: стандартизация протоколов, чтобы можно было в одну систему объединять приборы от разных производителей силами простых пользователей; стандартизация серверного и мобильного ПО (разработчики мобильных и серверных приложений просто сосредотачиваются на том, чтобы их приложение могло работать со стандартизованной системой умного дома); производство дешёвых электронных комплектующих (а чтобы они были дешёвые, они должны быть массовыми), а также помимо всего этого, вся эта продукция должна быть простой и понятной обычному пользователю (ему не хочется знать про mqtt и прочее, он и про Bluetooth то знает, что это просто такой вид связи для приборов и телефонов), должны быть наработаны опыт, документация. И наконец, общество должно дойти до того уровня потребностей, когда ему понадобится прямо массово всё вот это вот, неважно, под влиянием рекламы или под влиянием каких-то других тенденций.

По поводу стандартизации протоколов подвижки есть, но чтобы это набрало полную силу - нужно время.

Было одно интересное решение - объединить центры умного дома (шлюзы, концентраторы и прочее) с WiFi-роутерами, но тут производители WiFi-роутеров задали резонный вопрос: а другие приборы от других производителей могут быть подключены? То есть, опять всё сводится к стандартизации.

А ныне существующие платформы будут оказывать сопротивление децентрализации, поскольку они зарабатывают на пользователях или производителях умной техники, поскольку это наиболее мощный источник доходов на данный момент.

К примеру, производитель умной техники создаёт свою платформу, прошивки для железок, серверную часть и прочие обвязки. Как это всё поддерживать, обслуживать, если на это требуются деньги?

Выходов два: либо прямая абонентская плата, либо экосистема для пользователей.

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

Если нет желания создавать свою платформу, то производитель умной техники может интегрироваться с какой-нибудь публичной платформой, например с Tuya. Тут всё бремя оплаты на себя берёт производитель умной техники: он вынужден платить платформе за обслуживание своих приборов, а чтобы были на это деньги, он должен постоянно производить и продавать свои приборы, и платить за них, чтобы они не "окирпичились". Такой платформе, как Tuya (и многим другим), не очень выгодны автономные системы, так как создают для заводов привлекательную модель - можно теперь не платить регулярные выплаты за лицензии, прошивки и обслуживание, а просто выпускать приборы, пригодные для использования в изолированной системе. Но опять же упираемся в недостаточную стандартизацию.

Единственное, на мой взгляд, что может серьезно содействовать повышению спроса на автономные системы, так это безопасность. Но и то многие моменты можно обойти, так как большинство умной техники и датчиков можно использовать и без их "умнодомовой" начинки, а пользовательские данные можно ужать до того предела, когда они в целом становятся не особо интересными (т.е. извлечь из них что-то можно, но ценность этого будет не шибкой большой).

И оговорюсь, что все рассуждения касаются именно бытового интернета вещей. В области промышленного интернета вещей (IIoT) и других областях (военная, медицинская, ...), насколько я знаю, там уже давно применяются децентрализованные подходы, в силу вопросов безопасности хотя бы.

В какой-то мере - да, по настоящему качественная система умного дома всегда строится как независимая автономная платформа, способная функционировать вне зависимости от внешних обстоятельств.

Но есть одна тонкость: на этом сложно зарабатывать, сложно продавать и такие продукты пока что не для массового пользователя, поскольку требуют от него определённого уровня технической подкованности. Массовый же покупатель хочет просто купить лампочку, датчики и уже начинать с ними играться, а не возиться с разворачиванием локальной платформы, куда помимо mqtt должно войти ещё всякие разные вещи, типа реестра приборов, UI и прочего, настраивать как то доступ к такой системе извне (привет возне с роутерами, DNS, белые/серые IP и прочее). В итоге бизнес, желающий зарабатывать как минимум, стабильно, а как максимум, много, создаёт централизованную экосистему, привязывая к себе пользователей.

Поэтому такие собственные, локальные умные дома пока остаются уделом энтузиастов.

Если рассуждать с точки зрения сегодняшнего дня, уже обладая пониманием конечного результата, когда подразумевается, что умные приборы изначально должны были быть как-то управляемыми на большом расстоянии, то да, в этом было противоречие...

Но если посмотреть не с сугубо технической точки зрения, а взять во внимание контекст изменения бизнеса и его идей во времени, то на первом этапе Bluetooth был более чем достаточен, поскольку требовалось просто управление на не очень большом расстоянии. И вся техника поначалу позиционировалась так, что можно еще и по BT управлять, но не более того.

Но дальше бизнес-заказчик развивал свои идеи, пожелания и да, в конечном итоге пришли к противоречию, которое и пришлось разрешать :)

На самом деле, утечки памяти организовать не так уж и сложно, смотря, что подразумевать под утечкой... Начиная с банальных моментов, вроде забыл удалить объект из коллекции, когда он тебе больше не нужен, и его сборщик мусора и не трогает. Или когда создаёшь слишком много объектов, а памяти на этот момент резко перестаёт хватать. Типичные программистские ошибки.

Я подробно уже рассказать не могу за давностью лет (5 лет прошло), но точно могу сказать, что сервис, который был тогда написан на Kotlin + rxKotlin, действительно отъедал память регулярно и приходилось его перезагружать.

Там было много моментов, связанных с тем, что где-то забывались подчищаться ресурсы, где-то создавалось слишком много объектов, где то не удалялись всякие слушатели/callback'и, тем более, на мой взгляд, реактивный стек rxJava/rxKotlin на тот момент, требовал более высокого уровня компетенций, более аккуратной работы.

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

Конечно же если всё делать правильно, проблем не будет. Но кто сказал, что мы всегда всё делаем правильно? Так что, не стоит недооценивать способность человеков обходить ограничения каких-либо систем, а особенно, если они это делают непреднамеренно :)

Ответил в комментарии выше :)

Сложно сказать :)

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

Основной довод в пользу Bluetooth и BLE звучал так: BT есть на каждом телефоне, и разработать прототипы приборов, которые управляются с телефона - достаточно просто и быстро, с учётом доступной компонентной базы на то время (середина 2010-х).

Далее конечно же предпринимались попытки разработать железки, работающие и с ZibGee, Wifi, NB IoT и так далее, но основная масса приборов, уже проданных на рынке, была на BLE.

Как-то так...

Согласен с тем, что позиция 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 решения вы руководствуетесь?
Понял, спасибо!

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

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

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

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

Подытожу.

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

Надеюсь, мне удалось прояснить свою позицию в этом вопросе :)
Одобрил ваш комментарий, но позвольте полюбопытствовать — что не так? Какую мысль вы хотели донести?
Спасибо, подправил!
Спасибо, исправил!
Спасибо, подправил!
Интересный комментарий :)

Постараюсь ответить по пунктам.
вообще кто придумал эти 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).
В общем-то да, в потерях сообщений от Redis нет особой внезапности. Но все равно неприятно :)
Про стримы — спасибо за наводку, просмотрел по диагонали. На досуге внимательнее почитаю :)
Спасибо за комментарий. Охотно верю в то, что существует множество решений на базе реактивного стека, и они хорошо масштабируются, и держат большое количество соединений и запросов.

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

Information

Rating
Does not participate
Location
Санкт-Петербург, Санкт-Петербург и область, Россия
Works in
Date of birth
Registered
Activity

Specialization

Backend Developer, Software Architect