14

我正在考虑将 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

如何查询特定用户、特定类别的日期时间范围内的结果?

谢谢!

4

4 回答 4

24

您需要记住 Redis 是一个内存数据库(即使它可以将数据持久化到磁盘)。您放入 Redis 的数据必须适合内存。

您提到的文章中的提议是关于使用 Redis 作为分布式排队系统。工作进程将项目出列并将它们写入磁盘,因此 Redis 内存中的项目并不多。这种设计有一个缺陷:如果工作进程无法将数据写入磁盘的速度不够快,Redis 内存消耗将会爆炸 - 所以它必须受到配置(Redis maxmemory 参数)或软件(在插入时修剪队列,或者清空)的限制队列已满)。

现在你的提议并没有真正起作用,因为你在 Redis 中写入的所有数据都将保存在内存中(即使它们是由 Redis 本身持久化到磁盘的)。

还有一点是你不能查询 Redis。Redis 不是关系数据库,它不支持 ad-hoc 查询机制,只支持涉及先前定义的访问路径的命令。如果要搜索具有不同参数的数据,则必须在插入时预测所有可能的搜索并构建相关的数据结构(集、排序集等)。

另一个存储(MongoDB 或关系数据库)可能更适合您的用例。

于 2012-11-01T08:07:42.953 回答
10

您可以使用以下结构存储日志:

"logs:{category}:{userid}:{datetime}" = message

然后请求如下:

"logs:*:{userid}:{datetime}"

或者

"logs:{category}:*:{datetime}"
于 2015-03-24T15:53:27.227 回答
3

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

您可以使用功能来获取所有键并将它们拆分以获取特定关键字的数据列表。

于 2013-11-20T05:00:27.670 回答
0

如果您使用以时间戳作为分数的排序集,则效果很好。缺点是内存问题(如其他答案中所述)和您将要进行的手动查询。

我一直在玩它,以防有人感兴趣:https ://github.com/hugollm/redis-logs-example

于 2019-01-28T11:01:54.347 回答