6、分布式

厨子大约 2 分钟数据库原创面试题Redis程序厨

6.Redis分布式

6.0 Redis可以做消息队列吗?

消息队列需要有三种特性

  • 有序性

  • 重复消息处理

  • 消息可靠性

我们使用List 则可以做到上面三条,有序性,重复消息(设置id),然后通过某些关键字实现可靠性(RPOPLPUSH)

基于 Streams 的消息队列解决方案

这个是Redis 专门为消息队列设置的数据类型

可以保证插入有序,并生成唯一id

会使用内部队列来保证可靠性。

6.1 并发访问(原子)

主要使用两种方法实现并发,加锁原子操作

加锁缺点:会降低性能,另一个就是需要加分布式锁,加分布式锁会比较困难。

原子操作主要有两种方法

1.将多条操作合并为一个

比如我们修改库存的情况,获取值-减库存-存值,这就是三个操作,我们可以使用Redis 自带的关键字来使其变为原子操作

INCR/DECR增值和减值

2.使用lua 脚本,使其保证原子性

使用lua 脚本,将减库存的三个操作进行合并,其实保持原子性

6.2 Redis 实现分布式锁

单个节点上的锁

分布式锁的实现需要两个条件

  • 保证加锁和解锁的原子性

  • 在共享存储上设置锁变量,必须保证锁变量的可靠性

实现分布式锁的方法

使用setnx 函数,完成分布式锁

但是这个函数有两个问题

  1. 没有id,有可能 A 加的锁,被B 给解了

  2. 加锁之后,A线程崩溃,导致锁一直未被释放

解决方法,给每个线程设置一个id,解析还需系铃人

给锁的设定设置一个有效时间,到期未解锁,则进行,主动释放。注意上诉操作要保证原子性

多个节点的锁

Redlock 算法的基本思路,是让客户端和多个独立的 Redis 实例依次请求加锁,如果客户端能够和半数以上的实例成功地完成加锁操作,那么我们就认为,客户端成功地获得分布式锁了,否则加锁失败。

缺点是锁比较重,降低业务效率。

http://zhangtielei.com/posts/blog-redlock-reasoning.htmlopen in new window