终篇!面试中可能会遇到的 ZooKeeper 问题

终篇!面试中可能会遇到的 ZooKeeper 问题

本文做者:HelloGitHub-老荀html

本文是 HelloZooKeeper 系列的最后一篇文章,接下来主要聊聊面试中若是被问到 ZooKeeper 的问题如何回答,也能够看成学完本系列的测试。node

准备好了吗?面试开始喽~「首发于 HelloGitHub 公众号」面试

1、模拟面试

终于来到重头戏了,本小节我会从网上找到一些关于 ZK 的面试题进行剖析讲解,而且站在面试官的基础上分析考点,相信看完这一节,出去面试再碰到 ZK 相关的问题你便能披荆斩棘、所向披靡!算法

我先给你们模拟一个面试的场景:数据库

面试官:我看你简历上用过 ZK,能给我介绍下吗?你是怎么理解 ZK 的做用呢?apache

(若是你把百度百科中的定义背给他听,我只能说 666,但千万别这样)编程

:个人理解 ZK 是一个脱离于应用的第三方进程,相似的数据库,消息队列,Redis 等都是扮演这个角色,拥有必定的数据存储和查询能力,可让咱们在如今都是分布式部署的应用之间“传递”数据,其次 ZK 支持的回调通知,让应用能够在一些业务场景中感知到数据的变化并及时做出相应的反应。最后,ZK 自己也支持集群部署具备高可用的特色,是一个可靠的第三方中间件。缓存

面试官:嗯,你刚刚提到了回调通知,能仔细跟我聊聊 ZK 是怎么去实现的吗?安全

:各类编程语言的客户端都会对这个回调通知进行抽象,一般须要开发者声明一个 callback 的对象,在 Java 的客户端中这个接口是 Watcher,ZK 服务端提供了一些方法,好比 getDataexists 或者最新版本中的 addWatch 均可以用来向 ZK 注册回调通知,而向服务端发送的回调通知,只会告诉服务端我当前的这个路径须要被通知,服务端得知后,会在内存中记录下来,路径和客户端之间的关系,客户端本身也须要记录下来,路径和具体回调的关系。当被订阅的路径发生事件的时候,各类增删改吧,服务端就会从内存中的记录去查看有没有须要通知的客户端,有的话会发送一个通知的请求给客户端,客户端收到通知后,就会从本地的记录中取出对应的回调对象去执行 callback 方法!markdown

(实际状况,我以为面试官可能不会让你一直说下去,应该是互相聊的一个状态)

面试官:嗯,说得挺详细,那你刚刚提到的 getDataexistsaddWatch 三种注册有什么区别吗?

getDataexists 以及 getChildren 注册的通知都是一次性的,当服务端通知过一次后,就会删除内存中的记录,以后若是仍然须要通知的话,客户端就要去继续注册,而 addWatch 注册的回调通知是永久性的,只须要注册一次能够一直被通知。

面试官:嗯好,你刚刚还提到了 ZK 有必定的数据存储能力,你能说说 ZK 是怎么保存和整理数据的吗?

:ZK 的数据体如今两部分。

面试官:哦?哪两部分?

:内存中和磁盘上。

面试官:那你先说说内存里 ZK 是怎么存储数据

:从逻辑上来说,ZK 内存中的数据实际上是一个树形结构,从 / 根节点开始,逐级向下用 / 分割,每个节点下面还能够有多个子节点,就相似于 Unix 中的目录结构,但在实际中,ZK 是使用一个 HashMap 去存储整个树形结构的数据的,key 是对应的全路径字符串,value 则是一个节点对象,包含了节点的各类信息。

面试官:能说说你以为为何要这么设计吗?

(其实我以为通常面试官不会这么问,如下回答也是我我的的猜测)

:首先 HashMap 查询速度很快,是 Java 标准库中一个很是重要的数据结构,在许多地方都有用到。ZK 自己并不须要排序或者是范围求值的操做,因此 HashMap 彻底能够知足查询的需求。至于为何逻辑上要设计成树形结构,父子节点,这个多是由于这个结构和 Unix 文件系统很像,很是便于理解以及基于路径进行数据的分类,并且最新的 ZK 中有一些功能是依赖了父子递归这个特性的(好比 addWatch),若是是普通的 key-value 是没法知足的。

