- PVSM.RU - https://www.pvsm.ru -
Статья рассказывает о разработке специализированной системы кэширования данных, ориентированной на использование в системах реального времени. Из этой истории разработки станут понятные некоторые архитектурные решения и отличия zero-cache от существующих систем кэширования.
Дано:
Обычный сервер с x86-64 совместимым процессором подключенный по каналам RS-485 (через USB преобразователи) к большому числу контроллеров. Контроллеры занимаются приемом и выдачей разовых команд, вращают шаговые двигатели, оцифровывают аналоговые сигналы (АЦП). Кроме того, к серверу могут быть подключены различные PCI платы (аналоговые, ARINC, MIL-STD и пр.), которые также выдают и принимают данные с внешних устройств.
На сервер по Ethernet каналу каждые 20 мс приходит пакет с текущими значениями параметров для выдачи их на контроллеры и платы. От сервера каждые 20 мс должен уходить пакет со считанными контроллерами и платами входными параметрами. Задержка выдачи новых параметров на все контроллеры должна составлять не более 20 мс.
Кроме основного Ethernet канала, есть дополнительный канал по которому сервер выдает свое состояние (работает или выключен) и получает команды на перезагрузку и выключение.
На сервер ставится не ОС реального времени, а Linux. Выдерживание заданных временных задержек обеспечивается высокой производительностью сервера.
Задача:
Реализовать серверное ПО для обработки всех информационных потоков — для всех контроллеров, PCI плат и обоих Ethernet каналов. Общее число таких информационных потоков порядка 16 штук.
Самое простое решение поставленной задачи (которое и было сначала реализовано) представляет собой многопоточное C++ приложение. Каждый поток обрабатывает конкретный канал RS-485, PCI плату или Ethernet порт. Информация между потоками передается через синглетон, инкапсулирующий STL map контейнер с ключами и объектами, представляющими параметры. Синхронизация между потоками осуществляется с помощью мьютексов, на уровне каждого отдельного параметра.
Достоинства:
Недостатки:
Для устранения существующих недостатков появилась идея хранить все общие параметры в БД MySQL вместо глобального синглетона. Такое решение позволило бы вместо одного процесса со множеством потоков реализовать отдельные независимые процессы для каждого информационного канала. Кроме того данные из БД стали бы легко доступны любому внешнему приложению, в том числе удаленно через дополнительный Ethernet канал. Но задержки на запись и чтение в БД MySQL оказались неприемлемо велики (в среднем порядка 100 мс на используемом оборудовании).
С целью ускорить доступ к данным была попытка использовать БД SQLite, файл которой размещается в разделе RAM. Задержки на операции чтения-записи сократились и стали порядка 20 мс. К сожалению, существовали пики в длительности задержек, связанные с попыткой одновременного доступа к данным из нескольких процессов (при работе одного процесса таких пиков не наблюдалось).
Дальнейшие поиски более быстрой системы хранения данных привели к системе кэширования memcached. Эта система показала практически такие же результаты как БД SQLite размещенная в разделе RAM — порядка 20 мс и пики до 50 мс.
Узким местом всех использованных ранее решений был единственный сокет системы БД или кэширования в который писали и читали данные сразу несколько процессов. В результате блокировок оказывалось, что операции доступа к данным происходят слишком медленно.
Чтобы устранить это узкое место появилась идея разнести параметры по разным сокетам. Каждый сокет должен обслуживаться отдельным потоком серверного приложения системы кэширования. Получаемые от клиентов запросы формируют очередь для каждого сокета, которая разбирается последовательно. Таким образом в каждый момент времени к одним и тем же данным в кэше имеет доступ единственный поток (который отвечает за данный ключ), обрабатывающий очередь запросов в порядке FIFO.
Для распределения параметров по разным сокетам используется служебный сокет сервера. Каждый клиент в начале сеанса связи высылает на служебный сокет имя ключа, котрый надо записать в кэш, а также данные для обратной связи (свой порт и хост). Сервер получив такой запрос проверяет существует ли указанный ключ в кэше. Если нет — ключ приписывается либо к существующему сокету, либо создается новый сокет, если лимит ключей у всех существующих сокетов достигнут. После этого сервер через служебный сокет сообщает клиенту новый сокет по которому следует вести весь дальнейший обмен. В результате каждый клиент общается только с сокетом, который обслуживает его ключи. При попытке чтения ключа, сервер ищет сокет к которому приписан требуемый ключ и выдает клиенту номер этого сокета.
Схема взаимодействия клиентов с системой кэширования.
Достоинства:
Недостатки:
В результате использования специализированной системы кэширования удалось добиться средней задержки на операции чтения и записи порядка 1 мс при пиковых значениях до 10 мс.
Кроме того, есть перспективы дальнейшего улучшения производительности благодаря использованию отложенной операции записи в кэш (клиент создает поток который посылает запросы на запись данных, при этом управление сразу возвращается в клиентское приложение). Также можно подумать над реализацией получения данных не по запросу от клиента, а по их изменению в кэше. Новое значение параметра при изменении может выдаваться всем подписанным на этот параметр клиентам.
www.zero-cache.org [1] — сайт пректа описанной специализированной системы кэширования
www.zeromq.org [2] — библиотека на базе которой реализована эта система кэширования
Автор: MegaPeter
Источник [3]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/c-3/27944
Ссылки в тексте:
[1] www.zero-cache.org: http://www.zero-cache.org
[2] www.zeromq.org: http://www.zeromq.org
[3] Источник: http://habrahabr.ru/post/170555/
Нажмите здесь для печати.