Redis

事务

Redis事务由 MULTI 开启,然后不断输入命令,这些命令不会被执行,直到输入 EXEC 。Redis保证在执行事务时,不会处理其他客户端的请求,但是在执行事务中遇到错误时,不会回滚,也不会停止执行。

另外Redis没有条件更新的语句,因此只能先读数据做判断要更新后再执行事务,然而可能判断完后其他客户端又修改了值,因此引入 watch 指令,如果watch的变量在exec之前被修改了,就不会执行事务。

当然也可以使用Lua脚本,官方说simpler and faster。执行Lua脚本时不会执行其他命令

哨兵

High availability with Redis Sentinel

哨兵用于支持Redis主从实例(不是Redis集群)的高可用。哨兵进程至少3个,最好都分布在不同的机器上。

Redis主节点和从节点的通信是异步的,所以有可能在主节点接收一个写请求后,还没来得及告诉给从节点,就挂了。哨兵重新选择一个主节点后,会丢失之前那次写请求,这是无法避免的。

为了避免错误报告,哨兵需要设置一个参数quorum,只有当quorum个哨兵都认为master挂了以后,才会开始failover。failover需要选举一个leader哨兵(得到过半数投票,和quorum数无关),然后由leader哨兵决定新的master节点。

如果是master节点和其他节点/哨兵通信断了,如果进入failover程序,会有两个节点认为自己是master。所以Redis有参数配置,当master发现自己不能和其他节点通信后,会停止服务,即使自己本身没挂。

Cluster

Scale with Redis Cluster

Redis cluster specification

集群和主从不一样,集群每个节点存储的数据是不同的。Redis集群没有使用consistent hashing,而是hash slot。一共有16384个slot,每个节点会包含一部分slot,当有新的节点加入时,就可以将一些slot的数据转移给新节点。在移动slot的时候,节点同时服务客户端请求。

由于集群每个节点的数据不一样,所以每个节点本身仍然可以有主从结构。

集群没有强一致性,可能会丢失写操作,原因和哨兵一样,是异步 replication。使用 WAIT 命令可以大幅减少写丢失的可能,但仍然没有强一致性,可能会丢失写操作。