Redis分布式锁,异步队列,做持久化,同步机制

 Redis 分布式锁

  • SETNX(SET If Not Exists):当且仅当 Key 不存在时,则可以设置,否则不做任何动作。
  • SETEX:可以设置超时时间
  • GETSET命令:设置新值并返回旧值,以此来释放锁或解决死锁。 原理是删除锁或将原来的锁值替换成新值。

其原理为:通过 SETNX 设置 Key-Value 来获得锁,随即进入死循环,每次循环判断,如果存在 Key 则继续循环,如果不存在 Key,则跳出循环,当前任务执行完成后,删除 Key 以释放锁。这种方式可能会导致死锁,为了避免这种情况,需要设置超时时间。

值得一提的是Redis 官方推荐 Redlock 来实现分布式锁     ,能够解决之前redis分布式锁的以下缺陷

  1. 高并发的情况下,如果两个线程同时进入循环,可能导致加锁失败。
  2. SETNX 是一个耗时操作,因为它需要判断 Key 是否存在,因为会存在性能问题。

基本逻辑

多节点redis实现的分布式锁算法(RedLock):有效防止单点故障
假设有5个完全独立的redis主服务器
1.获取当前时间戳
2.client尝试按照顺序使用相同的key,value获取所有redis服务的锁,在获取锁的过程中的获取时间比锁过期时间短很多,这     是为了不要过长时间等待已经关闭的redis服务。并且试着获取下一个redis实例。
   比如:TTL为5s,设置获取锁最多用1s,所以如果一秒内无法获取锁,就放弃获取这个锁,从而尝试获取下个锁
3.client通过获取所有能获取的锁后的时间减去第一步的时间,这个时间差要小于TTL时间并且至少有3个redis实例成功           获取锁,才算真正的获取锁成功
4.如果成功获取锁,则锁的真正有效时间是 TTL减去第三步的时间差 的时间;比如:TTL 是5s,获取所有锁用了2s,                  则真正锁有效时间为3s(其实应该再减去时钟漂移);
5.如果客户端由于某些原因获取锁失败,便会开始解锁所有redis实例;因为可能已经获取了小于3个锁,必须释放,               否则影响其他client获取锁

 Redis 异步队列

Redis的队列list是有序的且可以重复的,作为消息队列使用时可使用rpush/lpush操作入队,使用lpop/rpop操作出队。当发布消息是执行lpush命令,将消息从列表左侧加入队列。消息接收方执行rpop命令从列表右侧弹出消息。

  • Redis 的 list(列表) 数据结构常用来作为异步消息队列使用,
  • 使用rpush/lpush操作入队列,使用lpop 和 rpop来出队列。rpush 和 lpop 结合 或者lpush 和rpop 结合;

   Redis提供了两种方式来做消息队列,一种是生产消费模式,另一种是发布订阅模式。

 

 Redis 做持久化

  •  1、RDB持久化方式能够在指定的时间间隔能对你的数据进行快照存储。
  •  2、AOF持久化方式(追加)记录每次对服务器写的操作
  • Redis分布式锁,异步队列,做持久化,同步机制_第1张图片

 Redis 同步机制

  • Redis的复制功能分为同步(sync )和命令传播( command propagate )两种操作模式: 
  • 前者有RDB持久化的影子, 后者则是主服务接收写命令的同步,有AOF的影子

1.1 同步

当客户端向从服务器发送SLAVEOF命令,要求从服务器复制主服务器时,从服务器首先需要执行同步操作,也即是,将从服务器的数据库状态更新至主服务器当前所处的数据库状态。

从服务器对主服务器的同步操作需要通过向主服务器发送SYNC命令来完成,以下是SYNC命令的执行步骤:

  1. 从服务器向主服务器发送SYNC命令。
  2. 收到SYNC命令的主服务器执行BGSAVE命令,在后台生成一个RDB文件,并使用一个缓冲区记录从现在开始执行的所有写命令。
  3. 当主服务器的BGSAVE命令执行完毕时,主服务器会将BGSAVE命令生成的RDB文件发送给从服务器,从服务器接收并载人这个RDB文件,将自己的数据库状态更新至主服务器执行BGSAVE命令时的数据库状态。
  4. 主服务器将记录在缓冲区里面的所有写命令发送给从服务器,从服务器执行这些写命令,将自己的数据库状态更新至主服务器数据库当前所处的状态。

1.2 命令传播

在同步操作执行完毕之后,主从服务器两者的数据库将达到一致状态,但这种一致并不是一层不变的,每当主服务器执行客服端发送的写命令时,主服务器的数据库就有可能会被修改,并导致主从服务器状态不再一致。

为了让主从服务器再次回到一致状态,主服务器需要对从服务器执行命令传播操作:主服务器会将自己执行的写命令,也即是造成主从服务器不一致的那条写命令,发送给从服务器执,行,当从服务器执行了相同的写命令之后,主从服务器将再次回到一致状态

你可能感兴趣的:(redis)