Opened 11 months ago
Closed 11 months ago
#655 closed улучшение (готово)
Оптимизировать учет аварий в "журнале аварий"
Reported by: | alx | Owned by: | alx |
---|---|---|---|
Priority: | средний | Milestone: | 1 очередь |
Component: | swd | Keywords: | |
Cc: |
Description
В плате SW-01 организован отдельный "журнал аварий", в который наносятся возникающие аварии, а также фиксируется время из завершения. Журнал организован в виде базы данных sqlite. Иногда при эксплуатации аппаратуры возникают ситуации, когда идет постоянный поток событий - периодическое возникновение и пропадание аварий (например из-за регулярного пропадания и восстановления входного сигнала на портах оборудования). В такой ситуации события могут поступать быстрее, чем они записываются в базу данных. Такая ситуация приводит к повышенной загрузке системы и возможным потерям записываемой в журнал аварий информации.
Был проведен ряд тестов, которые показали, что при возникновении аварий новые записи в БД (INSERT) записываются за константное время, в то время как запросы завершения аварий (UPDATE) выполняются за линейное время, и-з за чего при большом размере БД (100000 записей) производительность падает до единиц запросов в секунду.
Предлагается оптимизировать запись в БД завершений аварий следующим образом:
- При добавлении новой записи об аварии в БД сохранять ROWID в памяти в специальном хэше. В качестве ключа использовать комбинацию номера слота и oid аварии. Максимальный размер кэша ограничить достаточно большим разумным числом (например 1000), чтобы туда помещалось подавляющее большинство активных аварий в блоке (в идеале - все).
- При завершении аварии искать соответствующий ROWID в кэше по ключу slot-oid, и если он найден, обновлять запись по условию
WHERE ROWID=N
. Если ROWID в кэше не найден (из-за переполнения кэша), выполняется fallback на старый вариант запросаWHERE slot=S AND oid='xxxxx' AND end IS NULL
.
Как показали эксперименты, запрос записи завершения аварии по ROWID выполняется за константное время. Таким образом, общая производительность записи в БД составляет около 230 запросов в секунду при использовании UBIFS и около 60 запросов в секунду при использовании JFFS2 независимо от размера БД.
Change History (8)
comment:1 by , 11 months ago
Summary: | Оптимизировать учем аварий в "журнале аварий" → Оптимизировать учет аварий в "журнале аварий" |
---|
comment:2 by , 11 months ago
С хэшем получается неудобно, так как, во-первых, иногда случается "групповое" завершение аварий (всех аварии платы), и непонятно, как их потом "вычистить" из кэша. Если не вычищать, они будут там копиться, и кэш может переполниться и просто перестать работать. Как вычищать мусор из кэша непонятно - старые записи от новых никак не отличаются, а добавллять ради этого таймстемп и потом по нему сортировать - слишком громоздко и затратно.
Решил вместо хэша использовать просто список элементов, в которых хранить слот, oid и ROWID. При добавлении новых элементов в "голову" списка те аварии, которые часто возникают и завершаются, будут всегда в начале списка, и их поиск будет выполняться быстро. В то же время при переполнении списка можно просто удалять элементы из "хвоста".
comment:4 by , 11 months ago
Resolution: | fixed |
---|---|
Status: | closed → reopened |
Поздно сообразил, что надо было просто добавить правильный индекс.
comment:5 by , 11 months ago
Resolution: | → готово |
---|---|
Status: | reopened → closed |
Провел еще ряд экспериментов. Наиболее оптимальные результаты получились при добавлении индекса slotend ON test(slot, end)
. С таким индексом получается около 150 запросов в секунду на UBIFS и около 35 запросов в секунду на JFFS2.
comment:6 by , 11 months ago
Resolution: | готово |
---|---|
Status: | closed → reopened |
Тикет был закрыт по ошибке.
Считаю, ранее сделанные изменения следует откатить в пользу решения с добавлением индекса.
comment:8 by , 11 months ago
Resolution: | → готово |
---|---|
Status: | reopened → closed |
В r2340:
Значительно ускорена работа журнала аварий.
В журнале аварий убраны все не очень нужные индексы,
и вместо них добавлен один индекс по столбцам slot и end.
Теперь записи о возникновении и завершении аварий в журнал
происходят со скоростью около 180 запросов в секунду
на UBIFS и около 45 запросов в секунду на JFFS2.
Считаю, что такой производительности более чем достаточно.
Блин! :)