2011-12-29 70 views
1

我想在Redis的时间线中存储事件列表。我正在考虑自1970年以来的排序集,以秒为单位作为分数,允许快速查找和范围搜索。在Redis中存储事件时间线

问题是我希望每个事件都代表一个对象,并带有几个键(大约3个),所以我会存储一组有序的ID - 然后应用程序将根据ID。

所以谈话会去是这样的:

> ZRANGEBYSCORE events start end 
1) "16" 
2) "17" 
> HGETALL events:16 
1) "key1" 
2) "val1" 
... 
> HGETALL events:17 
... 

有没有更好的方式来组织或做的事情,将避免为每个结果单独调用应用程序。一切都可以在redis服务器端完成,以避免这种开销?这是一个大问题吗?

PS。我正在使用节点客户端,但我的问题也适用于其他语言。

回答

2

一个显而易见的解决方案是按值而不是按引用努力工作,找回它。所以你的zset可以存储序列化的对象,而不是在这些对象上存储引用。使用节点,JSON易于使用。

现在,如果您需要保留当前结构(例如,因为您的某些对象由各种zsets共享),那么您需要考虑使用rountrips而不是命令。 Redis中昂贵的是往返,而不是O(1)命令本身的执行。

HGETALL不支持可变参数(即只能检索一个散列对象)。但Redis非常擅长处理流水线命令,由于节点的异步特性,这对于node_redis驱动程序来说尤其容易。因此在你的例子中,你只需要2次往返:第一次执行ZRANGEBYSCORE,第二次执行所有HGETALL命令(即在发出第二次HGETALL命令之前不要等待第一次HGETALL命令的结果)。这将是非常有效的。

随着当前的Redis版本(2.4),无法消除第二次往返。

+0

我们使用这种确切的方法来做类似的事情。另外,Redis脚本部门应该让您在单次旅行中完成此操作 – tddmonkey 2011-12-30 10:15:33

+0

将所有这些信息存储在一个字段中是否存在缺陷?就像在rdbms字段中存储csv一样?这仅仅是速度的权衡? – Adam 2011-12-30 13:06:29

+0

当物体很小时没有真正的缺点。当对象较大,并且想要支持部分更新,或者想要从各种容器共享对象时,存在一个缺点。关于你对csv的评论,所有的数据库系统都必须序列化行(mysql,postgreSQL,Oracle等)。它们中的大多数支持可变长度数据(带分隔符或大小前缀)。他们使用的格式是二进制的,优化的,但就复杂性而言,序列化的代价与简单的csv行没有什么不同。 – 2011-12-30 14:24:16

1

你可以字符串化的对象,并将其存储为stringwith JSON.stringify(),然后用JSON.parse()