存储redis密钥的最佳方式

时间:2014-03-21 00:36:10

标签: c ruby database redis nosql

我使用Redis存储一些信息并检测该信息随时间的变化(例如,考虑用户和位置)。使用更长或更短的键名有什么价值?使用更长的密钥更清晰,但使用更长的密钥名需要大量内存或性能吗?

以下是示例:

SET L:123456 "<name> <latitude> <longitude> ..."
HSET U:987654321 loc 123456 time <epoch>

SET loc:{123456} "<name> <latitude> <longitude> ..."
HSET user:{U987654321} loc 123456 time <epoch>

2 个答案:

答案 0 :(得分:3)

这完全取决于你将如何使用它。 如果每个字节都很重要,例如当您必须为转移到云服务的每个kB付费时,您就可以计算成本。数学很简单;一个字节是'在线上'的一个字节'。在redis中,对于更大的值,它同样简单。对于较小的值,Redis会进行一些内存优化。

在你的HSET示例中,您将成员分开,只有在大多数时候需要将它们分开时才有意义。一个更好的方法 -might - 是:HSET user:data 987654321 '{"loc": "123456", "time": "2014-01-01T13:00:00"}'。单独的键/成员'成本'远远超过更长的字符串,性能明智。您甚至可以将整个表或数据集放在一个成员中,如果它只用作一个完整的半静态实体。

速度和尺寸:之间存在显着差异。

键: 较短的通常是更高的存储器效率以及速度效率。如果您使用redis Sorted Set,您甚至可以使用'数字'作为键(排序集'成员'加'得分')。我说“数字”因为技术上得分是浮点64,但要用作ID,它必须介于-999999999999999和999999999999999之间(包括15位数),没有任何小数部分。这可能非常有用,因为Redis对排序集进行快速且可扩展的O(log(n))动态排序(使用跳过列表,简化)。

值: MsgPack格式(未压缩)占用的空间最小,特别是如果您存储一次定义且值很多。 JSON的内存效率要低一些,但它是一种常见的IPC格式,不应该被忽略。原始字符串,字符分隔,固定长度(ugh),无论您的愿望如何,都可以使用。在将数据存储在Redis中之前,您始终可以压缩数据。到目前为止内存效率。谈到速度,它不那么简单。如果要使用Lua服务器端脚本(应该使用),则无法对压缩数据执行任何操作。 JSON和MsgPack可以反序列化,但只能“作为一个整体”。这在大多数情况下都很好。最灵活的是存储单独的值(例如作为HSET的成员),但这也是有代价的(大多数时候:价格太高)。你也可以结合所有这些。我们最常用的:两个或三个分隔符分隔值的前缀,后跟MsgPack有效负载。

我的一般建议是:从仅使用HSET和ZSET开始,不要拆分属于一起的数据,在10-25个字符之间使用描述性的PascalCased名称,如果你需要键中的分隔符,请使用':' (名称空间),序列化为JSON(为简单起见,但代码易于切换到MsgPack),使用Lua脚本(即使你不知道Lua,你在Redis中使用的子集很小)。

我不会在项目的启动阶段过多地担心它,你可以随时更改它,并在你有一些可插入的数据时立即进行一些A / B比较。

希望这有帮助,TW

答案 1 :(得分:0)

现在Redis v3.2几乎就在这里,您应该考虑切换到新的地理哈希功能:http://redis.io/commands/geoadd