Redis:使用lua和并发事务

时间:2018-08-13 22:30:00

标签: redis transactions

两个问题

  1. lua脚本真的可以解决所有Redis交易情况吗?
  2. 从一个客户端进行异步事务处理的最佳实践是什么?

让我解释一下,第一个问题

Redis交易受到限制,无法使用unwatch个特定的密钥,并且所有密钥在exec上均不受监视;我们仅限于给定客户的单个正在进行的交易。

我已经看到threads,许多Redis用户声称他们只需要lua脚本。甚至redis官方文档都指出,他们可能会使用lua脚本删除交易。但是,在某些情况下这还不够用,例如最标准的情况:使用redis作为缓存。

假设我们要在redis中缓存持久性数据存储中的一些数据。这是一个快速的过程:

  1. 检查缓存->未命中
  2. 从数据库加载数据
  3. 存储在Redis中

但是,如果在第2步(加载数据)和第3步(存储Redis)之间,另一个客户端更新了数据怎么办?

redis中存储的数据将过时。所以...我们使用redis交易对吗?在从数据库加载之前,我们watch对该密钥进行了加密,如果在存储之前更新了其他密钥,则存储将失败。大!但是,在原子lua脚本中,我们无法从外部数据库加载数据,因此此处不能使用lua。希望我只是错过了一些东西,或者我们的过程有问题。

进入第二期(异步事务)

假设我们有一个socket.io集群,该集群处理各种消息和游戏请求,以实现服务器与客户端之间的高速通信。该集群是用node.js编写的,并适当使用了promise和异步概念。

说两个请求命中了我们集群中的一台服务器,这需要在Redis中加载和缓存数据。从上面使用我们的事务,可以监视多个键,并且多个multi-> exec事务将在一个redis连接上以重叠的顺序运行。一旦第一个执行程序运行,即使其他事务仍在运行,所有监视的键也将被取消监视。这样可以使第二笔交易在应该失败的时候成功。

这些重叠可能发生在同一服务器上发生的完全独立的请求中,或者如果需要同时加载多种数据类型,有时甚至出现在同一请求中。

这里的最佳做法是什么?我们是否需要为每个单独的交易创建一个单独的Redis连接?似乎我们会损失很多速度,并且在这种情况下,我们会看到仅从一台服务器创建了许多连接。

作为替代方案,我们可以使用redlock / mutex锁定代替redis事务,但是相比之下,这很慢。

任何帮助表示赞赏!

1 个答案:

答案 0 :(得分:0)

将查询升级为Redis工程师后,我收到以下消息:

  

杰里米,你好

     

您使用多个后端连接的方法将是处理此问题的预期方法。我们看不到多个后端连接有任何问题,每个后端连接都使用乐观的Redis事务(WATCH / MULTI / EXEC)-“第二笔交易在应该失败的地方成功”的可能性不大。

     

使用LUA不适用于此问题。

     

最好的问候,   Redis实验室团队