我正在考虑将Redis用于Web应用程序日志记录。我用谷歌搜索有人使用这种方法,将日志转储到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
如何在特定用户的日期时间范围内查询特定类别的结果?
谢谢!
答案 0 :(得分:22)
您需要记住,Redis是一个内存数据库(即使它可以将数据保存到磁盘)。您放入Redis的数据必须适合内存。
您提到的文章中的提议是关于将Redis用作分布式排队系统。工作进程将项目出列并将其写入磁盘,因此Redis内存中没有那么多项目。这种设计有一个缺陷:如果工作进程无法足够快地将数据写入磁盘,Redis内存消耗将会爆炸 - 因此必须受配置(Redis maxmemory参数)或软件限制(在插入时修剪队列,或为空队列满员时。)
现在您的提案确实无法正常工作,因为您在Redis中编写的所有数据都将保留在内存中(即使它们由Redis本身保存到磁盘)。
另一点是你无法查询Redis。 Redis不是关系数据库,它不支持ad-hoc查询机制,只支持涉及先前定义的访问路径的命令。如果要搜索具有不同参数的数据,则必须预测所有可能的搜索,并在插入时构建相关的数据结构(集合,排序集等)。
另一个商店(MongoDB或关系数据库)可能更适合您的用例。
答案 1 :(得分:9)
您可以存储具有以下结构的日志:
"logs:{category}:{userid}:{datetime}" = message
然后请求如下:
"logs:*:{userid}:{datetime}"
或者
"logs:{category}:*:{datetime}"
答案 2 :(得分:2)
Redis位于内存数据存储区中。使用Save或BGSAVE命令可以直接将数据持久保存到磁盘。持久性(RDB / AOF)是存储在内存中的一项功能。
提到的要求是将日志存储到磁盘。使用任何消息队列(如RabbitMQ)而不是内存数据存储区应该简单。 (日志不会吃掉记忆)
生成日志的应用程序可以将它们发布到队列中,并使单独的消费者使用日志消息并将其写入磁盘。
如何在特定用户的日期时间范围内查询特定类别的结果?
每个日志块都应该保存为结构(例如C / C ++),如下所示:
struct log{
long datatime;
string userId;
string message;
string category;
};
将此结构序列化为字符串并将其作为值存储在Redis中。 这些值的关键是: key = userId + DELIMITER + category + DELIMITER + datatime
您可以使用获取所有密钥的功能并将其拆分以获取特定关键字的数据列表。
答案 3 :(得分:0)
如果您使用带有时间戳记的排序集作为分数,则效果很好。缺点是内存问题(如其他答案所述)和您将要进行的手动查询。
如果有人感兴趣,我一直在玩它:https://github.com/hugollm/redis-logs-example