最新通俗讲解分布式锁,看完不懂算我输(2),java锁面试题

Kafka实战笔记

关于这份笔记,为了不影响大家的阅读体验,我只能在文章中展示部分的章节内容和核心截图

image.png

  • Kafka入门
  • 为什么选择Kafka
  • Karka的安装、管理和配置

image.png

  • Kafka的集群
  • 第一个Kafka程序
  • image.png

afka的生产者

image.png

  • Kafka的消费者
  • 深入理解Kafka
  • 可靠的数据传递

image.png

image.png

  • Spring和Kalka的整合
  • Sprinboot和Kafka的整合
  • Kafka实战之削峰填谷
  • 数据管道和流式处理(了解即可)

image.png

  • Kafka实战之削峰填谷

image.png

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

我们如果采用 Redis 作为分布式锁,那么上图中负 “责红包的妹子(服务)”,就可以替换成 Redis,请自行脑补。

1、为什么 Redis 可以实现分布式锁?

首先 Redis 是单线程的,这里的单线程指的是网络请求模块使用了一个线程(所以不需考虑并发安全性),即一个线程处理所有网络请求,其他模块仍用了多个线程。

在实际的操作中过程大致是这样子的:

服务器 1 要去访问发红包的妹子,也就是 Redis,那么他会在 Redis 中通过 “setnx key value” 操作设置一个 key 进去,value 是啥不重要,重要的是要有一个 key,也就是一个标记,而且这个 key 你爱叫啥叫啥,只要所有的服务器设置的 key 相同就可以。

假设我们设置一个,如下图:

img

那么我们可以看到会返回一个 1,那就代表了成功。

如果再来一个请求去设置同样的 key,如下图:

img

这个时候会返回 0,那就代表失败了。

那么我们就可以通过这个操作去判断是不是当前可以拿到锁,或者说可以去访问 “负责发红包的妹子”,如果返回 1,那我就开始去执行后面的逻辑,如果返回 0,那就说明已经被人占用了,我就要继续等待。

当服务器 1 拿到锁之后,进行了业务处理,完成后,还需要释放锁,如下图所示:

删除成功返回 1,那么其他的服务器就可以继续重复上面的步骤去设置这个 key,以达到获取锁的目的。

当然以上的操作是在 Redis 客户端直接进行的,通过程序调用的话,肯定就不能这么写,比如 java 就需要通过 jedis 去调用,但是整个处理逻辑基本都是一样的。

通过上面的方式,我们好像是解决了分布式锁的问题,但是想想还有没有什么问题呢?

对,问题还是有的,可能会有死锁的问题发生,比如服务器 1 设置完之后,获取了锁之后,忽然发生了宕机。

那后续的删除 key 操作就没法执行,这个 key 会一直在 Redis 中存在,其他服务器每次去检查,都会返回 0,他们都会认为有人在使用锁,我需要等。

为了解决这个死锁的问题,我们就需要给 key 设置有效期了。

设置的方式有 2 种:

  • 第一种就是在 set 完 key 之后,直接设置 key 的有效期 “expire key timeout” ,为 key 设置一个超时时间,单位为 second,超过这个时间锁会自动释放,避免死锁。

这种方式相当于,把锁持有的有效期,交给了 Redis 去控制。如果时间到了,你还没有给我删除 key,那 Redis 就直接给你删了,其他服务器就可以继续去 setnx 获取锁。

  • 第二种方式,就是把删除 key 权利交给其他的服务器,那这个时候就需要用到 value 值了,比如服务器 1,设置了 value 也就是 timeout 为当前时间 + 1 秒 ,这个时候服务器 2 通过 get 发现时间已经超过系统当前时间了,那就说明服务器 1 没有释放锁,服务器 1 可能出问题了,服务器 2 就开始执行删除 key 操作,并且继续执行 setnx 操作。

但是这块有一个问题,也就是不光你服务器 2 可能会发现服务器 1 超时了,服务器 3 也可能会发现,如果刚好服务器 2 setnx 操作完成,服务器 3 就接着删除,是不是服务器 3 也可以 setnx 成功了?

那就等于是服务器 2 和服务器 3 都拿到锁了,那就问题大了。这个时候怎么办呢?

这个时候需要用到 “GETSET key value” 命令了。这个命令的意思就是获取当前 key 的值,并且设置新的值。

假设服务器 2 发现 key 过期了,开始调用 getset 命令,然后用获取的时间判断是否过期,如果获取的时间仍然是过期的,那就说明拿到锁了。

如果没有,则说明在服务 2 执行 getset 之前,服务器 3 可能也发现锁过期了,并且在服务器 2 之前执行了 getset 操作,重新设置了过期时间。

那么服务器 2 就需要放弃后续的操作,继续等待服务器 3 释放锁或者去监测 key 的有效期是否过期。