面试官:嗯好,那你再说说磁盘上 ZK 是怎么存储数据的呢?

:ZK 在磁盘上规定了两种文件类型,一种是 log 文件,一种是 snapshot。log 文件是增量记录,负责对每个写请求进行保存,snapshot 文件是全量记录,是对内存的快照。

面试官:ZK 是怎么保证内存中的数据和磁盘中的数据的一致性呢?

:真正的强一致性,ZK 没法保证。对于每一次的写请求,ZK 是采起先记录磁盘再修改内存的,因此保证了若是出现意外的话,优先记录磁盘能够尽量的保证数据的完整。若是 ZK 是正常退出的话,也会强制刷磁盘文件和生成 snapshot,保证了一致性,但若是是非正常退出的话,极端状况下的一部分数据是会丢失的。

面试官:你刚刚也提到了 ZK 自己也能够集群部署的?能多聊一点吗?

:ZK 的配置文件 zoo.cfg 中能够配置其余节点的信息,各个节点经过 dataDir 目录下的 myid 文件进行区分,不一样节点之间能够相互通讯,客户端连上集群中的任意一个节点均可以进行通讯。

面试官:ZK 集群中有几种不一样的角色?你知道吗?

:有 Leader、Follower、Observer 三种角色。

面试官:说说他们之间的区别吧

:集群中有且只能有一个 Leader,Leader 负责对整个集群的写请求事务进行提交,在一个集群选出 Leader 以前是没法对外提供服务的。Follower 和 Observer 都只能处理读请求,区别是 Follower 有投票权能够参与 Leader 的竞选,Observer 没法参与 Leader 的竞选。

面试官:那你能够跟我讲讲,选举 Leader 依靠哪些信息吗?

:每个节点都会维护三个最重要的信息:epoch、zxid、myid。epoch 表明选举的轮次,优先比较,若是相同则继续比较下一级。zxid 表明本节点处理过的最大事务 ID,越大表明当前节点经手的写请求越多,知道的也就越多,第二优先级比较,若是还相同则比较 myid,myid 整个集群中不能重复,因此最终必定能分出胜负。胜利的节点当选 Leader。

(准确的说,epoch 和 zxid 是一个字段,一个记录在高 32 位,一个记录在低 32 位)

面试官:不一样节点之间怎么通讯呢?怎么去进行选举?

:每个 ZK 节点在启动的时候,会经过读取配置文件中的集群信息,与其余节点创建 Socket 链接,集群间的通讯就是经过这个 Socket。每一个节点选举的时候都把本身认为的候选人信息广播出去,同时也接收来自其余节点的候选人信息,经过比较后,失败的一方会更改本身的候选人信息并从新进行广播,反复直到某一个节点获得半数以上投票,选举就完成了。

面试官:不一样的节点角色,在处理读写请求上有什么不一样吗?你先聊聊 Leader 吧

:好滴,Leader 做为集群中的老大,负责对收到的写请求发起提案 PROPOSAL,告诉其余节点当前收到一个写请求,其余节点收到后,会在本地进行归档,其实就是写入文件输出流,完毕后会发送一个 ACK 给 Leader,Leader 统计到半数以上的 ACK 以后会再次发送给其余节点一个 COMMIT,其余节点收到 COMMIT 以后就能够修改内存数据了。读请求的话不须要提案直接查询内存中的数据返回便可。

面试官:那 Follower 或 Observer 呢?

:他们收到读请求是同样的,直接返回本地的内存数据便可。可是写请求的话,会将当前请求转发给 Leader,而后由 Leader 去处理,就和以前的流程是同样的。

面试官:不一样的请求 ZK 是如何保证顺序呢?

:这个顺序的保证最终是落实在一个先进先出的队列,优先进该队列的请求会被先处理,因此能保证顺序。

面试官:不一样的客户端的请求怎么保证顺序呢?A 先发送了一个建立节点,在该请求返回以前,B 发送了一个查询该节点,B 会阻塞到 A 执行完毕再查询吗?仍是直接返回查询不到节点?

:B 会直接返回查不到。不一样的客户端之间的顺序 ZK 不保证,缘由是在底层 ZK 是经过一个 Map 去分别放置不一样的客户端的请求的,不一样的客户端的 key 是不同的,而这个 Map 的 value 则是我刚刚提到的先进先出的队列。因此只有同一个客户端的请求能被顺序执行,不一样的客户端是没法保证的。

