我仍然认为使用KEYS 与Redis是无法伸缩的, 不论你设置什么聪明的计谋 来进行线性复杂的工作。
分割是这种方案之一,传统RDBMS通常用于降低平板桌上的表扫描费用。你的想法实际上是将这一概念改成 Redis 。
但是,与提供这种设备的传统 RDBMS 相比,有一个重大差异( Oracle, MySQL,...): Redis 是单轨事件循环。 因此扫描无法与任何其他活动同时进行( 比如为其他客户端连接服务 ) 。 当 Redis 扫描数据时, 它会被所有连接屏蔽 。
您需要设置大量分区( 数据库) 才能取得良好的性能。 类似 1/ 1000 或 1/ 1000, 类似全球密钥数的 1/ 1000 。 这就是为什么它无法缩放 : Redis 不是设计来处理如此多的数据库的。 您可能会遇到所有数据库中循环的内部机制的问题 。 从源代码中提取的列表如下 :
- automatic rehashing
- item expiration management
- database status logging (every 5 secs)
- INFO command
- maxmemory management
您可能不得不限制数据库的数量, 从而限制可缩放性。 如果您设置了1000个数据库, 比如 1M 项, 工作正常, 10M 项将较慢, 100M 项无法使用 。
如果您仍想继续使用线性扫描来执行此设备, 支持同时扫描的其他仓库( 如 MySQL、 MOngoDB 等) 将更好地为您服务。 对于其他仓库, 关键点将是高效执行项目到期 。
如果您真的需要使用 Redis, 您可以在不依赖多个数据库的情况下很容易地分割数据。 例如, 您可以使用我描述的 https:// stackoverflow. com/ questions/ 9127736/ redis- sorded- set- and- best- way- to- storee- uids/ 9195219# 9195219 > 的方法。 有了这个策略, 密钥列表会以渐进的方式检索, 而搜索实际上是在客户端完成的 。 主要的好处是您可以拥有大量的分区, 这样Redis 就不会屏蔽 。
现在, AFAIK 没有存储引擎能够以任意的常规表达式(即避免线性扫描)有效地搜索数据。 但是,这个功能是由一些搜索引擎提供的,通常使用n-grog 索引。
http://swtch.com/~rsc/regexm/regexp4.html" rel=“不跟随 Noreferrer”>http://swtch.com/~rsc/regexp/regexp4.html
这个索引机制也许可以适应Redis(您会使用 Redis 存储键的字串索引), 但它代表着许多要写入的代码 。
您也可以想象将正则表达式限制在前缀搜索中。 例如 U: SMITH: (. *) 实际上是用前缀 U: SMITH 搜索 :
在此情况下, 您可以使用 zset 来索引您的密钥, 并在客户端进行线性搜索, 一旦您感兴趣的密钥范围被检索到 。 zset 中项目的评分是从客户端的密钥中计算出来的, 这样得分顺序与密钥的字典顺序相对应 。
有了这样的 zset, 就可以通过 zscore 和 zrange 命令的组合来获取您要逐块扫描块块的钥匙范围 。 其后果是扫描的钥匙数量有限( 按前缀), 搜索在客户端进行, 并且与 Redis conconconmotion 模式友好。 缺点在于复杂性( 特别是处理项目到期) 和网络带宽消耗 。