Неблокирующая запись логов в БД. Практики и критерии. Что делать?
Вводные:
— Есть набор cron-задач, с интервалом в 3/5/8/10 минут в группе серверов.
— Раз в 120 минут происходит их единовременный запуск.
Но не в ошибке организации крона проблема. Проблема в логировании и уведомлении разработчиков.
Как порождается ошибка:
— Единовременный запуск скриптов чтения и записи в БД
— по взаимосвязанной группе строк
— на группе серверов с расхождением по времени
Итог:
— Лок по строкам, 5 тысяч писем через PDD яндекса без гарантии своевременной доставки, в пределах 0 - 96 часов.
— Об этом создаются почтовые уведомления для отправки.
— Тут умирает php-fpm
Кандидат на решение:
— Есть идея создавать строку в БД, если в эту минуту не происходило такой ошибки,
— Увеличивать значение поля "количетсво ошибок" при повторном вхождении ошибки в этот интерва (1 минута).
— Раз в 5-10 минут мы будем высылать таблицу-сводку ошибок.
Чую, что я близок к изобретению велосипеда, но вопрос - в другом.
Как/куда мне гарантировано писать 50/100/1000 записей INSERT/UPDATE/SELECT в секунду?
А если кластернуть?
Redis/Memcached/MongoDB? Готовые продакшен-решения всей задачи?
Все приложения/скрипты читают, обновляют и пишут в одну и ту же таблицу?
Используются ли транзакции? Запираются ли записи на время отправки уведомлений?
Из-за какой именно ошибки "умирает php-fpm"?
рекомендую redis, у него на ключик можно поставить время жизни, также есть механизм PUB/SUB, но и все остальное прокатит, в том числе и prostgres и mysql. Также можно использовать elastisearch +logstash для хранения логов.
ElastiSearch, на quora.com очень хвалят. Компании раз в 100 тысяч больше нашей.
Это меня немного смущает, хотя я и теку на это решение. Но его внедрение я бы приурочил к переходу на тотальное логирование по сквозному ключу от access.log nginx c расширенными метриками по браузеру, во Front`а и API-ядра проекта, а закончил б уже на БД логах.
Тогда бы было понятно, на что мне такой комбаин.
Сейчас сердце клонится к "редиске", хоть с первого пинка она зваелась медленнее memcache, который уже есть в стэке, ситуацию с ним выправили. Но мои фобии упираются в то, как он начнет кашлять, когда на одну и ту же запись/обновление строки нападёт 3 сервера по 50/100/100 запросов к одной строке?
Признаюсь, тут моя матчасть хромает. Слово знаю - LOCK. А что оно будет значить для меня в такой вот попытке - не пойму.
Since Redis is single threaded, you will probably want to use master-slave replication to separate writes from reads, since yes, writes will generally block reads.
Кандидат на решение:
— Есть идея создавать строку в БД, если в эту минуту не происходило такой ошибки,
— Увеличивать значение поля "количетсво ошибок" при повторном вхождении ошибки в этот интерва (1 минута).
— Раз в 5-10 минут мы будем высылать таблицу-сводку ошибок.
Чую, что я близок к изобретению велосипеда...
Работаю с похожим велосипедом, полет нормальный. Только не в БД считаются повторы, а в оперативке. Чтобы избежать лишнего IO.
5 тысяч писем через PDD яндекса
Это зачем? Хотите сказать, их будет кто-то читать?
Ок, т.е. завести глобальную переменную?) Правда - без БД?
По поводу того, как оно происходит. 50 писем в секунду на протяжении минуты 6 раз в день, с единоверменной доставкой Яндексом в веб и почтовые клиенты it-службы с оттяжокй в 0-96 часов. Вопервых, их можно посчитать.))