面试官:能说说不一样的客户端的 key 是什么吗?怎么保证不一样。

:每个客户端在链接至 ZK 后会被分配一个 sessionId,这个 sessionId 是经过当前时间戳、节点的 myid 和一个递增特性生成的一个 long 类型字段,能够保证不会重复。

面试官:说到 session,你知道 ZK 的会话是怎么维持的吗?

:你问的是客户端和服务端之间的会话吗?

面试官:是的,你能跟我说说吗?

:每个客户端在链接 ZK 的时候会同时上报本身的超时时间,加上刚刚的 sessionId,ZK 的服务端会在本地维护一个映射关系,经过计算能够计算出该 sessionId 的超时时间,而且 ZK 本身也有一个 tickTime 的配置,经过一个算法能够将不一样客户端不一样超时间都映射到相同间隔的时间点上,再将这个超时时间和 sessionId 关系存起来。

面试官:映射到相同的时间点上有什么好处吗?

:这样服务端在启动后,后台会有一个线程,经过这个统一的时间间隔,取出 session 过时的客户端,向他们发送会话过时的消息,极大的节约了性能。

面试官:客户端是怎么去更新会话的超时时间呢?

:首先客户端的每次操做都会刷新这个超时时间,其次客户端必须设计一个 PING 的操做,用于在客户端空闲的时候主动去刷新会话超时时间,防止过时。

面试官:除了客户端和服务端之间的会话,还有别的吗?

:服务端和服务端之间也有心跳,并且服务端的心跳是由 Leader 主动发起的,向其余节点发送 PING 请求,而其余节点收到 PING 后,须要把本地的会话信息一并发送给 Leader。


编不下去了,上面一些题具备我强烈的主观偏好性,我以为若是面试官是个菜鸡的话,这些问题大部分都问不出来,因此重点是不在于我怎么回答,而是当你对背后的原理了然于胸时,天然是神挡杀神,佛挡杀佛。

我说说我认为比较重要的几个特性:

  • 回调通知,ZK 其余原理能够不懂,可是怎么用回调是确定要知道的。
  • 选举,ZK 最具特点的一个属性,基本都会问一下。
  • 持久化,说清楚两种文件的区别。
  • 会话,会话的概念,以及怎么维持。

最后经过一个模拟面试回答了一下我认为 ZK 中比较有特色的面试问题,若是你们对面试问题还有什么疑问记得留言给我噢~必须给大家安排上!

2、网上真题

我大部分题目是网上直接搜的,网址在这里 ZooKeeper面试题(2020最新版)可是过滤了一些太 low 的题目。

4. ZooKeeper 怎么保证主从节点的状态同步?

我上面说了 Leader 在接受到写请求后,会发起提案,而后等待其余节点的 ACK,这个 ACK 是要求半数以上经过才能继续下去的,因此能收到半数以上的 ACK 说明集群中的一半以上都已经完成了本地磁盘的归档,天然是保证了主从之间的数据同步。


5. 四种类型的数据节点 Znode

我以前的文章中有介绍如今 ZK 中有 7 种节点类型,关于新节点的原理我还没来得及讲,因此他若是这么问了你能够很官方的回答他:

  • 持久节点
  • 持久顺序节点
  • 临时节点
  • 临时顺序节点

他通常后面会接着问二者的区别,临时节点会随着客户端的会话断开而自动删除,原理就是在建立临时节点的时候,服务端会维护一个 sessionId 和它对应的临时节点路径列表,当关闭会话时,把这个列表里的路径都拿出来一一删除便可。而顺序节点的区别就在于 ZK 会自动为路径加上数字的后缀,仅此而已。


并发建立时,顺序节点怎么保证后缀数字惟一呢?

ZK 的请求是放入队列里一个个处理的,因此其实并无所谓的并发,前一个请求处理完再处理下一个请求,天然就能保证后缀数字的惟一性了。


10. ACL 权限控制机制

ZK 将权限分为两大类,两大类又能继续细分:

  • 客户端的角色权限
    • IP
    • 用户名密码
    • world,最宽泛的权限,也就是没有权限
    • super,特殊的用户名密码,至关于管理员权限
  • 节点的数据权限
    • Create,建立
    • Delete,删除
    • Read,读
    • Write,写
    • ACL,读写权限

11. Chroot 特性

chroot 是 ZK 设计给客户端的命名空间隔离,做为不一样客户端的根节点,由客户端去维护,总的来讲就是发送请求以前把 chroot 的路径拼接上,再去请求服务端。chroot 对于服务端是透明的,彻底不知道的。


15. 数据同步

Learner 和 Leader 之间同步数据是一个比较漫长和复杂的过程,总的来讲能够大体分为如下步骤:

  • Learner 上报本身的信息给 Leader
  • Leader 根据 Learner 信息决定使用何种同步方法
    • DIFF,直接从最近的 500 个提案中恢复数据,直接发送提案便可
    • TRUNC,一般出现于 Learner 是前 Leader,须要降级本身的数据达到和 Leader 一致
    • SNAP,Leader 直接发送整个内存快照给 Follower
  • Leader 和 Learner 开始同步
  • 同步完成后开始对外提供服务

终篇!面试中可能会遇到的 ZooKeeper 问题

3、配置大全

托你们的福,我把 ZK 的源码所有(爆肝)浏览了一遍,找到了至少 99% 的配置选项,ZK 的配置大体能够分为 3 种:

  • 启动命令行传入的参数
  • zoo.cfg 配置文件中的参数
  • 当前环境变量中的参数

终篇!面试中可能会遇到的 ZooKeeper 问题

3.1 命令行参数

命令行参数不多,并且没有对应的配置名称,这里我简单介绍下:

单机版只支持两种形式的命令行传参

  • 客户端监听端口加 data 目录,上一节源码调试中用的就是这一个形式,例如: 2181 /your/zk/data/path
  • 或者只传一个参数,zoo.cfg 的路径,例如:/your/zoocfg/path

集群版更简单只支持 zoo.cfg 的路径一个参数

3.2 zoo.cfg 文件中的配置

我仔细查看源码的时候发现有些配置实际做用时须要计算又或者是一鱼两吃,被多个地方使用,因此很难一步到位的讲清楚,因此下面的介绍仅供参考,配置项加星号(*)的是我将来打算开篇讲解的。

配置项 默认值(单位) 介绍
dataDir /tmp/zookeeper 存放 snapshot、myid 文件路径
clientPort 2181 监听客户端请求端口
tickTime 2000(毫秒) 影响客户端会话检查间隔、服务端之间心跳间隔
syncLimit 5 tickTime * syncLimit 决定了服务端心跳超时时间
initLimit 10 tickTime * initLimit 决定了 ACK 的超时时间
dataLogDir 和 dataDir 一致 存放 log 文件路径
minSessionTimeout tickTime * 2 客户端的超时时间最小值
maxSessionTimeout tickTime * 20 客户端的超时时间最大值
electionAlg 3 选举算法(1,2 已被废弃)
localSessionsEnabled* false 启用本地会话
localSessionsUpgradingEnabled* false 本地会话能够升级成全局会话
clientPortAddress - 客户端的 host 要求,不配置的话能够接受任意发向 2181 的请求
secureClientPort - SSL 安全端口号
secureClientPortAddress - SSL 安全 host
observerMasterPort* - 使 Observer 经过 Follower 去了解集群中的选举状况
clientPortListenBacklog 50 TCP 服务端用于临时存放已完成三次握手的请求的队列的最大长度
maxClientCnxns 60 客户端最大链接数
connectToLearnerMasterLimit 0 决定了 Follower 链接 Leader 的超时时间
quorumListenOnAllIPs false 服务端是否接受来自任意 IP 地址的请求
peerType - 选项 observer / participant,决定节点角色
syncEnabled true Learner 是否须要本地持久化文件
dynamicConfigFile* - 动态配置路径
autopurge.snapRetainCount 3 保留多少个最新的 snapshot 文件
autopurge.purgeInterval 0(小时) 间隔多久进行一次 snapshot 的清理
standaloneEnabled true 是否容许单机模式启动
reconfigEnabled* false 是否容许动态配置
sslQuorum false 集群间是否使用 SSL 通讯
portUnification false 是否容许不安全链接
sslQuorumReloadCertFiles false 启用密钥更新时自动加载
quorum.auth.enableSasl false 启用集群间 SASL 鉴权
quorum.auth.serverRequireSasl false
quorum.auth.learnerRequireSasl false
quorum.auth.learner.saslLoginContext QuorumLearner
quorum.auth.server.saslLoginContext QuorumServer
quorum.auth.kerberos.servicePrincipal zkquorum/localhost
quorum.cnxn.threads.size 20 集群间异步创建链接线程池最大线程数
jvm.pause.info-threshold.ms 1000(毫秒) INFO 输出暂停统计阈值
jvm.pause.warn-threshold.ms 10000(毫秒) WARN 输出暂停统计阈值
jvm.pause.sleep.time.ms 500(毫秒) JVM 暂停统计线程 sleep 间隔
jvm.pause.monitor* false 是否启用 JVM 暂停统计
metricsProvider.className* DefaultMetricsProvider(全路径) 统计实现类路径
multiAddress.enabled false
multiAddress.reachabilityCheckTimeoutMs 1000(毫秒)
multiAddress.reachabilityCheckEnabled true
(以开头)server.* 集群配置
(以开头)group* 分组配置
(以开头)weight* 权重
(以开头)metricsProvider.* 自定义的统计配置

以上就是 3.6.2 中 zoo.cfg 全部的官方配置选项了

3.3 环境变量配置

Java 程序想要指定环境变量有两种方法:

  • 只须要在启动的时候在后面加上 -DpropertyKey=propertyValue 便可
  • ZK 还支持一种简单的方式就是在 zoo.cfg 中直接指定(指定时不须要写 zookeeper. 的前缀)。只要不是在上面 2.2 中 ZK 本身定义的配置项里,ZK 启动的时候读取这些配置会自动帮他们添加 zookeeper. 前缀并加入当前环境变量中

若是该配置是 follower.nodelay,就只能用第一种方式添加环境变量了。

让咱们也来看看 ZK 本身定义了哪些环境变量配置吧

配置项 默认值 配置
zookeeper.server.realm* - 客户端配置
zookeeper.clientCnxnSocket ClientCnxnSocketNIO(全路径) 客户端配置,通讯的实现类
zookeeper.client.secure true 客户端配置
zookeeper.request.timeout 0 客户端配置,异步 API 超时时间
zookeeper.server.principal - 客户端配置
zookeeper.sasl.client.username zookeeper 客户端配置
zookeeper.sasl.client.canonicalize.hostname true 客户端配置
zookeeper.disableAutoWatchReset false 客户端配置,会话超时自动清空 watcher
zookeeper.sasl.clientconfig -
zookeeper.sasl.client true 启用 SASL
zookeeper.ssl(.quorum).authProvider x509 SSL 实现类,加 quorum 的是服务端的配置,下同
zookeeper.ssl(.quorum).protocol TLSv1.2
zookeeper.ssl(.quorum).enabledProtocols -
zookeeper.ssl(.quorum).ciphersuites 根据不一样的 jvm 版本
zookeeper.ssl(.quorum).keyStore.location -
zookeeper.ssl(.quorum).keyStore.password -
zookeeper.ssl(.quorum).keyStore.type -
zookeeper.ssl(.quorum).trustStore.location -
zookeeper.ssl(.quorum).trustStore.password -
zookeeper.ssl(.quorum).trustStore.type -
zookeeper.ssl(.quorum).context.supplier.class -
zookeeper.ssl(.quorum).hostnameVerification true
zookeeper.ssl(.quorum).crl false
zookeeper.ssl(.quorum).ocsp false
zookeeper.ssl(.quorum).clientAuth -
zookeeper.ssl(.quorum).handshakeDetectionTimeoutMillis 5000(毫秒)
zookeeper.kinit /usr/bin/kinit
zookeeper.jmx.log4j.disable false 禁用 jmx log4j
zookeeper.admin.enableServer* true 是否启用 Admin Server
zookeeper.admin.serverAddress* 0.0.0.0
zookeeper.admin.serverPort* 8080
zookeeper.admin.idleTimeout* 30000
zookeeper.admin.commandURL* /commands
zookeeper.admin.httpVersion* 11
zookeeper.admin.portUnification false
zookeeper.DigestAuthenticationProvider.superDigest - 管理员帐号密码
zookeeper.ensembleAuthName -
zookeeper.requireKerberosConfig -
zookeeper.security.auth_to_local DEFAULT
(以开头)zookeeper.authProvider.* - 自定义 scheme 校验规则
zookeeper.letAnySaslUserDoX -
zookeeper.SASLAuthenticationProvider.superPassword -
zookeeper.kerberos.removeHostFromPrincipal -
zookeeper.kerberos.removeRealmFromPrincipal -
zookeeper.X509AuthenticationProvider.superUser -
zookeeper.4lw.commands.whitelist* - 四字命令白名单
zookeeper.preAllocSize 65536 * 1024
zookeeper.forceSync yes
zookeeper.fsync.warningthresholdms 1000(毫秒) fsync 告警阈值
zookeeper.txnLogSizeLimitInKb -1(KB) log 文件大小
zookeeper.datadir.autocreate true data 目录自动建立
zookeeper.db.autocreate true
zookeeper.snapshot.trust.empty false 不信任空的 snapshot 文件
zookeeper.snapshot.compression.method 空字符串 snapshot 文件压缩实现
zookeeper.commitProcessor.numWorkerThreads CPU 核心数
zookeeper.commitProcessor.shutdownTimeout 5000(毫秒)
zookeeper.commitProcessor.maxReadBatchSize -1
zookeeper.commitProcessor.maxCommitBatchSize 1
zookeeper.fastleader.minNotificationInterval 200(毫秒) 收集选票超时时间(初始)
zookeeper.fastleader.maxNotificationInterval 60000(毫秒) 收集选票超时时间(最大)
zookeeper.leader.maxTimeToWaitForEpoch -1
zookeeper.leader.ackLoggingFrequency 1000
zookeeper.testingonly.initialZxid - 初始化 zxid,仅供测试!
zookeeper.leaderConnectDelayDuringRetryMs 100 Leaner 链接 Leader 超时时间
follower.nodelay true 设置 TCP no delay
zookeeper.forceSnapshotSync false Learner 强制使用 snapshot 和 Leader 进行同步
zookeeper.leader.maxConcurrentSnapSyncs 10
zookeeper.leader.maxConcurrentDiffSyncs 100
zookeeper.observer.reconnectDelayMs 0(毫秒) Observer 延迟重连至 Leader
zookeeper.observer.election.DelayMs 200(毫秒) Observer 延迟开始选举
zookeeper.observerMaster.sizeLimit 32 1024 1024
zookeeper.electionPortBindRetry 3 选举端口链接重试次数
zookeeper.tcpKeepAlive false Socket keep alive 设置
zookeeper.cnxTimeout 5000(毫秒) Socket 超时时间
zookeeper.multiAddress.enabled false
zookeeper.multiAddress.reachabilityCheckTimeoutMs 1000(毫秒)
zookeeper.multiAddress.reachabilityCheckEnabled true
zookeeper.quorumCnxnTimeoutMs -1
zookeeper.observer.syncEnabled true Observer 是否须要本地归档
zookeeper.bitHashCacheSize 10 位图初始缓存大小
zookeeper.messageTracker.BufferSize 10
zookeeper.messageTracker.Enabled false
zookeeper.pathStats.slotCapacity 60
zookeeper.pathStats.slotDuration 15
zookeeper.pathStats.maxDepth 6
zookeeper.pathStats.sampleRate 0.1
zookeeper.pathStats.initialDelay 5
zookeeper.pathStats.delay 5
zookeeper.pathStats.topPathMax 20
zookeeper.pathStats.enabled false
zookeeper.watcherCleanThreshold 1000
zookeeper.watcherCleanIntervalInSeconds 600
zookeeper.watcherCleanThreadsNum 2
zookeeper.maxInProcessingDeadWatchers -1
zookeeper.watchManagerName WatchManager(全路径)
zookeeper.connection_throttle_tokens 0
zookeeper.connection_throttle_fill_time 1
zookeeper.connection_throttle_fill_count 1
zookeeper.connection_throttle_freeze_time -1
zookeeper.connection_throttle_drop_increase 0.02
zookeeper.connection_throttle_drop_decrease 0.002
zookeeper.connection_throttle_decrease_ratio 0
zookeeper.connection_throttle_weight_enabled false
zookeeper.connection_throttle_global_session_weight 3
zookeeper.connection_throttle_local_session_weight 1
zookeeper.connection_throttle_renew_session_weight 2
zookeeper.extendedTypesEnabled* false 是否启用 TTL 节点类型
zookeeper.emulate353TTLNodes* false 是否兼容 3.5.3 的 TTL
zookeeper.client.portUnification false
zookeeper.netty.server.outstandingHandshake.limit -1
zookeeper.netty.advancedFlowControl.enabled false
zookeeper.nio.sessionlessCnxnTimeout 10000(毫秒)
zookeeper.nio.numSelectorThreads CPU 核心数 / 2 再开方
zookeeper.nio.numWorkerThreads CPU 核心数 * 2
zookeeper.nio.directBufferBytes 64 * 1024(字节)
zookeeper.nio.shutdownTimeout 5000(毫秒)
zookeeper.request_stale_connection_check true
zookeeper.request_stale_latency_check false
zookeeper.request_throttler.shutdownTimeout 10000(毫秒)
zookeeper.request_throttle_max_requests 0
zookeeper.request_throttle_stall_time 100
zookeeper.request_throttle_drop_stale true
zookeeper.serverCnxnFactory NIOServerCnxnFactory(全路径)
zookeeper.maxCnxns 0
zookeeper.snapshotSizeFactor 0.33
zookeeper.commitLogCount 500
zookeeper.sasl.serverconfig Server
zookeeper.globalOutstandingLimit 1000
zookeeper.enableEagerACLCheck false
zookeeper.skipACL no
zookeeper.allowSaslFailedClients false
zookeeper.sessionRequireClientSASLAuth false
zookeeper.digest.enabled true
zookeeper.closeSessionTxn.enabled true
zookeeper.flushDelay 0
zookeeper.maxWriteQueuePollTime zookeeper.flushDelay / 3
zookeeper.maxBatchSize 1000
zookeeper.intBufferStartingSizeBytes 1024
zookeeper.maxResponseCacheSize 400
zookeeper.maxGetChildrenResponseCacheSize 400
zookeeper.snapCount 100000
zookeeper.snapSizeLimitInKb 4194304(千字节)
zookeeper.largeRequestMaxBytes 100 1024 1024
zookeeper.largeRequestThreshold -1
zookeeper.superUser -
zookeeper.audit.enable false 是否启用 audit 日志
zookeeper.audit.impl.class Log4jAuditLogger(全路径) audit 日志功能实现类