这块其实有一个小问题是,服务器 3 已经修改了有效期,拿到锁之后,服务器 2 也修改了有效期,但是没能拿到锁,但是这个有效期的时间已经被在服务器 3 的基础上有增加一些,但是这种影响其实还是很小的,几乎可以忽略不计。

2、为什么 Zookeeper 可实现分布式锁?

百度百科是这么介绍的:ZooKeeper 是一个分布式的,开放源码的分布式应用程序协调服务,是 Google 的 Chubby 一个开源的实现,是 Hadoop 和 Hbase 的重要组件。

那对于我们初次认识的人,可以理解成 ZooKeeper 就像是我们的电脑文件系统,我们可以在 d 盘中创建文件夹 a,并且可以继续在文件夹 a 中创建文件夹 a1,a2。

那我们的文件系统有什么特点?那就是同一个目录下文件名称不能重复,同样 ZooKeeper 也是这样的。

在 ZooKeeper 所有的节点,也就是文件夹称作 Znode,而且这个 Znode 节点是可以存储数据的。

我们可以通过 “create /zkjjj nice” 来创建一个节点,这个命令就表示,在跟目录下创建一个 zkjjj 的节点,值是 nice。同样这里的值,和我在前面说的 Redis 中的一样,没什么意义,你随便给。

另外 ZooKeeper 可以创建 4 种类型的节点,分别是:

  • 持久性节点

  • 持久性顺序节点

  • 临时性节点

  • 临时性顺序节点

首先说下持久性节点和临时性节点的区别:

  • 持久性节点表示只要你创建了这个节点,那不管你 ZooKeeper 的客户端是否断开连接,ZooKeeper 的服务端都会记录这个节点;

  • 临时性节点刚好相反,一旦你 ZooKeeper 客户端断开了连接,那 ZooKeeper 服务端就不再保存这个节点;

  • 顺便也说下顺序性节点,顺序性节点是指,在创建节点的时候,ZooKeeper 会自动给节点编号比如 0000001,0000002 这种的。

Zookeeper 有一个监听机制,客户端注册监听它关心的目录节点,当目录节点发生变化(数据改变、被删除、子目录节点增加删除)等,Zookeeper 会通知客户端。

四、在 Zookeeper 中如何加锁?

下面我们继续结合我们上面的分红包场景,描述下在 Zookeeper 中如何加锁。

假设服务器 1,创建了一个节点 /zkjjj,成功了,那服务器 1 就获取了锁,服务器 2 再去创建相同的锁,就会失败,这个时候就只能监听这个节点的变化。

等到服务器 1 处理完业务,删除了节点后,他就会得到通知,然后去创建同样的节点,获取锁处理业务,再删除节点,后续的 100 台服务器与之类似。

注意这里的 100 台服务器并不是挨个去执行上面的创建节点的操作,而是并发的,当服务器 1 创建成功,那么剩下的 99 个就都会注册监听这个节点,等通知,以此类推。

但是大家有没有注意到,这里还是有问题的,还是会有死锁的情况存在,对不对?

当服务器 1 创建了节点后挂了,没能删除,那其他 99 台服务器就会一直等通知,那就完蛋了。。。

这个时候就需要用到临时性节点了,我们前面说过了,临时性节点的特点是客户端一旦断开,就会丢失,也就是当服务器 1 创建了节点后,如果挂了,那这个节点会自动被删除,这样后续的其他服务器,就可以继续去创建节点,获取锁了。

但是我们可能还需要注意到一点,就是惊群效应:举一个很简单的例子,当你往一群鸽子中间扔一块食物,虽然最终只有一个鸽子抢到食物,但所有鸽子都会被惊动来争夺,没有抢到…

总结

面试难免让人焦虑不安。经历过的人都懂的。但是如果你提前预测面试官要问你的问题并想出得体的回答方式,就会容易很多。

此外,都说“面试造火箭,工作拧螺丝”,那对于准备面试的朋友,你只需懂一个字:刷!

给我刷刷刷刷,使劲儿刷刷刷刷刷!今天既是来谈面试的,那就必须得来整点面试真题,这不花了我整28天,做了份“Java一线大厂高岗面试题解析合集:JAVA基础-中级-高级面试+SSM框架+分布式+性能调优+微服务+并发编程+网络+设计模式+数据结构与算法等”

image

且除了单纯的刷题,也得需准备一本【JAVA进阶核心知识手册】:JVM、JAVA集合、JAVA多线程并发、JAVA基础、Spring 原理、微服务、Netty与RPC、网络、日志、Zookeeper、Kafka、RabbitMQ、Hbase、MongoDB、Cassandra、设计模式、负载均衡、数据库、一致性算法、JAVA算法、数据结构、加密算法、分布式缓存、Hadoop、Spark、Storm、YARN、机器学习、云计算,用来查漏补缺最好不过。

image

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

用来查漏补缺最好不过。

[外链图片转存中…(img-hfw5je43-1715683268741)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值