Redis06——分布式锁与Redis扩容

236 阅读3分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

为什么使用setnx

为什么使用setnx

1,原子操作(若没有setnx则需要使用事务,通信延时) set

2,使用分布式锁,要用set(key,value,EX,timeout,NX) (过期时间、value为"UUID+TreadID"、lua脚本原子删除)

使用分布式锁的要点

  1. 使用 set 命令设置锁标记必须有超时时间,(使得持有锁的应用崩溃也可以释放锁不会造成死锁);
  2. 每个获取锁的客户端设置的 value 必须是独一无二的防止锁被其他线程误删);
  3. 使用LUA脚本保证原子性来删除锁
  4. 对于不需要超时时间的情况,可以设置不断刷新锁超时时间的线程
  5. 为了保证集群的锁不会出现超时的情况,必须合理设置网络等待时间和锁超时时间。
  6. 分布式集群中,直接每台机器设置一样的超时时间和锁标记防止数据同步延迟丢失锁,);

这个分布式锁满足如下四个条件:

  1. 任意时刻只能有一个客户端持有锁;
  2. 不能发生死锁,有一个客户端持有锁期间出现了问题没有解锁,也能保证后面别的客户端继续去持有锁;
  3. 加锁和解锁必须是同一个客户端,客户端自己加的锁只能自己去解;
  4. 只要大多数 Redis 节点正常,客户端就能正常使用锁。

总结:分布式锁的使用,使用set命令将redis未命中的数据作为key存入缓存作为锁,只有锁设置成功时才能访问数据库。(注意设置key的过期时间value设置为唯一标志防止锁被误删,“UUID+ThreadID”,使用LUA脚本原子性删除锁)【set key value ex 100 nx】 value: 通常存储加锁方的唯一标记,如 “UUID+ThreadID”

【set key value ex 100 nx】 (注意设置key的过期时间value设置为唯一标志防止锁被误删,使用LUA脚本原子性删除锁)

Redis怎么扩容?

Redis持久化数据和缓存怎么做扩容?

如果Redis被当做缓存使用,使用一致性哈希实现动态扩缩容

如果Redis被当做持久化存储使用必须使用固定的keys-to-nodes映射关系节点的数量不能变化。否则的话,必须使用Redis集群在运行时进行数据再平衡

一致性哈希分布式系统对象与节点的映射关系,传统方案是使用对象的哈希值对节点个数取模,再映射到相应编号的节点,这种方案在节点个数变动时,绝大多数对象的映射关系会失效而需要迁移;而一致性哈希算法中,当节点个数变动时,映射关系失效的对象非常少,迁移成本也非常小