redis执行失败后的处理

以前工作那会儿,总是在很纠结redis执行失败了怎么处理。最主要的是两个问题

  1. redis执行失败了怎么处理程序?
  2. redis事务中间有一条或者某几条数据执行失败了怎么处理?特别是redis事务,一直强调redis事务执行的时候不支持事务回滚,中间某一条命令执行失败后,后面的命令会继续执行,这导致我一直存在一个很大的疑惑,这不会导致数据偏差吗?比如一个事务三条语句,incr key三次,如果key初始值是1,incr key三次是得到的结果是4,如果有一次命令执行失败了,得到的结果就是3,这样存在的数据便宜,会导致问题都很难查找,就算找到了问题所在,要去实际生产环境种恢复数据都很麻烦,总不能先暂停生产环境,去恢复数据,然后再开系统吧。

今天认真思考了这两个问题,总结了一下redis的设计思路和执行失败后的处理,特别是第二种情况下的原因及处理。


对于问题1:

redis执行失败了怎么处理程序?

redis执行失败分两种情况,

  1. 网络问题,命令发送失败。
  2. redis本身故障导致访问不了。
  3. 命令或者数据不符合要求。

对于第一种情况和第二种情况,redis的连接一旦失败,系统不提供自动重连功能,这样的好处就是这一条连接故障,命令失败,不会导致突然又能连接上执行后面的命令,重连过程需要程序和运维来保障,不会引起数据错误。

对于第三种情况,命令或者数据不符合要求导致失败,redis的思维是把此问题抛给程序员,要在程序编写简单认真检查测试。


对于问题2:

redis事务中间有一条或者某几条数据执行失败了怎么处理?特别是redis事务,一直强调redis事务执行的时候不支持事务回滚,中间某一条命令执行失败后,后面的命令会继续执行,这导致我一直存在一个很大的疑惑,这不会导致数据偏差吗?比如一个事务三条语句,incr key三次,如果key初始值是1,incr key三次是得到的结果是4,如果有一次命令执行失败了,得到的结果就是3,这样存在的数据便宜,会导致问题都很难查找,就算找到了问题所在,要去实际生产环境种恢复数据都很麻烦,总不能先暂停生产环境,去恢复数据,然后再开系统吧。

首先我们来看redis的事务执行:

multi命令开始,exec命令结尾,这就是一个redis的完整事务。我们把问题种的事务写成语句

set key 1
multi
incr key
incr key
incr key
exec

我们来看一看发生错误的情况:

  1. exec还没执行成功的时候发生错误。
  2. exec执行成功了,但是还是发生了错误。

我们来分析这两种情况发生的原因

    首先是网络或者redis本身原因,导致redis没用收到exec命令。此时redis放弃整个事务,不执行。理由很简单,事务都没用结束,故障了,没有必要执行。

    其次是exec执行成功了,但是由于语句语法错误导致执行失败,那就跳过这一条失败的语句,继续执行下一条语句。一直到事务执行完成。redis不提供失败回滚的原因,首先,不会由于网络原因等其他情况导致命令没有收到,一个完整的事务所有命令都收到了,那说明redis已经有明确指示,redis按照命令执行就好。如果由于语法错误导致命令失败,那就是程序员本身代码问题,不能因为程序员自身问题,来要求redis提供更多的操作。

由此redis的哲学我们就知道得很清晰了,redis保障收到事务(一组消息),至于命令正确与否,那是程序员要保证的问题,没有收到的消息或者收到一半就放弃不执行,redis保证执行速度。所有命令和数据的正确与否有程序员把握,redis本身只负责根据数据来刷新自己管理的内存。这种设计思路就像流水线,下面的工人是不负责检查上一道工序是否合格,他觉得做得了就做,做不了就扔了。

===================================================================

留个联系方式:[email protected]

公众号:ghost20036 

公众号二维码:

如果谁有软件方面的问题,技术或者工作上的问题,可以一起探讨。

猜你喜欢

转载自blog.csdn.net/ghossst2003/article/details/109212853