一尘不染

存储Redis密钥的最佳方法

redis

我正在使用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>

阅读 455

收藏
2020-06-20

共1个答案

一尘不染

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

在您的HSET示例中,您拆分了成员,这仅在大多数情况下需要将它们彼此分离时才有意义。更好的方法 -might- 是:HSET user:data 987654321 '{"loc": "123456", "time": "2014-01-01T13:00:00"}'。出于性能考虑,单独的键/成员比较长的字符串“花费”更多。如果仅将整个表或数据集用作一个完整的半静态实体,则甚至可以将其放在一个成员中。

速度和大小: 之间存在显着差异。

关键: 较短的内存通常更有效地提高存储效率,并提高速度。如果您使用redis Sorted
Set
,甚至可以使用“数字”作为键(已排序的“成员”加“分数”)。我说“数字”是因为分数从技术上讲是float64,但要用作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

2020-06-20