Redis:获取所有哈希值的最佳方法

Nik*_*ach 7 python database hash redis

我目前在Redis表中存储大约50k个哈希值,每个哈希值都有5个键/值对.每天一次我运行批处理作业来更新哈希值,包括将一些键值设置为哈希中另一个键的值.

这是我的python代码,它遍历键并将old_code设置为new_code,如果给定哈希值存在new_code值:

pipe = r.pipeline()

for availability in availabilities:
    pipe.hget(availability["EventId"], "new_code")

for availability, old_code in zip(availabilities, pipe.execute()):
    if old_code:
        availability["old_code"] = old_code.decode("utf-8")

for availability in availabilities:
    if "old_code" in availability:
        pipe.hset(
            availability["EventId"], "old_code", availability["old_code"])
    pipe.hset(availability["EventId"], "new_code", availability["MsgCode"])
pipe.execute()
Run Code Online (Sandbox Code Playgroud)

我有点奇怪,我必须两次迭代键才能达到相同的结果,有没有更好的方法呢?

我想弄清楚的另一件事是如何获得具有最佳性能的所有哈希值.以下是我目前的工作方式:

d = []
pipe = r.pipeline()
keys = r.keys('*')
for key in keys:
    pipe.hgetall(key)
for val, key in zip(pipe.execute(), keys):
    e = {"event_id": key}
    e.update(val)
    if "old_key" not in e:
        e["old_key"] = None
    d.append(e)
Run Code Online (Sandbox Code Playgroud)

所以基本上我keys *然后迭代HGETALL所有键来获取值.这太慢了,尤其是迭代.有更快的方法吗?

Kar*_*all 7

一个不理想的变化怎么样?转置存储数据的方式.

而不是每个有5个值的50k哈希值.有5个哈希,每个哈希值为50k.

例如,你的哈希依赖于eventid,你将new_code,old_code和其他内容存储在该哈希中

现在,对于new_code有一个哈希映射,它将包含作为成员的eventid,它的值为value.所以new_code就是一个包含50k成员值对的哈希映射.

因此,循环5而不是50k将相对更快.

我做了一个小实验,以下是数字

50k hashes * 5 elements 
Memory : ~12.5 MB
Time to complete loop through of elements : ~1.8 seconds

5 hashes * 50k elements
Memory : ~35 MB
Time to complete loop through of elements : ~0.3 seconds.
Run Code Online (Sandbox Code Playgroud)

我已经使用KEY_i和VALUE_i这样的简单字符串进行了测试(其中i是增量器),因此在您的情况下内存可能会增加.而且我刚刚浏览了数据,我没有做过任何操作,所以时间也会因你的情况而有所不同.

正如您所看到的,此更改可以为您提供5倍的性能提升,以及2倍的内存.

Redis对范围内的哈希进行压缩(512 - 默认值).由于我们存储的范围超过了这个范围(50k),因此内存中会出现这种峰值.

基本上这是一个权衡,你可以选择最适合你的应用程序.

对于你的第一个问题:

  1. 你在每个哈希中得到new_code的值,现在你把所有东西都放在一个哈希中 - >只需一次调用.
  2. 然后你逐个更新old_code和new_code.现在,您可以使用单个调用使用hmset来完成它们.

希望这可以帮助.