终篇!面试中可能会遇到的 ZooKeeper 问题

ZK 的配置仍是不少的,有些我这里 TODO 了,之后有机会和你们详细介绍下~并且至关一部分的配置 ZK 官方的文档中已经给出了解释,能够查看 ZK 3.6.2 配置文档

我这里还要吐槽下,ZK 中有些配置是用 true 或者 false,有些使用 yes 或者 no,明显是两个(波)人开发的,这种不该该作一个统一吗?yes 或 no 真的不少余...

4、系列结语

感谢大家能看到这里,陪伴这个系列从开始到如今!这个项目从有想法立项到以后跟蛋蛋沟通,再到正式开始编写,到最后我写下这段结语,大概经历了三个多月(大家看到的时候应该是更晚),如今回头再看以前写的东西,感慨颇深。

(截图来自-B 站何同窗的视频)

终篇!面试中可能会遇到的 ZooKeeper 问题

若是以我本身的自控能力,这玩意本身搞,搞着搞着可能就凉了,在此感谢蛋蛋给予个人帮助和鼓励。关于 ZK 个人确以前有研究过一段时间,可是以如今的眼光看,当时的研究其实也就是皮毛而已(可能如今也仍是),不少东西是我此次整理时现学的,收获很是多,最直观的感觉就是,我之后出去面试不会再惧怕 ZK 相关的问题了。

感谢你们这 3 个月的陪伴,本系列终结喽!若是还有什么想学的开源框架和技术能够留言告诉咱们,后续继续为你们安排免费的干货教程。

最最后,来个大大的赞吧!

终篇!面试中可能会遇到的 ZooKeeper 问题


关注 HelloGitHub 公众号 收到第一时间的更新。

还有更多开源项目的介绍和宝藏项目等待你的发掘。

相关文章
相关标签/搜索