LINUX.ORG.RU

«Мягкий» real-time


0

0

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

1. Визуализирует состояние железки (где запись ведется, где нет и тп)

2. Записывает события в базу

3. Принимает запросы о состоянии канала и состоянии записи от клиентов и команды о назначении дополнительных атрибутов записям

4. Сам проставляет записям нкоторые атрибуты

Причем работать это должно в режиме гарантированного отклика - клиент получает отклик в переделах 3 секунд, а время обработки события о начале или окончании записи не должно превышать одной секунды, вне зависимости от блокировок в СУБД и ее (СУБД) загрузки

Пока что построена система о пяти независсимых нитях:

DBThread - нить хранит список "грязных" объектов, которые надо сохранить в базе и собственно пишет в базу

QueueRunner - очередь активных записей и обработчик команд (сообщений), пришедших от других нитей. Другие нити могут только добавить сообщения в очередь. QueueRunner делает все действия какие надо, и складывает задания в очередь к DBThread.

Recorder - считывает сообщения с железки и обслуживающей ее программы и кладет их к QueueRunner.

Networker - слушает запросы от клиентов и складывает из в QueueRunner. Если клиенту надо "срочно" вернуть ответ, Networker может прочесть данные из записи, хранящейся в QueueRunner.

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

Visual - визуализирует состояние очередей и железки.

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

Есть какие-нибудь мысли как ЭТО все улучшить?

★★★★★

И да, над всем этим бдительно смотрит WatchDog, который вопит и устаривает истерику, если кто-то из "боевиков" типа QueueRunner, Recorder или Networker вдруг не подает признаки жизни в течение нескольки (10...15) секунд.

no-dashi ★★★★★
() автор топика

этСтавишь линух, делаешь самый минимальный своп, отключаешь все сервисы, выносишь лишнее из крона, автообновления итп что может дёргать тачку. Отключи компрессию логов. Тюнишь некоторые sysctl типа vm.swappiness=0. Следишь чтобы был всегда многократный запас производительности... и всё.

true_admin ★★★★★
()
Ответ на: комментарий от true_admin

> Следишь чтобы был всегда многократный запас производительности...

И потом кто-нибудь в базе делает lock tablename

> и всё.

Ага, точно "все" :-)

no-dashi ★★★★★
() автор топика
Ответ на: комментарий от true_admin

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

Это всё разумно, но для времен реакции порядка секунд - не обязательно.

> Следишь чтобы был всегда многократный запас производительности... и всё.

Ыыыы... какой кошмар %)

tailgunner ★★★★★
()

А насчет архитектуры - она выглядит разумно на первый взгляд, но дьявол в мелочах. Например, как обрабатывается переполнение очередей (DBThread тормозит, например).

tailgunner ★★★★★
()
Ответ на: комментарий от no-dashi

> И потом кто-нибудь в базе делает lock tablename

Кто? Барабашка?

true_admin ★★★★★
()
Ответ на: комментарий от true_admin

> Выскажи свою некошмарную идею.

Понимаешь, некошмарной идеи нет... если кратко, то система должна давать гарантии "by design" - есть разные специальные техники для этого. То есть, должна быть спроектирована специальным образом (но-дачи так и сделал). А ты вообще считаешь (судя по твоему постингу), что специальное проектирование не нужно.

tailgunner ★★★★★
()

> Есть какие-нибудь мысли как ЭТО все улучшить?

А что конкретно сейчас не устраивает?

mv ★★★★★
()

Можно не жадные до процессора треды свести в один, который будет работать асинхронно.

mv ★★★★★
()
Ответ на: комментарий от tailgunner

> А ты вообще считаешь (судя по твоему постингу), что специальное проектирование не нужно.

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

true_admin ★★★★★
()
Ответ на: комментарий от true_admin

>> А ты вообще считаешь (судя по твоему постингу), что специальное проектирование не нужно.

> Ничего подобного.

"Ничего подобного" было бы, если бы ты сам не сказал "и всё".

tailgunner ★★★★★
()
Ответ на: комментарий от dn2010

> Ingo Molnar писал патчи как раз для такого варианта realtime

