Comments 15
Только мне кажется, что для решения описанной задачи предназначены Message Queues?
Я, может быть, не до конца понял суть задачи; статья всё же написана немного суховато. Я решал, как мне кажется, похожую задачу: надо было по https получать запрос к пикселю-счётчику, расположенному на страницах многих сайтов, и складывать в Cassandra (потом её поменяли на ClickHouse). Запросов могло быть много, данные было очень важно не терять, загрузке страниц этот пиксель должен был не мешать по минимуму. Похоже на ваш кейс?
В итоге была такая конфигурация: за nginx стоял php-fpm, под ним выполнялся скрипт из буквально 15 строк, который брал $_REQUEST
, проверял что в cookie есть user-id, если нет — генерировал новый, устанавливал cookie, отправлял данные в RabbitMQ и завершался. Размер одного сообщения был типа 4 килобайт.
По крону раз в минуту запускался скрипт уже под php-cli, забирал пачками данные из Rabbit и сливал в базу. Сам Rabbit крутился на той же виртуалке. Память fpm была ограничена каким-то смешным количеством, число процессов было типа 10 (как я понимаю сейчас — даже много). Умещалась вся конструкция в 200-рублёвую виртуалку на VScale, 100 rps из Танка выдерживала, 99% ответов умещались в 80ms. Вся работа уложилась в 2 человеко-дня, нагрузка от реальных пользователей, правда, выше 50 rps не поднималась. Собственно всё, на статью для Хабра не тянет, максимум на коммент)
Твою задачу можно решить проксированием каждого хита в ClickHouse прям из nginx, я бы сделал так :)
А uuid кто будет генерировать?)
Запросов могло быть много, данные было очень важно не терять
Из описания ClickHouse, в руководстве:
- транзакции отсутствуют;
- низкие требования к консистентности данных;
Похоже на ваш кейс?
Задачи похожи, но в нашем случае мы действительно ничего не теряем. Так как есть и репликация, и транзакции и балансировка нагрузки.
Я автор GoReplay, спасибо за упоминание :)
Да, для вашей цели post_action пожалуй неплохое решение.
Стоит добавить что задача добавления uuid в GoReplay решается довольно просто с помощью middleware https://github.com/buger/goreplay/tree/master/middleware
Например такая NodeJS программа
var uuidV4 = require('uuid/v4');
var gor = require("goreplay_middleware");
gor.init()
gor.on('request', function(req) {
req.http = gor.setHttpHeader(req.http, "X-Request-ID", uuidV4());
return req;
})
Главный плюс GoReplay в данном случае что это не прокси, он просто анализирует входящий траффик. Не нужно беспокоится что из-за ошибки в прокси будут проблемы у бользователя. Но nginx в этом плане конечно очень надежный.
Ну и конечно GoReplay также может записывать и ответы сервера, и при их проигрывании на другую среду, можно сравнивать ответы оригильные и новые.
Как то так https://goreplay.org :)
Опыт внедрения Tarantool в сервисе Calltouch