Redis для регистрации
Я думаю об использовании Redis для целей регистрации веб-приложений. Я гуглил, что есть люди, использующие этот подход, выкидывающие журналы в очередь / список Redis, а затем запланированный рабочий для записи на диск.
http://nosql.mypopescu.com/post/8652869828/another-redis-use-case-centralized-logging
Я хочу понять, почему бы не использовать Redis для сохранения на диске? Если я выделил небольшой сервер, на который Redis будет писать, отдельно от базы данных, сервер приложений, возможно ли использовать Redis для непосредственного сохранения журналов?
Мне также нужна помощь в запросе Redis по дате, пользователю и т. Д. Например, каждый журнал выглядит следующим образом.
datetime=>2012-03-24 17:45:12
userid=>123
message=>test message
category=>my category
Как я могу запросить результаты в пределах диапазона времени / даты, определенного пользователя, определенной категории?
Спасибо!
3 ответа
Необходимо помнить, что Redis - это база данных в памяти (даже если она может сохранять данные на диске). Данные, которые вы помещаете в Redis, должны помещаться в память.
Предложение в статье, которую вы упоминаете, касается использования Redis в качестве распределенной системы очередей. Рабочие процессы исключают элементы из очереди и записывают их на диск, поэтому в памяти Redis не так много элементов. У этой конструкции есть недостаток: если рабочие процессы не могут записать данные достаточно быстро на диск, потребление памяти Redis возрастет - поэтому оно должно быть ограничено конфигурацией (параметр Redis maxmemory) или программным обеспечением (обрезать очередь во время вставки или пустым). очередь, когда она заполнится).
Теперь ваше предложение не работает, поскольку все данные, которые вы пишете в Redis, будут храниться в памяти (даже если они сохраняются на диске самим Redis).
Другое дело, что вы не можете запросить Redis. Redis не является реляционной базой данных, он не поддерживает механизм специальных запросов, а только команды с предварительно определенными путями доступа. Если вы хотите искать данные с разными параметрами, вы должны предвидеть все возможные поиски и создавать соответствующие структуры данных (набор, отсортированные наборы и т. Д.) Во время вставки.
Другой магазин (MongoDB или реляционная база данных), вероятно, будет гораздо лучше подходить для вашего случая использования.
Вы можете хранить журналы со следующей структурой:
"logs:{category}:{userid}:{datetime}" = message
И затем запросите это следующим образом:
"logs:*:{userid}:{datetime}"
Или же
"logs:{category}:*:{datetime}"
Redis находится в хранилище данных памяти. Прямое сохранение данных на диск возможно с помощью команды Сохранить или BGSAVE. Постоянство (RDB/AOF) является функцией в дополнение к хранению в памяти.
Упомянутое требование - хранить журналы на диске. Использование любой из очередей сообщений (например, RabbitMQ) вместо хранилища данных в памяти должно упростить задачу. (логи не будут кушать память)
Приложения, генерирующие журналы, могут публиковать их в очередях, а отдельные потребители потребляют сообщения журнала и записывают их на диск.
Как я могу запросить результаты в пределах диапазона времени / даты, определенного пользователя, определенной категории?
Каждый блок журнала должен быть сохранен как структура (например, C/C++) примерно так:
struct log{
long datatime;
string userId;
string message;
string category;
};
Сериализуйте эту структуру в строку и сохраните ее в Redis как значение. Ключи для таких значений будут выглядеть так: key = userId + DELIMITER + category + DELIMITER + datatime
Вы можете иметь функцию, которая возвращает все ключи и разделяет их, чтобы получить список данных для вашего конкретного ключевого слова.
Это работает довольно хорошо, если вы используете отсортированный набор с отметкой времени в качестве оценки. Недостатками являются проблема с памятью (как упоминалось в других ответах) и ручные запросы, которые вы будете выполнять.
Я играл с этим, на случай, если кому-то будет интересно: https://github.com/hugollm/redis-logs-example