Sergei_Erjemin
@Sergei_Erjemin
Улыбайся, будь самураем...

Где лучше хранить глобальный циклический буфер посещений(посетителей) сайта?

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

Например (1), просто в файле. Типа циклического лога. При обращении к странице раз читаем файл, обрабатываем (сами или библиотеками) и записываем в тот же файл. Файловых операций две: одна на чтение, второй раз на запись.

Можно тоже самое проделывать с базой (2). Завести таблицу и в нее при каждом обращении к странице добавлять запись, и удалять самую старую. Минус -- в базе накапливается мусор (удаленные записи на самом деле все еще там, и чтобы база не "пухла" понапрасну ее иногда придется чистить.

Более извратный способ -- хранить циклический буфер как файл, но в базе (3). Завести строку с одним полем пожирнее, и в нем, как в файл варианта 1, все складываем. Один SELECT, один UPDATE.

Понятно, что в случаях 1 и 3 сколько-то ресурса сожрет разбор этого циклического буфера. И это время поможет сэкономить вариант 2. Но, допустим, что этим можно временем пренебречь. Какой вариант предпочтительнее/правильнее/распространёнее?? Может еще есть варианты? Буфер небольшой, нагрузки умеренные, городить всякие внешние службы очередей не хочется.
  • Вопрос задан
  • 262 просмотра
Решения вопроса 1
@nirvimel
Не надо ничего удалять.
Одна специальная запись (в отдельной таблице) будет хранить номер (первичный ключ) последней записи в логе.
На добавление новой записи в лог расходуется ровно один UPDATE (первичный ключ извлекается подзапросом), после чего номер последней записи инкрементируется и берется остаток по модулю равному количеству записей лога в ротации. Если СУБД позволяет, то идеально было бы сделать это на триггере апдейта в таблицу лога, тогда эти апдейты со стороны клиента становятся полностью атомарными, их больше ненужно заворачивать в транзакции, можно выполнять в любом порядке, в отложенном режиме (не дожидаясь ответа сервера) если драйвер БД это допускает (это может сильно увеличить производительность).

Что касается файла: если вы не являетесь экспертом в различных режимах fsync и атомарности дисковых транзакций, то не советую заниматься частой перезаписью файла с ценные данными. На этом обожглись многие разработчики СУБД не говоря уже о прикладных кодерах. (когда кажется, что последовательность дисковых операций просто не допускает возможности базе остаться в инвалидном состоянии, но все равно после падения база каким-то образом оказывается в инвалидном состоянии).
Ответ написан
Пригласить эксперта
Ответы на вопрос 3
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
Файлы тут не годятся однозначно, ибо не поддерживают атомарную вставку/удаление строк. Вам придётся полностью блокировать файл на чтение/запись, иначе будут происходить конфликты версий и часть информации потеряется. То же самое и для blob-записи в базе данных.
Так что оптимальный вариант - стандартная таблица БД с очисткой по крону/триггеру самой БД.
Ответ написан
leahch
@leahch
3Д специалист. Долго, Дорого, Дерьмово.
Про redis.io еще никто не сказал? Тогда я первый - https://redislabs.com/ebook/redis-in-action/part-2...
Прикрутить к джанго - 5 минут.
Ответ написан
Sanasol
@Sanasol
нельзя просто так взять и загуглить ошибку
Зачем такой акцент на циклическости?

Хранить где угодно, "цикличность" добавляется регулярной очисткой файла/базы по крону.
Либо на уровне кода выбирать нужный период из базы.

Зависит от того что вам надо хранить и для каких целей.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы