欢迎关注公众号(通过文章导读关注:【11来了】),及时收到 AI 前沿项目工具及新技术的推送!

在我后台回复 「资料」 可领取编程高频电子书

在我后台回复「面试」可领取硬核面试笔记

前言

最近在更新面试突击专栏,我把每一篇将字数都尽量控制在 2000 字以内,可能在文章里边写的没有那么细致,主要是提供一些 问题 以及 回答的思路 ,以及 面试中可能忽略的漏洞 ,所以在看完文章之后,如果自己简历中有这方面的内容的话,一定要认真去整理一份自己的回答,并且多查阅相关资料,如果看的文章少,就会导致学习到的内容太片面

分布式锁、幂等性问题

接下来主要说一下,分布式系统中,在业务以及技术实践中,经常遇到的一些问题


接口有处理幂等性问题吗?

什么时候需要处理 幂等性问题 呢?

就比如 创建订单 场景中,如果因为网络抖动原因,导致请求超时了,此时去重试创建订单操作,发送了 重复请求,那么就可能导致出现了重复创建订单的操作

怎么解决呢?对接口进行 幂等性处理

幂等性处理的解决方案我之前也写过一篇文章,可以参考一下:幂等性处理

具体选择哪一种方案,需要根据自己的业务需求来选

一般不需要对所有的接口都保证幂等性,而是仅仅 对少数的核心接口保证幂等性

比如对于创建类的操作,可以通过 数据库中的唯一索引 来保证幂等性

对于更新类的操作,可以通过 Redis 来保证幂等性



分布式锁问题

先说一下什么时候需要去使用 分布式锁

就比如,多个服务对同一个数据进行操作的时候,为了保证该数据的 并发安全,需要在操作前加上 分布式锁

这里举个分页缓存的例子,在 Redis 中构建一个分页缓存,那么在第一次查询时,会进行分页缓存的构建,如果分页缓存中的数据发生变化,也需要对分页缓存进行构建,如果不加分布式锁,就会出现 数据库和缓存不一致 的问题出现:

  • 当用户 A 新增分享的时候,另一个用户 B 此时正好来查询用户 A 的分享列表,用户 B 线程先去缓存中查询,发现没有,再去数据库中查询用户 A 的分享列表,此时 B 拿到了 A 新增分享之前的旧数据,此时如果用户 A 新增分享并落库,并且去缓存中对用户 A 的列表缓存进行重建,那么此时缓存列表中是用户 A 的最新数据,但是此时用户 B 的线程在数据库中已经查到了用户 A 的旧数据,用户 B 的线程继续执行,将用户 A 的旧数据给放入到列表缓存中,覆盖掉了用户 A 更新的缓存,那么此时就会导致缓存数据库不一致

这个我之前也写过一篇文章,可以查看具体操作:Redis 分页缓存+分布式锁

分布式锁常见的有:Redis 实现的分布式锁、ZooKeeper 实现的分布式锁

那么对于这两种分布式锁实现的 原理 一定要清楚,其中使用 Redis 的分布式锁一般都是用 Redisson 框架提供的,里边的分布式锁的源码,有时间的情况下,真的要好好了解一下!

其实选择分布式锁,使用 Redis 分布式锁比较多,因为 Redis 在高并发场景下的表现比 ZooKeeper 要好一些

而对于 ZooKeeper 分布式锁来说,了解它原理的同时,也要去了解一下存在的 羊群效应 以及如何对羊群效应进行优化!

我在这一篇文章中也写了,可以详细看一下:ZooKeeper 中的分布式读写锁应对羊群效应


如果 Redis 集群故障时,分布式锁会失效吗?

其实是 会失效 的,如果客户端 A 去 Redis 集群中添加分布式锁,先将锁写入到 Redis 的 master 中,如果 master 还没来得及将分布式锁同步到 slave 就宕机了,那么就会导致 slave 中并没有分布式锁的信息,如果客户端 B 来加锁,还是可以加上同一把锁,结果就是客户端 A 和 B 都拿着同一把分布式锁在执行

这种情况解决的话,解决思路是加分布式锁时,必须 master 和 slave 都同时写入分布式锁信息 之后,才算加锁成功,这样就不会出现上边的问题了

这样解决的话,就抛弃了一部分性能,来换取可靠性

不过这种问题出现的概率还是很小的,任何系统设计方案都存在利弊,舍弃一部分对自己业务不重要的可靠性来提升性能或者相反,都是根据自己业务需要来进行选择



分布式锁在高并发场景下的优化问题

如果面试一些互联网大厂,提高分布式锁这块的内容,可能面试官会去问你,有对分布式锁进行过性能优化吗?

这一块的内容,可能大家没有想过这个问题,其实思路也比较简单,就是 分段加锁,目的就是减小你的锁粒度,以此来 提高系统的并发度

就比如,扣减库存,需要添加分布式锁,如果库存有 10000 个,那么可以在数据库中创建 10 个库存字段,stock_1stock_2...,那么每次对库存操作,就对其中的一个库存字段给加锁就可以的,将库存分成了 10 个库存字段,原来一个分布式锁对库存加锁,同一时间只可以一个线程来处理,库存分片之后,同一时间可以有 10 个线程获取分布式锁,并发度提高了 十倍

如果某次来扣减库存时,库存不足的情况下,需要合并库存进行扣减,合并库存就是对其他库存字段加锁,并且查询库存,如果足够,就进行库存扣减操作

总的来说,对分布式锁的优化就是:分段锁 + 合并库存扣减

分布式锁、幂等性问题_缓存