答应我,不会这些概念,简历不要写 “熟悉” zookeeper
程序员内点事 人气:0
> 整理了一些Java方面的架构、面试资料(微服务、集群、分布式、中间件等),有需要的小伙伴可以关注公众号【程序员内点事】,无套路自行领取
- [一口气说出 9种 分布式ID生成方式,面试官有点懵了](https://mp.weixin.qq.com/s?__biz=MzAxNTM4NzAyNg==&mid=2247483785&idx=1&sn=8b828a8ae1701b810fe3969be536cb14&chksm=9b859174acf21862f0b95e0502a1a441c496a5488f5466b2e147d7bb9de072bde37c4db25d7a&token=745402269&lang=zh_CN#rd)
- [面试总被问分库分表怎么办?你可以这样怼他](https://mp.weixin.qq.com/s?__biz=MzAxNTM4NzAyNg==&mid=2247483882&idx=1&sn=9e0901dd19e3e06a135fe96780c43477&chksm=9b859117acf218017d9273d4328258c01f6a105180ae8534dc0aaa362cc0c3020dd55de3a95e&token=361009039&lang=zh_CN#rd)
- [一口气说出 6种 @Transactional 注解失效场景](https://mp.weixin.qq.com/s?__biz=MzAxNTM4NzAyNg==&mid=2247483977&idx=1&sn=7d8d3c89bfe2261f6422572dca405990&chksm=9b8592b4acf21ba2a8368bb0cf7fff4d3832ce87da33674372a852034186e2966f27fafde66f&token=1082808293&lang=zh_CN#rd)
- [基于 Java 实现的人脸识别功能(附源码)
](https://mp.weixin.qq.com/s?__biz=MzAxNTM4NzAyNg==&mid=2247483925&idx=1&sn=c83bf51f3c67ce7ea65c3ac7b200a852&chksm=9b8592e8acf21bfe26ab0852aa1028f87fbde355ca3e43186a0be08f223bb25e8e00e91d6ee0&token=285522223&lang=zh_CN#rd)
- [9种分布式ID生成之美团(Leaf)实战](https://mp.weixin.qq.com/s?__biz=MzAxNTM4NzAyNg==&mid=2247483889&idx=1&sn=35b0eb32de3e63c013585ef1db5d3076&chksm=9b85910cacf2181a23bdc1344a1984e3fa7613cc8dd9e28f3b10196fc73b9022d735f4031e88&token=662935248&lang=zh_CN#rd)
#### 唠唠叨叨
本文主要分享一下`zookeeper`的一些基本概念,在正式进入正题前,和大家聊一聊刚入行时我的面试经验,可以说是耿直的有些可爱。
**面试官**:用过`zookeeper` 吗?
**我**:用过啊,给`dubbo`提供服务的注册与发现嘛
**面试官**:知道 `zookeeper` 是什么吗?
**我**:知道啊,注册中心嘛
**面试官**:那你们项目中都是怎么用 `zookeeper` 的?
**我**:就在 `springboot` 的 `application.properties` 配置文件里添加一个 `zookeeper` 服务地址就行了。。。
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200330171333682.gif#pic_center)
.
上边的对话好像也没什么毛病,但似乎又感觉哪里有点不太对,结果就是每次我如此回答面试都被pass。
为什么会被问zookeeper?因为我的简历项目上写着熟练使用zookeeper,可面试官理解的 “熟练” 使用可不是会配置,工程启动不报错那么简单。所以还是有必要全面了解一下zookeeper的相关知识。
---
#### 一、zookeeper初识?
`Zookeeper` 它作为`Hadoop`项目中的一个开源子项目,是一个经典的分布式数据一致性解决方案,致力于为分布式应用提供一个高性能、高可用,且具有严格顺序访问控制能力的分布式协调服务。
##### 1、zookeeper数据模型
`zookeeper` 维护了一个类似文件系统的数据结构,每个子目录(/微信、/微信/公众号)都被称作为 `znode` 即节点。和文件系统一样,我们可以很轻松的对 `znode` 节点进行增加、删除等操作,而且还可以在一个`znode`下增加、删除`子znode`,区别在于文件系统的是,`znode`可以存储数据(严格说是必须存放数据,默认是个空字符)。
由于`zookeeper`是目录节点结构,在获取和创建节点时,必须要以`“/”` 开头,否则在获取节点时会报错 `Path must start with / character`。
```javascript
[zk: localhost:2181(CONNECTED) 13] get test
Command failed: java.lang.IllegalArgumentException: Path must start with / character
```
根节点名必须为`“/XXX”`,创建子节点时必须要带上根节点目录`“/XXX/CCC”`、`“/XXX/AAA”`。
例如:想要获取下图 `程序员内点事` 节点必须拼接完整的路径 `get /微信/公众号/程序员内点事`
```javascript
get /微信/公众号/程序员内点事
```
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200330163601701.png?#pic_center)
`znode`被用来存储 `byte级` 或 `kb级` 的数据,可存储的最大数据量是`1MB`(**请注意**:一个节点的数据量不仅包含它自身存储数据,它的所有子节点的名字也要折算成Byte数计入,因此`znode`的子节点数也不是无限的)虽然可以手动的修改节点存储量大小,但一般情况下并不推荐这样做。
---
##### 2、znode节点属性
一个`znode`节点不仅可以存储数据,还有一些其他特别的属性。接下来我们创建一个`/test`节点分析一下它各个属性的含义。
```javascript
[zk: localhost:2181(CONNECTED) 6] get /test
456
cZxid = 0x59ac //
ctime = Mon Mar 30 15:20:08 CST 2020
mZxid = 0x59ad
mtime = Mon Mar 30 15:22:25 CST 2020
pZxid = 0x59ac
cversion = 0
dataVersion = 2
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 3
numChildren = 0
```
节点属性 | 注解
-------- | -----
cZxid | 该数据节点被创建时的事务Id
mZxid | 该数据节点被修改时最新的事物Id
pZxid | 当前节点的父级节点事务Id
ctime | 该数据节点创建时间
mtime | 该数据节点最后修改时间
dataVersion | 当前节点版本号(每修改一次值+1递增)
cversion | 子节点版本号(子节点修改次数,每修改一次值+1递增)
aclVersion | 当前节点acl版本号(节点被修改acl权限,每修改一次值+1递增)
ephemeralOwner | 临时节点标示,当前节点如果是临时节点,则存储的创建者的会话id(sessionId),如果不是,那么值=0
dataLength | 当前节点所存储的数据长度
numChildren | 当前节点下子节点的个数
我们看到一个`znode`节点的属性比较多,但比较主要的属性还是`zxid`、`version`、`acl` 这三个。
---
**Zxid:**
`znode`节点状态改变会导致该节点收到一个`zxid`格式的时间戳,这个时间戳是全局有序的,znode节点的建立或者更新都会产生一个新的。如果`zxid1`的值 < `zxid2`的值,那么说明`zxid2`发生的改变在`zxid1`之后。每个znode节点都有3个`zxid`属性,`cZxid`(节点创建时间)、`mZxid`(该节点修改时间,与子节点无关)、`pZxid`(该节点或者该节点的子节点的最后一次创建或者修改时间,孙子节点无关)。
`zxid`属性主要应用于`zookeeper`的集群,这个后边介绍集群时详细说。
**Version:**
`znode`属性中一共有三个版本号`dataversion`(数据版本号)、`cversion`(子节点版本号)、`aclversion`(节点所拥有的ACL权限版本号)。
`znode`中的数据可以有多个版本,如果某一个节点下存有多个数据版本,那么查询这个节点数据就需要带上版本号。每当我们对`znode`节点数据修改后,该节点的`dataversion`版本号会递增。当客户端请求该`znode`节点时,会同时返回节点数据和版本号。另外当`dataversion`为 `-1`的时候可以忽略版本进行操作。对一个节点设置权限时`aclVersion`版本号会递增,下边会详细说ACL权限控制。
验证一下,我们修改`/test`节点的数据看看`dataVersion `有什么变化,发现`dataVersion `属性变成了 3,版本号递增了。
```javascript
[zk: localhost:2181(CONNECTED) 10] set /test 8888
cZxid = 0x59ac
ctime = Mon Mar 30 15:20:08 CST 2020
mZxid = 0x59b6
mtime = Mon Mar 30 16:58:08 CST 2020
pZxid = 0x59ac
cversion = 0
dataVersion = 3
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 4
numChildren = 0
```
##### 3、znode的类型
`zookeeper` 有四种类型的`znode`,在用客户端 `client` 创建节点的时候需要指定类型。
```javascript
zookeeper.create("/公众号/程序员内点事", "".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
```
- `PERSISTENT`-持久化目录节点 :client创建节点后,与zookeeper断开连接该节点将被持久化,当client再次连接后节点依旧存在。
- `PERSISTENT_SEQUENTIAL`-持久化顺序节点 :client创建节点后,与zookeeper断开连接该节点将被持久化,再次连接节点还存在,zookeeper会给该节点名称进行顺序编号,例如:/lock/0000000001、/lock/0000000002、/lock/0000000003。
- `EPHEMERAL`-临时目录节点 : client与zookeeper断开连接后,该节点即会被删除
- `EPHEMERAL_SEQUENTIAL`-临时顺序节点 : client与zookeeper断开连接后,该节点被删除,会给该节点名称进行顺序编号,例如:/lock/0000000001、/lock/0000000002、/lock/0000000003。
#### 二、节点的ACL权限控制
`ACL`:即 `Access Control List` (节点的权限控制),通过`ACL`机制来解决`znode`节点的访问权限问题,要注意的是`zookeeper`对权限的控制是基于`znode`级别的,也就说节点之间的权限不具有继承性,即子节点不继承父节点的权限。
`zookeeper`中设置ACL权限的格式由`
加载全部内容