Russian Qt Forum

Qt => Многопоточное программирование, процессы => Тема начата: sergek от Декабрь 24, 2018, 19:31



Название: Кэширование обновляемых данных
Отправлено: sergek от Декабрь 24, 2018, 19:31
Коллеги,
раздумываю над организацией кэша данных в сервера диспетчеризации распределенной системы мониторинга. Хотелось бы услышать подсказку по средствам реализации этого самого кэша.

Сервер выполнен в виде веб-сервиса (см. рисунок), имеет REST API, по которому поступают данные от узлов распределенной системы. Обработка каждого запроса выполняется в своем отдельном потоке. Узлов около сотни, темп поступления от каждого узла - 5-10 сек., объем данных небольшой (суммарный от всех узлов - несколько мегабайт).
UI системы - браузер, отображающий данные, поступающие из узлов. Из UI могут поступать различные команды, которые через блоки обработки запросов и формирования запросов REST API могут направляться в узлы системы. Эти запросы также выполняются в своих (клиентских) потоках.
Все данные, поступающие от узлов по разным каналам, аккумулируются в кэше текущих данных, откуда и забираются по http для отображения в UI. Кэш выполнен в виде массива вложенных контейнеров, создается в главном потоке сервиса.

Собственно, вопрос простой - я предполагаю весь кэш держать в памяти (куче), а в качестве средства синхронизации использовать QReadWriteLock. Как считаете, нет тут очевидных ошибок? Может быть, подскажете, как, на ваш взгляд, лучше организовать хранение текущих данных?


Название: Re: Кэширование обновляемых данных
Отправлено: RedDog от Декабрь 25, 2018, 14:46
Если кеш это нечто большее, чем набор контейнеров, то я бы ему сделал свой поток, отличный от главного, а может вообще б распараллелил через пул доступ к нему.


Название: Re: Кэширование обновляемых данных
Отправлено: sergek от Декабрь 25, 2018, 16:06
Да не спасет это. Обновление данных производится многими клиентами, часто и порциями (т.е. за один сеанс обновляются не все массивы, а только их часть). А вот чтение - значительно реже, но зато требуются все данные, и выполняется кое-какая обработка, например, вычисление некоторых характеристик.
По всему выходит, что для чтения следует использовать некую локальную копию кэша. Криво как-то все...


Название: Re: Кэширование обновляемых данных
Отправлено: Igors от Декабрь 26, 2018, 11:08
Если Вы употребляете термин "REST API" - то возможно хотите получать ответы только тех кто с ним работал. Я нет, поэтому не знаю уместны ли мои соображения ниже  :)

Да не спасет это. Обновление данных производится многими клиентами, часто и порциями (т.е. за один сеанс обновляются не все массивы, а только их часть). А вот чтение - значительно реже, но зато требуются все данные, и выполняется кое-какая обработка, например, вычисление некоторых характеристик.
По всему выходит, что для чтения следует использовать некую локальную копию кэша. Криво как-то все...
Если "частая запись" + "большое (но редкое) чтение" то QReadWriteLock не подходит, т.к. в своем первозданном виде он рассчитан на наоборот, достаточно редкую запись. Также надо разбираться что лочить - весь кеш или поэлементно, пример

- в кэше 10 эл-тов. Выполняется чтение, прочитано уже 5. Значит блокировать всю запись необязательно, прочитанные (или считанные) переписывать уже можно.


Название: Re: Кэширование обновляемых данных
Отправлено: sergek от Декабрь 26, 2018, 13:26
Если Вы употребляете термин "REST API" - то возможно хотите получать ответы только тех кто с ним работал. Я нет, поэтому не знаю уместны ли мои соображения ниже  :)
Да фигня)) Обычные асинхронные http-запросы. Особенность с точки зрения кэша - данные могут поступать когда угодно.
Если "частая запись" + "большое (но редкое) чтение" то QReadWriteLock не подходит, т.к. в своем первозданном виде он рассчитан на наоборот, достаточно редкую запись. Также надо разбираться что лочить - весь кеш или поэлементно, пример
Думал над этим, - не получается. Для чтения нужны все данные сразу. Поэтому в частичной блокировке смысла нет.
Решил пока использовать самое тупое решение - при чтении делать копию всего кэша. Клиентская нагрузка предполагается небольшая, не более десятка клиентов. Будет тормозить или жрать память - буду думать над оптимизацией, этот кусок структурно хорошо обособлен.


Название: Re: Кэширование обновляемых данных
Отправлено: Igors от Декабрь 27, 2018, 10:55
Решил пока использовать самое тупое решение - при чтении делать копию всего кэша. Клиентская нагрузка предполагается небольшая, не более десятка клиентов. Будет тормозить или жрать память - буду думать над оптимизацией, этот кусок структурно хорошо обособлен.
Проблемы остаются те же - нужно залочить кеш чтобы сделать копию, при этом притормозив "писателей", т.к. если их много - копированию будет трудно прорваться.


Название: Re: Кэширование обновляемых данных
Отправлено: RedDog от Декабрь 27, 2018, 12:47
А чоб sqlite какую нидь в ОЗУ не попользовать?
Она может дать многопоточный доступ на запись/чтение, только до завершения транзакции записи, читать будешь старые данные.


Название: Re: Кэширование обновляемых данных
Отправлено: sergek от Декабрь 27, 2018, 14:44
А чоб sqlite какую нидь в ОЗУ не попользовать?
Вообще о БД подумывал, только забыл (или не знал)) о том, что можно ее держать в ОЗУ. Отказался по двум причинам - необходимость периодической упаковки/вакуума (наверное, для случая в ОЗУ это не требуется) и из-за типизации данных (разве что хранить в текстовом виде?).
Но мысль интересная, спасибо.