По опыту, наибольшее количество проблем создает как раз не операционка, а база данных. Она может находиться на другом компе, СУБД может просто "тормозить" из-за своих внутренних мыслей и т.п.

В общем, предложенная схема сработала, поставленная задача решена. Конечно, надо еще все переписать "набело", но в третьем приближении система пиковый удар держит :-)

no-dashi ★★★★★
() автор топика
Ответ на: комментарий от true_admin

> И некоторый тюннинг системы.

Тюнинг дает проценты производительности. Дизайн дает прирост в порядки :-)

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

no-dashi ★★★★★
() автор топика
Ответ на: комментарий от no-dashi

> Тюнинг дает проценты производительности. Дизайн дает прирост в порядки :-)

Как старый админ говорю-ты не прав :). Без правильно настроенной тачки ничего работать толком не будет. С другой стороны, а что считать тюнингом? Индексы в базе расставить это тюннинг? Логи вынести на отдельный винт? Итп. Это можно рассматривать как тюнинг так и часть дизайна.

> может просто "тормозить" из-за своих внутренних мыслей и т.п.

База делает то что ты ей скажешь. Сама по себе она запросы выполняет.

true_admin ★★★★★
()
Ответ на: комментарий от true_admin

Слушай, старый админ, шел бы ты в Admin, и не мешал дядькам программистам обсуждать серьезные вещи :))

если по делу, то тут наверное будет очень важдым выбор СУБД...

может всю эту "клюкву" написать на Erlang, и заюзать "софт-реалтайм" СУБД Mnesia? ;)

Удачи!

Cy6erBr4in ★★★
()
Ответ на: комментарий от true_admin

> База делает то что ты ей скажешь. Сама по себе она запросы выполняет.

Данные в базе нужны для того, чтобы их впоследствии читали и с ними работали. И все эти инджексы и прочее для OLTP как мертвому припарка, а часто даже скорей как больному цианид. OLTP - это много мелких insert/update и крайне прсотые select вида select id from table wheer value=:name, здесь оптимизации места просто нет.

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

Мы строили индексы, читали планы запросоы, оптимизировали распределение датафайлов по носителям, смотрели выводы статспаков и всякой муетни и занимались прочей чушью... И как мы гордились, когда оборотная ведомость начала формироваться за 10 минут а не за 20... А потом наш главный "оптимизатор" уволился. Да. И поскольку смотреть на всякие latch waits и прочую пое..нь мне надоело, то я занялся нормальной работой с перепроктированием запросов. Какие результаты? Для сравнения, некоторый отчет собирался 10-15 минут, после переписывания начал собираться за 10-15 секунд. Баланс собирался 8-12 часов, стал собираться за 5-15 минут. Это проектирование :-)

no-dashi ★★★★★
() автор топика
Ответ на: комментарий от no-dashi

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

Индексы не нужны? Даже если у тебя все запросы с where id=... то индекс всё равно используется потому что это primary key. Но только в жизни такими простыми запросами OLTP не ограничивается. И тут я могу привести хороший пример. Добавление индексов на поля которые используются в where удалось сократить время исполнения запроса с 7 секунд до 0.13. Вполне сравнимо с "Баланс собирался 8-12 часов, стал собираться за 5-15 минут".

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

Или какие-нить mbufы кончатся и тачка выпадет из сети.

Без допиливания настроек ОС и сопутствующих компонентов зачастую не обойтись. Можно сказать что эти настройки тоже часть архитектуры, тогда непонятно чего мы спорим.

true_admin ★★★★★
()
Ответ на: комментарий от true_admin

> И забыл какой-нить updatedb из крона выкинуть. В результате ночью одновременно у всех тачек резко напряглись винты и кластер резко залагал. А тут ещё ротация логов с бэкапами подоспела.

Жжошь. На боевых серверах производительность подсистем I/O под тяжелыми СУБД такая, что они все примонтированные ФС поднимают в кэш за несколько секунд, датафайлы СУБД вообще на отдельном сторадже, и все эти такие "страшные" по твоему мнению процессы на скорость обращения к ним не повлияют в принципе. Проверено :-)

> Но только в жизни такими простыми запросами OLTP не ограничивается.И тут я могу привести хороший пример. Добавление индексов на поля которые используются в where удалось сократить время исполнения запроса с 7 секунд до 0.13.

Плохой пример. OLTP как раз раз ограничивается крайне простыми запросами (а приведенный тобой случа как раз крайне простой), поскольку основные операции там как раз поиск в справочнике по ключевым атрибутам. А ключевые атрибуты, как известно, ясны уже на этапе постановки задачи, то есть индексы для них построены на этапе проектирования БД. Увы.

Опять таки - в журналируемых версионных СУБД (а назови сейчас не такую?) операция записи в три-пять раз медленнее операции чтения, плюс конкуренция за совместно изменяемые объекты (если такие есть)... Не зря в настрйоках "шаблонов" для создания базы оракла есть два готовых темплейта - Transaction processing и Data warehouse.

> Без допиливания настроек ОС и сопутствующих компонентов зачастую не обойтись

Как раз обходится, совершенно естественным образом. Для soft-realtime систем критична как раз архитектура "думающей" части системы, а не операционка. На одном и том же железе оракел под виндами, под солярисом и под линуксом покажет примерно одинаковую производительность, при условии невыхода нагрузки системы на "закритический" режим. "Тонкий тюнинг" операционки нужен только при неправильном развертывании СУБД (чего правда очень много).

no-dashi ★★★★★
() автор топика
Ответ на: комментарий от true_admin

> Я сказал что чтобы всё работало нормально все компоненты системы должны работать нормально

Как бы "нормально" не работала операционка под сервером логики, о котором шла речь в самом начале, ЕСЛИ БЫ все это было сделано в одном потоке, пусть и с использованием всяческих select() и poll(), то в случае замедления СУБД по любой причине, программа также встала бы на неопределенное время

Первый вариант (когда было не было жестких требований по времени реакции) реализовывался именно так, без нити DBThread. Последствия были неприятны - постоянные жалобы пользователей и лаги, попытки подлатать программу то тут, то там и так далее.

Впрочем, "админ программера не разумеет" :-)

no-dashi ★★★★★
() автор топика
Ответ на: комментарий от no-dashi

> ЕСЛИ БЫ все это было сделано в одном потоке, пусть и с использованием всяческих select() и poll(), то в случае замедления СУБД по любой причине, программа также встала бы на неопределенное время

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

tailgunner ★★★★★
()
Ответ на: комментарий от no-dashi

Устал спорить. Если у вас такие могучие железки которые всё стерпят то вам это действительно не надо.

true_admin ★★★★★
()

Присоединяюсь к вопросу mv: "А что конкретно сейчас не устраивает?"

Может имеет смысл делать отельный процесс middleware, который будет работать с СУБД, буферезировать UPDATE, кешировать справочники из БД. Ваша программа взаимодействует с ним через UNIX-socket'ы, процесс многопоточный или работает с БД асинхронно.

И я не совсем понял фразу:

>Если клиенту надо "срочно" вернуть ответ, Networker может прочесть данные из записи, хранящейся в QueueRunner.

То есть обращаемся не к очереди "грязных" объектов, хранящейся у DBThread, которая и должна быть самая большая, так как БД непредсказуема, а именно к очереди QueueRunner?

mky ★★★★★
()
Ответ на: комментарий от mky

> То есть обращаемся не к очереди "грязных" объектов, хранящейся у DBThread, которая и должна быть самая большая, так как БД непредсказуема, а именно к очереди QueueRunner?

Объекты в QueueRunner постоянно рождаются и умирают по командам от Recorder. По командам от Networker у объектов меняются атрибуты, и ответа такие команды не требуют, но есть одна специфическая команда LINE_STATE, по приходу которой необходимо сделать ответ "текущее состояние опрашиваемой линии такое-то". То есть вся работа именно с QueueRunner.

В момент когда объект рождается, он записывается в два списка - в список "активных" в QueueRuneer и список "известных" у DBThead. Если QueueRunner изменил объект, DBThread сохранит его когда руки дойдут. Как только QueueRunner решил что объект должен умереть, он ставит на нем метку "более не нужен", и кода DBThread заканчивает с ним работать, объект окончательно уничтожается.

> Может имеет смысл делать отельный процесс middleware

IMHO, это нагромождение сущностей и сложностей вне меры

no-dashi ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.