在一次调用中从redis缓存查询百万个密钥

g0czyy6m  于 2021-06-08  发布在  Redis
关注(0)|答案(2)|浏览(337)

我使用redis作为我的缓存服务器。为了清楚起见,我存储了键值对,比如 'S0007226_2005-07-09': '[15.3462, -1]' . 查询是关于特定键的,而不是基于范围的。对于查询,我使用的是pyredis客户端。
我经常要从缓存中取出100万个密钥。这种查询对于redis来说太重了,最多需要10秒。这里的问题是,查询中n个键的mget是一个o(n)操作(n是查询中的键数)。我已经添加了日志查询时间表。

| Keys   | time(ms)|
| 703732 | 6869.66 |
| 26806  | 277.21  |
| 13180  | 137.41  |
| 400    | 5.83    |
| 2589   | 29.04   |
| 180    | 3.6     |
| 98413  | 1009.84 |
| 151994 | 1524.12 |

这似乎很正常,因为随着按键数量的增加,时间以o(n)的方式增加。另外,我正在使用redis管道将密钥列表分解为10k块。
我想将查询时间缩短到~1秒或更短。如果不是redis,我可以尝试并行请求并合并结果。但考虑到redis只能在单核上工作,我认为这不是一个可行的选择。可能的出路:
去做一些设计上的改变,我不必首先查询一百万个键。
使用其他工具而不是redis来处理负载。
在目前的设置本身进行一些优化,以更好地处理它。
假设我必须从2和3中选一个。我有什么选择。我是否应该尝试其他一些为更高吞吐量而设计的缓存服务器,或者我是否可以在查询/存储或设置中进行一些优化以获得更好的结果。

rbl8hiat

rbl8hiat1#

我认为您不应该同时查询1mn密钥。您应该使用内存缓存和redis缓存构建缓存。
您应该像这样查询:
在本地缓存中搜索
查询redis只为那些不可用的键。
始终使用ttl,ttl将帮助您随着时间的推移分发密钥查询,如果您认为许多密钥可能同时过期,则向ttl添加一个随机增量。
即使这样做后,如果您看到单节点redis的性能问题,也不会使用主副本。考虑到你拥有的钥匙数量,你需要有10多个碎片。

xiozqbni

xiozqbni2#

“如果不是redis,我可以尝试并行请求并合并结果。”
你仍然可以并行请求。创建多主机设置,并在多个主机上共享/分发密钥。然后,您可以并行地从多个主机请求数据。
我还可以从经验中告诉你,没有什么比redis更快的了,因为它完全是内存中的单线程进程。所以在你的问题中#2是非常不可能的。
我宁愿改变设计,即#1。如果没有,那么做一个多主机设置和并行请求。

相关问题