栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

使用EVAL,SCAN和DEL的Redis通配符删除脚本返回“非确定性命令后不允许写入命令”

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

使用EVAL,SCAN和DEL的Redis通配符删除脚本返回“非确定性命令后不允许写入命令”

更新: 以下内容适用于3.2之前的Redis版本。从该版本开始,基于效果的复制取消了对非确定性的禁令,因此所有赌注都是关闭(或更确切地说是打开)。

您不能(也不应)将

SCAN
命令族与脚本中的任何写命令混合使用,因为前者的答复取决于内部Redis数据结构,而内部Redis数据结构又是服务器进程所独有的。换句话说,不能保证两个Redis进程(例如主进程和从属进程)返回相同的答复(因此,在Redis复制上下文中(不是基于操作,而是基于语句的)会破坏它)。

Redis的试图通过阻止任何写入命令(例如,以保护自身免受这样的情况下

DEL
),如果它是一个随机命令后执行(例如
SCAN
而且
TIME
SRANDMEMBER
和类似的)。我敢肯定有解决这个问题的方法,但是您想这样做吗?请记住,您将进入未定义系统行为的未知区域。

取而代之的是,接受一个事实,即您不应该将随机的读写混合使用,并尝试考虑一种解决问题的不同方法,即按照原子方式根据模式删除一堆密钥。

首先问问自己是否可以放宽任何要求。它必须是原子的吗?原子性意味着Redis在删除期间将被阻止(无论最终实现如何),并且操作的时间取决于作业的大小(即,删除的键数及其内容[删除大的键比删除短字符串更昂贵]])。

如果不需要原子性,则定期/懒惰

SCAN
并小批量删除。如果必须的话,请理解您基本上是在尝试模仿
邪恶的
KEYS
命令:)但是,如果您事先了解该模式,则可以做得更好。

假设模式在您的应用程序运行时是已知的,那么您可以收集相关的密钥(例如,在Set中),然后使用该集合以原子安全且复制安全的方式实现删除,这比遍历整个密钥空间更有效。

但是,最“棘手”的问题是,您需要在确保原子性的同时运行临时模式匹配。如果是这样,则问题归结为立即获取键空间的按模式过滤的快照,然后立即进行一系列删除(重新强调:阻止数据库时)。在这种情况下,您可以很好地

KEYS
在Lua脚本中使用并希望获得最好的结果(但要知道,您可能
SHUTDOWNNOSAVE
很快就会诉诸:P)。

最后的优化是索引键空间本身。两者

SCAN
KEYS
基本上都是全表扫描,那么如果我们要索引该表怎么办?想象一下,在交易期间可以查询的键名称上保留索引-
您可能可以使用排序集和字典范围(HT @TwBert
)来消除大多数模式匹配需求。但是代价不菲……您不仅要进行双重记账(将每个键的名称成本存储在RAM和CPU中),而且还被迫增加应用程序的复杂性。为什么要增加复杂性?因为要实现这样的索引,您必须自己在应用程序层(以及可能的所有其他Lua脚本)中维护它,因此请在事务中仔细包装对Redis的每个写操作,该事务还会更新索引。

假设您做了所有这些工作(并考虑到了明显的陷阱,例如增加了复杂性的潜在错误,Redis,RAM和CPU的写入负载至少翻了一番,缩放限制等),您可以在肩并祝贺您使用非Redis设计的方式使用Redis。尽管即将发布的Redis版本可能(或可能没有)针对此挑战提供了更好的解决方案(
@TwBert-想要进行RCP / contrib联合并再次破解Redis?
),但在尝试此操作之前,我真的敦促您重新考虑原始要求并确认您正确使用了Redis(即根据数据访问需求设计“模式”)。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/369100.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号