Master-master репликация и масштабирование приложений между всеми IoT-устройствами и облаком |
||
МЕНЮ Искусственный интеллект Поиск Регистрация на сайте Помощь проекту ТЕМЫ Новости ИИ Искусственный интеллект Разработка ИИГолосовой помощник Городские сумасшедшие ИИ в медицине ИИ проекты Искусственные нейросети Слежка за людьми Угроза ИИ ИИ теория Внедрение ИИКомпьютерные науки Машинное обуч. (Ошибки) Машинное обучение Машинный перевод Реализация ИИ Реализация нейросетей Создание беспилотных авто Трезво про ИИ Философия ИИ Big data Работа разума и сознаниеМодель мозгаРобототехника, БПЛАТрансгуманизмОбработка текстаТеория эволюцииДополненная реальностьЖелезоКиберугрозыНаучный мирИТ индустрияРазработка ПОТеория информацииМатематикаЦифровая экономика
Генетические алгоритмы Капсульные нейросети Основы нейронных сетей Распознавание лиц Распознавание образов Распознавание речи Техническое зрение Чат-боты Авторизация |
2017-02-01 00:30 На фото представлены устройства, использованные для прототипирования. Как видно, за основу взята платформа Intel Edison, так как она поддерживает многие архитектуры, в том числе MIPS и ARM.
Всем привет. В этой статье я хотел бы поделиться опытом решения одной интересной проблемы, связанной с синхронизацией данных между IoT-устройствами и облачным приложением. Сначала я расскажу об основной идее и целях моего проекта, а затем подробно опишу его техническую сторону и реализацию: речь пойдет об ОС Contiki, базах данных, протоколах и подобных аспектах. В заключение я кратко перечислю технологии, использованные при построении системы. Вкратце о проекте Для начала давайте поговорим об основной идее проекта. Ниже схематично изображен принцип работы готовой системы: Есть пользователь, который через облачный сервис или напрямую (по Wi-Fi) подключается к IoT- устройству. Также где-то в Интернете имеется облачный сервер приложения. Облаком может служить что угодно: скажем, инстанс AWS или Azure или выделенный сервер. Для обмена данными между сервером приложения и IoT-устройствами устанавливается соединение по какому-то протоколу. IoT-устройства каким-то образом соединены друг с другом (например, по Ethernet или Wi-Fi). Помимо этого, есть отдельная группа IoT-устройств, генерирующих телеметрические данные (такие как показатели освещенности или температура).В общей сложности, может набраться больше 100 или даже больше 1000 устройств. Моя основная задача заключалась в том, чтобы обеспечить обмен данными между облаком и этими IoT-устройствами. Прежде чем двигаться дальше, стоит упомянуть, какие требования предъявлялись к системе:
Техническая реализация Здесь все довольно просто: пользователь подключается к серверу приложения по HTTP(S), WebSocket или подобному протоколу. Небольшая задачка для читателей: как вы думаете, что можно использовать для соединения между сервером приложения и IoT-устройством? Если вы подумали про MQTT, вы однозначно правы! Равно как и те, кто выбрал HTTP(S). На самом деле подойдет любой протокол — выбирайте на свой вкус! Мой же выбор пал на — барабанная дробь — асинхронную репликацию! Я имею в виду обычную для баз данных репликацию. Вы можете спросить, зачем мне репликация. Ответ прост: репликация используется для синхронизации данных, поэтому я могу повсюду — включая облако и IoT-устройства — поддерживать одну версию базы данных. Однако репликацию довольно сложно реализовать. Хочешь репликацию — заведи базу данных, которая ее поддерживает, потому что — повторюсь — репликация естественно присуща базам данных. Здесь я бы хотел сказать пару слов о тех базах данных, которые я рассматривал при работе над проектом: SQLite, Redis, MySQL, PostgreSQL и Tarantool. Я сравнил их характеристики и попробовал запустить несколько штук — за исключением MySQL и PostgreSQL — прямо на IoT-устройстве. Ниже расскажу, что из этого вышло. SQLite — однозначно хорошее решение для хранения данных непосредственно на IoT-устройстве, но у нее нет репликации, и она не поддерживает параллельный доступ из разных процессов. Redis не поддерживает master-master репликацию и поэтому не может решить мою проблему, так как мне необходима двусторонняя репликация. MySQL и PostgreSQL слишком тяжеловесны для IoT-устройства, так что я даже не пытался их устанавливать. Но если вы все-таки решите это сделать, смело делитесь своим опытом в комментариях. Последней в моем списке шла база данных Tarantool. Сразу скажу, что я являюсь коммитером в проект Tarantool, поэтому хорошо знаю сам проект и людей, которые его разрабатывают. К тому же, в Tarantool есть master-master репликация. В общем, для меня это был определенно лучший вариант. Вы же можете использовать в своем проекте другую базу данных. Основная идея, которую я пытаюсь донести, в том, что IoT-устройства могут использовать базы данных с master-master репликацией для обмена данными. До настоящего момента я лишь поверхностно знакомил вас с проектом. Теперь давайте немного погрузимся в его технические аспекты. Начну с проблем, с которыми я столкнулся при использовании Tarantool. Во-первых, Tarantool не запускалась на архитектуре ARMv7. Во-вторых, Tarantool не запускалась в 32-битном окружении, что только усугубляло ситуацию. В итоге я смог решить эти проблемы. Ниже приведу правила разработки, которые мне в этом помогли.
Ожидается, что ваши автотесты можно запустить на IoT-устройстве. Если это не так, есть риск убить много времени на отладку. Итак, у меня есть работающая база данных с master-master репликацией. Замечательно! Следующий шаг — соединить устройства, на которых эта база данных установлена, по 6LoWPAN. Напомню, у меня есть сеть из множества IoT-устройств, соединенных друг с другом по 6LoWPAN, с которых мне необходимо собрать все телеметрические данные. Краткая схема работы готовой системы Устройства с сенсорами передают телеметрические данные посредством радиоволн. Этот стандарт называется 6LoWPAN (IPv6 поверх маломощных беспроводных персональных сетей). Замечу, что я не использовал в проекте LoRaWAN. Возможно, я найду применение этой технологии в будущем, но в этой статье я сосредоточусь на 6LoWPAN. Итак, для сбора телеметрических данных я буду использовать шлюз, являющийся важной частью системы. Шлюз — это MIPS-устройство (MIPS — это семейство процессоров) с WAN-антенной для сбора данных, передаваемых посредством радиоволн. Кроме этого, на шлюзе установлено приложение 6LBR, конвертирующее полученные данные в IPv6-пакеты. Приложение 6LBR Изображение выше иллюстрирует принцип работы 6LBR. Шлюз с установленным на него 6LBR служит конвертером между беспроводной сенсорной сетью и любой другой. На картинке изображена конвертация из беспроводной сенсорной сети в IP-сеть лишь потому, что так 6LBR работает по умолчанию. Немного позже я объясню, как изменить это поведение. Более подробную информацию можно найти на странице 6LBR на GitHub. Вы можете спросить, что же мне дает использование 6LBR. Во-первых, я получаю стек IP, так что я могу использовать функционал стеков TCP и UDP в моих приложениях 6LBR. Во-вторых, я могу использовать любое устройство ввода-вывода с 6LBR. Скажем, можно записать сырые данные прямо в bash. =) К сожалению, 6LBR не пишет напрямую в MQTT. MQTT-брокеры ничего не знают о сырых данных, и с этим приходится мириться. Зачем же мне понадобилась прямая запись в MQTT-брокер? Ответ прост: дело в legacy-коде. Здесь я бы хотел сказать пару слов о приложениях 6LBR. В общем случае приложение 6LBR — это написанный на С код с API, позволяющим использовать стек IP и делать некоторые другие вещи. Разработка такого приложения сопряжена как минимум с двумя трудностями: сложная модель потоков и сложная модель памяти. Поэтому запаситесь терпением и приготовьтесь к частым аварийным завершениям вашей программы. Ниже приведен небольшой кусок разработанного мной приложения 6LBR (заранее прошу прощения: могу выложить только картинку с нарочно запутанным кодом, потому что исходники закрыты): Обратите внимание на одну интересную вещь — PROCESS_YIELD(). В 6LBR есть кооперативная многозадачность, а это значит, что приложения 6LBR должны возвращать управление в каждой итерации цикла. Код не должен выполняться слишком долго. Итак, давайте еще раз посмотрим, на какой стадии находится наш проект. С помощью шлюза и установленного на него приложения 6LBR я создал mesh network для чтения и записи данных внутри нее. Мне также удалось обернуть IP-пакеты в MQTT-сообщения, каждое из которых содержит информацию об устройстве, включая телеметрические данные. Кроме того, у меня появилась возможность манипулировать устройствами ввода-вывода: скажем, я могу записывать MQTT-сообщения на UART. Но затем я столкнулся с новой проблемой: Tarantool не работает с MQTT-брокерами. Ниже расскажу, как мне удалось обойти это ограничение. Я решил использовать libmosquitto, написанную на чистом С MQTT-библиотеку, потому что она позволяет довольно просто интегрировать MQTT в мое приложение. Ниже приведен пример использования этой библиотеки для работы с MQTT-сообщениями (ссылка):
Я могу взять ссылку на дескриптор сокета и использовать собственный событийный цикл для обработки некоторых событий. И это здорово! Хотел бы обратить ваше внимание на то, что в Tarantool, так же как и в 6LBR, есть кооперативная многозадачность. Для возвращения управления Tarantool использует coio_wait() .Ах да, забыл упомянуть, что Tarantool — это еще и сервер приложений на языке Lua. Сюрприз! Поэтому я портировал libmosquitto на Lua. Ниже привожу кусок кода, в котором вызывается функция, которую вы уже видели в предыдущем примере:
Я также портировал все функции из API libmosquitto. Посмотреть на результат можно здесь. По ссылке дан пример использования. Все что нужно сделать для сбора данных со всех устройств внутри mesh network — это вызвать функцию subscribe() из определенного места и опубликовать метод get() ! Заключение Давайте посмотрим на то, что у нас получилось: Соединение с сервером приложения установлено посредством предоставляемой Tarantool master-master репликации. Из этого вытекают два полезных свойства:
Именно эти свойства и являются решением моих проблем. Я также могу соединить мои IoT-устройства посредством master-master репликации. Таким образом устройства и облако объединяются в кластер, который можно использовать для синхронизации всех данных. Все IoT-устройства и облако синхронизированы большую часть времени, за исключением случаев, когда между ними пропадает соединение. Как только соединение будет восстановлено, все данные снова синхронизируются. Просто замечательно! Шлюз с установленным на него приложением 6LBR позволяет обмениваться данными между моими IoT-устройствами и другими IoT-устройствами. Он оборачивает каждое сообщение в MQTT-сообщение и передает его в канал UART. IoT-устройство #N с установленным на него MQTT-брокером считывает эти сообщения из канала UART. MQTT-брокер перенаправляет сообщения в Tarantool по MQTT-соединению. Tarantool считывает их, затем для каждого сообщения сервер приложений Tarantool выполняет некоторый код. IoT-устройство #N соединено со всеми остальными устройствами посредством предоставляемой Tarantool master-master репликации. Такая же репликация используется для соединения всех устройств с облаком. На этом все! Я решил поставленную задачу и очень надеюсь, что мой опыт поможет вам в ваших собственных проектах в будущем. Подытожу: я использовал Tarantool и как основной фронтенд на моих выделенных серверах, и как сервер приложений. Если вас заинтересовала данная тема, рекомендую взглянуть на другую мою статью на английском языке. Оставайтесь на связи и следите на новостями! Источник: habrahabr.ru Комментарии: |
|