ZooKeeper Server/Client Session 设计及代码分析

本文深入探讨了ZooKeeper客户端和服务端之间的会话机制,包括会话标识、密码验证、超时设置及Watcher通知机制等内容,并对其实现进行了批判性的分析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 
学习开源项目,首要应该是了解其机制。拿来主义固然可以加速开发,但是也会带来潜在的风险。如果你想把自己的应用做的好,你需要保证每一次汲取的营养都是精华,而尽量不要引入糟粕。最近有很多分布式的研发,所以了解了一下ZooKeeper,我们来看看有什么有趣的东西。

ZooKeeper用了不少代码维护ZK client和ZK server之间的session。基本架构是一个NIO server,后面是processer序列,一个NIO请求,先由PreProcessor处理,最后由FinalProcessor处理。中间可能根据情况加入其它processor。这有点像apache servlet的设计概念,但我个人一向不喜欢这种逻辑表达。作为web servlet容器还可以,但作为应用server,这极度弱化了面向对象概念。应该立即将NIO请求转化为对象,再由对象自行,或交予适合的handler处理对象,而不是将所有请求看为一个流。

通常session意味着有状态保持,可是ZooKeeper的session只有owner和timeout,这根本不是状态。那么Sesion到底是干什么用的呢?看看ZooKeeper官方文档上怎么说的,

When a client gets a handle to the ZooKeeper service, ZooKeeper creates a ZooKeeper session, represented as a 64-bit number, that it assigns to the client. If the client connects to a different ZooKeeper server, it will send the session id as a part of the connection handshake. As a security measure, the server creates a password for the session id that any ZooKeeper server can validate.The password is sent to the client with the session id when the client establishes the session. The client sends this password with the session id whenever it reestablishes the session with a new server.

ZooKeeper Session re-connection是有一个password校验,可是该password在每个Server上都由相同的code产生,也就是说,只要是ZooKeeper服务器,有一个算一个,password都能通过。这个feature似乎可有可无?

One of the parameters to the ZooKeeper client library call to create a ZooKeeper session is the session timeout in milliseconds. The client sends a requested timeout, the server responds with the timeout that it can give the client. The current implementation requires that the timeout be a minimum of 2 times the tickTime (as set in the server configuration) and a maximum of 20 times the tickTime.

这似乎是session唯一确实有效的机制,但这和维护一个NIO channel并无多大区别。不同只在于不同ZooKeeper client可以有不同的timeout。

Another parameter to the ZooKeeper session establishment call is the default watcher. Watchers are notified when any state change occurs in the client. For example if the client loses connectivity to the server the client will be notified, or if the client's session expires, etc... This watcher should consider the initial state to be disconnected (i.e. before any state changes events are sent to the watcher by the client lib). In the case of a new connection, the first event sent to the watcher is typically the session connection event.

Watcher的解释与实际代码不符合。文档上说有其他实现,但code我只看到One-time trigger。这个很简单,当client发起请求时,加个watcher标签。Server更新DataTree之后便向client端发一个TCP response。在实现上,ZooKeeper NIOServerCnxn implements Watcher,Watcher直接注册到DataTree上,key是path。

Watcher设计的实现的结果非常类似于RPC。即client/server端封装同样的WatcherEvent,这样Client端直接监听WatcherEvent,就好像直接从Server端扔出的event一样。不过我个人以为,还是使用通用的通讯协议,用XML,JSON或直接byte,例如RTSP,在client自己解析好。因为这样更灵活些,扩展性更好些。

总之,ZooKeeper client/server session没什么意思。还有很多非常有趣的漏洞,

首先,为了检查session timeout,居然每个session extends Thread!虽然默认只有10个client连接,但该值可配。这是很危险的,Thread数超过1024,JVM调度就不大灵光了。另外NIOServerCnxn中处理NIO的Factory居然只有单线程在跑。而且整个后台处理设计也是基于单线程的。PrepRequestProcessor使用一个LinkedBlockingQueue处理request。本来用LinkedBlockingQueue是个好主意,但是只有一个线程在处理它。显然是太少了。而且SessionTrackerImpl处加了太多没有必要的同步锁,本来就是单线程处理,要同步锁干什么?


我估计ZooKeeper的核心应该还是Paxos算法的实现。下面会接着看。
[2025-06-04 16:02:18,809] INFO Registered kafka:type=kafka.Log4jController MBean (kafka.utils.Log4jControllerRegistration$) [2025-06-04 16:02:19,395] INFO Setting -D jdk.tls.rejectClientInitiatedRenegotiation=true to disable client-initiated TLS renegotiation (org.apache.zookeeper.common.X509Util) [2025-06-04 16:02:19,503] INFO Registered signal handlers for TERM, INT, HUP (org.apache.kafka.common.utils.LoggingSignalHandler) [2025-06-04 16:02:19,509] INFO starting (kafka.server.KafkaServer) [2025-06-04 16:02:19,510] INFO Connecting to zookeeper on 97.2.171.140:2181 (kafka.server.KafkaServer) [2025-06-04 16:02:19,540] INFO [ZooKeeperClient Kafka server] Initializing a new session to 97.2.171.140:2181. (kafka.zookeeper.ZooKeeperClient) [2025-06-04 16:02:19,548] INFO Client environment:zookeeper.version=3.6.3--6401e4ad2087061bc6b9f80dec2d69f2e3c8660a, built on 04/08/2021 16:35 GMT (org.apache.zookeeper.ZooKeeper) [2025-06-04 16:02:19,548] INFO Client environment:host.name=i-app-ecs-0003.novalocal (org.apache.zookeeper.ZooKeeper) [2025-06-04 16:02:19,548] INFO Client environment:java.version=1.8.0_262 (org.apache.zookeeper.ZooKeeper) [2025-06-04 16:02:19,548] INFO Client environment:java.vendor=Oracle Corporation (org.apache.zookeeper.ZooKeeper) [2025-06-04 16:02:19,548] INFO Client environment:java.home=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.262.b10-1.an7.x86_64/jre (org.apache.zookeeper.ZooKeeper) [2025-06-04 16:02:19,548] INFO Client environment:java.class.path=/home/kafka/kafka2023/kafka/bin/../libs/activation-1.1.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/aopalliance-repackaged-2.6.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/argparse4j-0.7.0.jar:/home/kafka/kafka2023/kafka/bin/../libs/audience-annotations-0.5.0.jar:/home/kafka/kafka2023/kafka/bin/../libs/commons-cli-1.4.jar:/home/kafka/kafka2023/kafka/bin/../libs/commons-lang3-3.8.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/connect-api-3.2.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/connect-basic-auth-extension-3.2.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/connect-json-3.2.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/connect-mirror-3.2.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/connect-mirror-client-3.2.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/connect-runtime-3.2.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/connect-transforms-3.2.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/hk2-api-2.6.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/hk2-locator-2.6.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/hk2-utils-2.6.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/jackson-annotations-2.12.6.jar:/home/kafka/kafka2023/kafka/bin/../libs/jackson-core-2.12.6.jar:/home/kafka/kafka2023/kafka/bin/../libs/jackson-databind-2.12.6.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/jackson-dataformat-csv-2.12.6.jar:/home/kafka/kafka2023/kafka/bin/../libs/jackson-datatype-jdk8-2.12.6.jar:/home/kafka/kafka2023/kafka/bin/../libs/jackson-jaxrs-base-2.12.6.jar:/home/kafka/kafka2023/kafka/bin/../libs/jackson-jaxrs-json-provider-2.12.6.jar:/home/kafka/kafka2023/kafka/bin/../libs/jackson-module-jaxb-annotations-2.12.6.jar:/home/kafka/kafka2023/kafka/bin/../libs/jackson-module-scala_2.12-2.12.6.jar:/home/kafka/kafka2023/kafka/bin/../libs/jakarta.activation-api-1.2.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/jakarta.annotation-api-1.3.5.jar:/home/kafka/kafka2023/kafka/bin/../libs/jakarta.inject-2.6.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/jakarta.validation-api-2.0.2.jar:/home/kafka/kafka2023/kafka/bin/../libs/jakarta.ws.rs-api-2.1.6.jar:/home/kafka/kafka2023/kafka/bin/../libs/jakarta.xml.bind-api-2.3.2.jar:/home/kafka/kafka2023/kafka/bin/../libs/javassist-3.27.0-GA.jar:/home/kafka/kafka2023/kafka/bin/../libs/javax.servlet-api-3.1.0.jar:/home/kafka/kafka2023/kafka/bin/../libs/javax.ws.rs-api-2.1.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/jaxb-api-2.3.0.jar:/home/kafka/kafka2023/kafka/bin/../libs/jersey-client-2.34.jar:/home/kafka/kafka2023/kafka/bin/../libs/jersey-common-2.34.jar:/home/kafka/kafka2023/kafka/bin/../libs/jersey-container-servlet-2.34.jar:/home/kafka/kafka2023/kafka/bin/../libs/jersey-container-servlet-core-2.34.jar:/home/kafka/kafka2023/kafka/bin/../libs/jersey-hk2-2.34.jar:/home/kafka/kafka2023/kafka/bin/../libs/jersey-server-2.34.jar:/home/kafka/kafka2023/kafka/bin/../libs/jetty-client-9.4.44.v20210927.jar:/home/kafka/kafka2023/kafka/bin/../libs/jetty-continuation-9.4.44.v20210927.jar:/home/kafka/kafka2023/kafka/bin/../libs/jetty-http-9.4.44.v20210927.jar:/home/kafka/kafka2023/kafka/bin/../libs/jetty-io-9.4.44.v20210927.jar:/home/kafka/kafka2023/kafka/bin/../libs/jetty-security-9.4.44.v20210927.jar:/home/kafka/kafka2023/kafka/bin/../libs/jetty-server-9.4.44.v20210927.jar:/home/kafka/kafka2023/kafka/bin/../libs/jetty-servlet-9.4.44.v20210927.jar:/home/kafka/kafka2023/kafka/bin/../libs/jetty-servlets-9.4.44.v20210927.jar:/home/kafka/kafka2023/kafka/bin/../libs/jetty-util-9.4.44.v20210927.jar:/home/kafka/kafka2023/kafka/bin/../libs/jetty-util-ajax-9.4.44.v20210927.jar:/home/kafka/kafka2023/kafka/bin/../libs/jline-3.21.0.jar:/home/kafka/kafka2023/kafka/bin/../libs/jopt-simple-5.0.4.jar:/home/kafka/kafka2023/kafka/bin/../libs/jose4j-0.7.9.jar:/home/kafka/kafka2023/kafka/bin/../libs/kafka_2.12-3.2.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/kafka-clients-3.2.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/kafka-log4j-appender-3.2.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/kafka-metadata-3.2.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/kafka-raft-3.2.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/kafka-server-common-3.2.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/kafka-shell-3.2.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/kafka-storage-3.2.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/kafka-storage-api-3.2.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/kafka-streams-3.2.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/kafka-streams-examples-3.2.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/kafka-streams-scala_2.12-3.2.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/kafka-streams-test-utils-3.2.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/kafka-tools-3.2.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/lz4-java-1.8.0.jar:/home/kafka/kafka2023/kafka/bin/../libs/maven-artifact-3.8.4.jar:/home/kafka/kafka2023/kafka/bin/../libs/metrics-core-2.2.0.jar:/home/kafka/kafka2023/kafka/bin/../libs/metrics-core-4.1.12.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/netty-buffer-4.1.73.Final.jar:/home/kafka/kafka2023/kafka/bin/../libs/netty-codec-4.1.73.Final.jar:/home/kafka/kafka2023/kafka/bin/../libs/netty-common-4.1.73.Final.jar:/home/kafka/kafka2023/kafka/bin/../libs/netty-handler-4.1.73.Final.jar:/home/kafka/kafka2023/kafka/bin/../libs/netty-resolver-4.1.73.Final.jar:/home/kafka/kafka2023/kafka/bin/../libs/netty-tcnative-classes-2.0.46.Final.jar:/home/kafka/kafka2023/kafka/bin/../libs/netty-transport-4.1.73.Final.jar:/home/kafka/kafka2023/kafka/bin/../libs/netty-transport-classes-epoll-4.1.73.Final.jar:/home/kafka/kafka2023/kafka/bin/../libs/netty-transport-native-epoll-4.1.73.Final.jar:/home/kafka/kafka2023/kafka/bin/../libs/netty-transport-native-unix-common-4.1.73.Final.jar:/home/kafka/kafka2023/kafka/bin/../libs/osgi-resource-locator-1.0.3.jar:/home/kafka/kafka2023/kafka/bin/../libs/paranamer-2.8.jar:/home/kafka/kafka2023/kafka/bin/../libs/plexus-utils-3.3.0.jar:/home/kafka/kafka2023/kafka/bin/../libs/reflections-0.9.12.jar:/home/kafka/kafka2023/kafka/bin/../libs/reload4j-1.2.19.jar:/home/kafka/kafka2023/kafka/bin/../libs/rocksdbjni-6.29.4.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/scala-collection-compat_2.12-2.6.0.jar:/home/kafka/kafka2023/kafka/bin/../libs/scala-java8-compat_2.12-1.0.2.jar:/home/kafka/kafka2023/kafka/bin/../libs/scala-library-2.12.15.jar:/home/kafka/kafka2023/kafka/bin/../libs/scala-logging_2.12-3.9.4.jar:/home/kafka/kafka2023/kafka/bin/../libs/scala-reflect-2.12.15.jar:/home/kafka/kafka2023/kafka/bin/../libs/slf4j-api-1.7.36.jar:/home/kafka/kafka2023/kafka/bin/../libs/slf4j-reload4j-1.7.36.jar:/home/kafka/kafka2023/kafka/bin/../libs/snappy-java-1.1.8.4.jar:/home/kafka/kafka2023/kafka/bin/../libs/trogdor-3.2.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/zookeeper-3.6.3.jar:/home/kafka/kafka2023/kafka/bin/../libs/zookeeper-jute-3.6.3.jar:/home/kafka/kafka2023/kafka/bin/../libs/zstd-jni-1.5.2-1.jar (org.apache.zookeeper.ZooKeeper) [2025-06-04 16:02:19,548] INFO Client environment:java.library.path=/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib (org.apache.zookeeper.ZooKeeper) [2025-06-04 16:02:19,549] INFO Client environment:java.io.tmpdir=/tmp (org.apache.zookeeper.ZooKeeper) [2025-06-04 16:02:19,549] INFO Client environment:java.compiler=<NA> (org.apache.zookeeper.ZooKeeper) [2025-06-04 16:02:19,549] INFO Client environment:os.name=Linux (org.apache.zookeeper.ZooKeeper) [2025-06-04 16:02:19,549] INFO Client environment:os.arch=amd64 (org.apache.zookeeper.ZooKeeper) [2025-06-04 16:02:19,549] INFO Client environment:os.version=3.10.0-1160.an7.x86_64 (org.apache.zookeeper.ZooKeeper) [2025-06-04 16:02:19,549] INFO Client environment:user.name=root (org.apache.zookeeper.ZooKeeper) [2025-06-04 16:02:19,549] INFO Client environment:user.home=/root (org.apache.zookeeper.ZooKeeper) [2025-06-04 16:02:19,549] INFO Client environment:user.dir=/home/kafka/kafka2023/kafka/bin (org.apache.zookeeper.ZooKeeper) [2025-06-04 16:02:19,549] INFO Client environment:os.memory.free=1013MB (org.apache.zookeeper.ZooKeeper) [2025-06-04 16:02:19,549] INFO Client environment:os.memory.max=1024MB (org.apache.zookeeper.ZooKeeper) [2025-06-04 16:02:19,549] INFO Client environment:os.memory.total=1024MB (org.apache.zookeeper.ZooKeeper) [2025-06-04 16:02:19,552] INFO Initiating client connection, connectString=97.2.171.140:2181 sessionTimeout=18000 watcher=kafka.zookeeper.ZooKeeperClient$ZooKeeperClientWatcher$@5bf0d49 (org.apache.zookeeper.ZooKeeper) [2025-06-04 16:02:19,557] INFO jute.maxbuffer value is 4194304 Bytes (org.apache.zookeeper.ClientCnxnSocket) [2025-06-04 16:02:19,564] INFO zookeeper.request.timeout value is 0. feature enabled=false (org.apache.zookeeper.ClientCnxn) [2025-06-04 16:02:19,570] INFO [ZooKeeperClient Kafka server] Waiting until connected. (kafka.zookeeper.ZooKeeperClient) [2025-06-04 16:02:19,577] INFO Client successfully logged in. (org.apache.zookeeper.Login) [2025-06-04 16:02:19,578] INFO Client will use DIGEST-MD5 as SASL mechanism. (org.apache.zookeeper.client.ZooKeeperSaslClient) [2025-06-04 16:02:19,595] INFO Opening socket connection to server i-app-ecs-0003.novalocal/97.2.171.140:2181. (org.apache.zookeeper.ClientCnxn) [2025-06-04 16:02:19,595] INFO SASL config status: Will attempt to SASL-authenticate using Login Context section 'Client' (org.apache.zookeeper.ClientCnxn) [2025-06-04 16:02:19,600] INFO Socket connection established, initiating session, client: /97.2.171.140:38148, server: i-app-ecs-0003.novalocal/97.2.171.140:2181 (org.apache.zookeeper.ClientCnxn) [2025-06-04 16:02:19,621] INFO Session establishment complete on server i-app-ecs-0003.novalocal/97.2.171.140:2181, session id = 0x108ea89bff30000, negotiated timeout = 18000 (org.apache.zookeeper.ClientCnxn) [2025-06-04 16:02:19,632] INFO [ZooKeeperClient Kafka server] Connected. (kafka.zookeeper.ZooKeeperClient) [2025-06-04 16:02:19,722] ERROR Fatal error during KafkaServer startup. Prepare to shutdown (kafka.server.KafkaServer) org.apache.zookeeper.KeeperException$InvalidACLException: KeeperErrorCode = InvalidACL for /brokers/ids at org.apache.zookeeper.KeeperException.create(KeeperException.java:128) at org.apache.zookeeper.KeeperException.create(KeeperException.java:54) at kafka.zookeeper.AsyncResponse.maybeThrow(ZooKeeperClient.scala:566) at kafka.zk.KafkaZkClient.createRecursive(KafkaZkClient.scala:1728) at kafka.zk.KafkaZkClient.makeSurePersistentPathExists(KafkaZkClient.scala:1626) at kafka.zk.KafkaZkClient.$anonfun$createTopLevelPaths$1(KafkaZkClient.scala:1618) at kafka.zk.KafkaZkClient.$anonfun$createTopLevelPaths$1$adapted(KafkaZkClient.scala:1618) at scala.collection.immutable.List.foreach(List.scala:431) at kafka.zk.KafkaZkClient.createTopLevelPaths(KafkaZkClient.scala:1618) at kafka.server.KafkaServer.initZkClient(KafkaServer.scala:501) at kafka.server.KafkaServer.startup(KafkaServer.scala:203) at kafka.Kafka$.main(Kafka.scala:109) at kafka.Kafka.main(Kafka.scala) [2025-06-04 16:02:19,725] INFO shutting down (kafka.server.KafkaServer) [2025-06-04 16:02:19,728] INFO [ZooKeeperClient Kafka server] Closing. (kafka.zookeeper.ZooKeeperClient) [2025-06-04 16:02:19,833] INFO Session: 0x108ea89bff30000 closed (org.apache.zookeeper.ZooKeeper) [2025-06-04 16:02:19,834] INFO EventThread shut down for session: 0x108ea89bff30000 (org.apache.zookeeper.ClientCnxn) [2025-06-04 16:02:19,836] INFO [ZooKeeperClient Kafka server] Closed. (kafka.zookeeper.ZooKeeperClient) [2025-06-04 16:02:19,839] INFO App info kafka.server for 0 unregistered (org.apache.kafka.common.utils.AppInfoParser) [2025-06-04 16:02:19,840] INFO shut down completed (kafka.server.KafkaServer) [2025-06-04 16:02:19,840] ERROR Exiting Kafka. (kafka.Kafka$) [2025-06-04 16:02:19,840] INFO shutting down (kafka.server.KafkaServer) [2025-06-04 16:15:57,279] INFO Registered kafka:type=kafka.Log4jController MBean (kafka.utils.Log4jControllerRegistration$) [2025-06-04 16:15:57,862] INFO Setting -D jdk.tls.rejectClientInitiatedRenegotiation=true to disable client-initiated TLS renegotiation (org.apache.zookeeper.common.X509Util) [2025-06-04 16:15:57,976] INFO Registered signal handlers for TERM, INT, HUP (org.apache.kafka.common.utils.LoggingSignalHandler) [2025-06-04 16:15:57,981] INFO starting (kafka.server.KafkaServer) [2025-06-04 16:15:57,982] INFO Connecting to zookeeper on 97.2.171.140:2181 (kafka.server.KafkaServer) [2025-06-04 16:15:58,015] INFO [ZooKeeperClient Kafka server] Initializing a new session to 97.2.171.140:2181. (kafka.zookeeper.ZooKeeperClient) [2025-06-04 16:15:58,030] INFO Client environment:zookeeper.version=3.6.3--6401e4ad2087061bc6b9f80dec2d69f2e3c8660a, built on 04/08/2021 16:35 GMT (org.apache.zookeeper.ZooKeeper) [2025-06-04 16:15:58,031] INFO Client environment:host.name=i-app-ecs-0003.novalocal (org.apache.zookeeper.ZooKeeper) [2025-06-04 16:15:58,031] INFO Client environment:java.version=1.8.0_262 (org.apache.zookeeper.ZooKeeper) [2025-06-04 16:15:58,031] INFO Client environment:java.vendor=Oracle Corporation (org.apache.zookeeper.ZooKeeper) [2025-06-04 16:15:58,031] INFO Client environment:java.home=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.262.b10-1.an7.x86_64/jre (org.apache.zookeeper.ZooKeeper) [2025-06-04 16:15:58,031] INFO Client environment:java.class.path=/home/kafka/kafka2023/kafka/bin/../libs/activation-1.1.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/aopalliance-repackaged-2.6.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/argparse4j-0.7.0.jar:/home/kafka/kafka2023/kafka/bin/../libs/audience-annotations-0.5.0.jar:/home/kafka/kafka2023/kafka/bin/../libs/commons-cli-1.4.jar:/home/kafka/kafka2023/kafka/bin/../libs/commons-lang3-3.8.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/connect-api-3.2.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/connect-basic-auth-extension-3.2.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/connect-json-3.2.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/connect-mirror-3.2.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/connect-mirror-client-3.2.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/connect-runtime-3.2.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/connect-transforms-3.2.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/hk2-api-2.6.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/hk2-locator-2.6.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/hk2-utils-2.6.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/jackson-annotations-2.12.6.jar:/home/kafka/kafka2023/kafka/bin/../libs/jackson-core-2.12.6.jar:/home/kafka/kafka2023/kafka/bin/../libs/jackson-databind-2.12.6.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/jackson-dataformat-csv-2.12.6.jar:/home/kafka/kafka2023/kafka/bin/../libs/jackson-datatype-jdk8-2.12.6.jar:/home/kafka/kafka2023/kafka/bin/../libs/jackson-jaxrs-base-2.12.6.jar:/home/kafka/kafka2023/kafka/bin/../libs/jackson-jaxrs-json-provider-2.12.6.jar:/home/kafka/kafka2023/kafka/bin/../libs/jackson-module-jaxb-annotations-2.12.6.jar:/home/kafka/kafka2023/kafka/bin/../libs/jackson-module-scala_2.12-2.12.6.jar:/home/kafka/kafka2023/kafka/bin/../libs/jakarta.activation-api-1.2.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/jakarta.annotation-api-1.3.5.jar:/home/kafka/kafka2023/kafka/bin/../libs/jakarta.inject-2.6.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/jakarta.validation-api-2.0.2.jar:/home/kafka/kafka2023/kafka/bin/../libs/jakarta.ws.rs-api-2.1.6.jar:/home/kafka/kafka2023/kafka/bin/../libs/jakarta.xml.bind-api-2.3.2.jar:/home/kafka/kafka2023/kafka/bin/../libs/javassist-3.27.0-GA.jar:/home/kafka/kafka2023/kafka/bin/../libs/javax.servlet-api-3.1.0.jar:/home/kafka/kafka2023/kafka/bin/../libs/javax.ws.rs-api-2.1.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/jaxb-api-2.3.0.jar:/home/kafka/kafka2023/kafka/bin/../libs/jersey-client-2.34.jar:/home/kafka/kafka2023/kafka/bin/../libs/jersey-common-2.34.jar:/home/kafka/kafka2023/kafka/bin/../libs/jersey-container-servlet-2.34.jar:/home/kafka/kafka2023/kafka/bin/../libs/jersey-container-servlet-core-2.34.jar:/home/kafka/kafka2023/kafka/bin/../libs/jersey-hk2-2.34.jar:/home/kafka/kafka2023/kafka/bin/../libs/jersey-server-2.34.jar:/home/kafka/kafka2023/kafka/bin/../libs/jetty-client-9.4.44.v20210927.jar:/home/kafka/kafka2023/kafka/bin/../libs/jetty-continuation-9.4.44.v20210927.jar:/home/kafka/kafka2023/kafka/bin/../libs/jetty-http-9.4.44.v20210927.jar:/home/kafka/kafka2023/kafka/bin/../libs/jetty-io-9.4.44.v20210927.jar:/home/kafka/kafka2023/kafka/bin/../libs/jetty-security-9.4.44.v20210927.jar:/home/kafka/kafka2023/kafka/bin/../libs/jetty-server-9.4.44.v20210927.jar:/home/kafka/kafka2023/kafka/bin/../libs/jetty-servlet-9.4.44.v20210927.jar:/home/kafka/kafka2023/kafka/bin/../libs/jetty-servlets-9.4.44.v20210927.jar:/home/kafka/kafka2023/kafka/bin/../libs/jetty-util-9.4.44.v20210927.jar:/home/kafka/kafka2023/kafka/bin/../libs/jetty-util-ajax-9.4.44.v20210927.jar:/home/kafka/kafka2023/kafka/bin/../libs/jline-3.21.0.jar:/home/kafka/kafka2023/kafka/bin/../libs/jopt-simple-5.0.4.jar:/home/kafka/kafka2023/kafka/bin/../libs/jose4j-0.7.9.jar:/home/kafka/kafka2023/kafka/bin/../libs/kafka_2.12-3.2.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/kafka-clients-3.2.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/kafka-log4j-appender-3.2.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/kafka-metadata-3.2.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/kafka-raft-3.2.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/kafka-server-common-3.2.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/kafka-shell-3.2.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/kafka-storage-3.2.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/kafka-storage-api-3.2.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/kafka-streams-3.2.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/kafka-streams-examples-3.2.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/kafka-streams-scala_2.12-3.2.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/kafka-streams-test-utils-3.2.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/kafka-tools-3.2.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/lz4-java-1.8.0.jar:/home/kafka/kafka2023/kafka/bin/../libs/maven-artifact-3.8.4.jar:/home/kafka/kafka2023/kafka/bin/../libs/metrics-core-2.2.0.jar:/home/kafka/kafka2023/kafka/bin/../libs/metrics-core-4.1.12.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/netty-buffer-4.1.73.Final.jar:/home/kafka/kafka2023/kafka/bin/../libs/netty-codec-4.1.73.Final.jar:/home/kafka/kafka2023/kafka/bin/../libs/netty-common-4.1.73.Final.jar:/home/kafka/kafka2023/kafka/bin/../libs/netty-handler-4.1.73.Final.jar:/home/kafka/kafka2023/kafka/bin/../libs/netty-resolver-4.1.73.Final.jar:/home/kafka/kafka2023/kafka/bin/../libs/netty-tcnative-classes-2.0.46.Final.jar:/home/kafka/kafka2023/kafka/bin/../libs/netty-transport-4.1.73.Final.jar:/home/kafka/kafka2023/kafka/bin/../libs/netty-transport-classes-epoll-4.1.73.Final.jar:/home/kafka/kafka2023/kafka/bin/../libs/netty-transport-native-epoll-4.1.73.Final.jar:/home/kafka/kafka2023/kafka/bin/../libs/netty-transport-native-unix-common-4.1.73.Final.jar:/home/kafka/kafka2023/kafka/bin/../libs/osgi-resource-locator-1.0.3.jar:/home/kafka/kafka2023/kafka/bin/../libs/paranamer-2.8.jar:/home/kafka/kafka2023/kafka/bin/../libs/plexus-utils-3.3.0.jar:/home/kafka/kafka2023/kafka/bin/../libs/reflections-0.9.12.jar:/home/kafka/kafka2023/kafka/bin/../libs/reload4j-1.2.19.jar:/home/kafka/kafka2023/kafka/bin/../libs/rocksdbjni-6.29.4.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/scala-collection-compat_2.12-2.6.0.jar:/home/kafka/kafka2023/kafka/bin/../libs/scala-java8-compat_2.12-1.0.2.jar:/home/kafka/kafka2023/kafka/bin/../libs/scala-library-2.12.15.jar:/home/kafka/kafka2023/kafka/bin/../libs/scala-logging_2.12-3.9.4.jar:/home/kafka/kafka2023/kafka/bin/../libs/scala-reflect-2.12.15.jar:/home/kafka/kafka2023/kafka/bin/../libs/slf4j-api-1.7.36.jar:/home/kafka/kafka2023/kafka/bin/../libs/slf4j-reload4j-1.7.36.jar:/home/kafka/kafka2023/kafka/bin/../libs/snappy-java-1.1.8.4.jar:/home/kafka/kafka2023/kafka/bin/../libs/trogdor-3.2.1.jar:/home/kafka/kafka2023/kafka/bin/../libs/zookeeper-3.6.3.jar:/home/kafka/kafka2023/kafka/bin/../libs/zookeeper-jute-3.6.3.jar:/home/kafka/kafka2023/kafka/bin/../libs/zstd-jni-1.5.2-1.jar (org.apache.zookeeper.ZooKeeper) [2025-06-04 16:15:58,031] INFO Client environment:java.library.path=/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib (org.apache.zookeeper.ZooKeeper) [2025-06-04 16:15:58,031] INFO Client environment:java.io.tmpdir=/tmp (org.apache.zookeeper.ZooKeeper) [2025-06-04 16:15:58,031] INFO Client environment:java.compiler=<NA> (org.apache.zookeeper.ZooKeeper) [2025-06-04 16:15:58,031] INFO Client environment:os.name=Linux (org.apache.zookeeper.ZooKeeper) [2025-06-04 16:15:58,032] INFO Client environment:os.arch=amd64 (org.apache.zookeeper.ZooKeeper) [2025-06-04 16:15:58,032] INFO Client environment:os.version=3.10.0-1160.an7.x86_64 (org.apache.zookeeper.ZooKeeper) [2025-06-04 16:15:58,032] INFO Client environment:user.name=root (org.apache.zookeeper.ZooKeeper) [2025-06-04 16:15:58,032] INFO Client environment:user.home=/root (org.apache.zookeeper.ZooKeeper) [2025-06-04 16:15:58,032] INFO Client environment:user.dir=/home/kafka/kafka2023/kafka (org.apache.zookeeper.ZooKeeper) [2025-06-04 16:15:58,032] INFO Client environment:os.memory.free=1013MB (org.apache.zookeeper.ZooKeeper) [2025-06-04 16:15:58,032] INFO Client environment:os.memory.max=1024MB (org.apache.zookeeper.ZooKeeper) [2025-06-04 16:15:58,032] INFO Client environment:os.memory.total=1024MB (org.apache.zookeeper.ZooKeeper) [2025-06-04 16:15:58,035] INFO Initiating client connection, connectString=97.2.171.140:2181 sessionTimeout=18000 watcher=kafka.zookeeper.ZooKeeperClient$ZooKeeperClientWatcher$@5bf0d49 (org.apache.zookeeper.ZooKeeper) [2025-06-04 16:15:58,040] INFO jute.maxbuffer value is 4194304 Bytes (org.apache.zookeeper.ClientCnxnSocket) [2025-06-04 16:15:58,047] INFO zookeeper.request.timeout value is 0. feature enabled=false (org.apache.zookeeper.ClientCnxn) [2025-06-04 16:15:58,052] INFO [ZooKeeperClient Kafka server] Waiting until connected. (kafka.zookeeper.ZooKeeperClient) [2025-06-04 16:15:58,057] INFO Client successfully logged in. (org.apache.zookeeper.Login) [2025-06-04 16:15:58,059] INFO Client will use DIGEST-MD5 as SASL mechanism. (org.apache.zookeeper.client.ZooKeeperSaslClient) [2025-06-04 16:15:58,074] INFO Opening socket connection to server i-app-ecs-0003.novalocal/97.2.171.140:2181. (org.apache.zookeeper.ClientCnxn) [2025-06-04 16:15:58,074] INFO SASL config status: Will attempt to SASL-authenticate using Login Context section 'Client' (org.apache.zookeeper.ClientCnxn) [2025-06-04 16:15:58,078] INFO Socket connection established, initiating session, client: /97.2.171.140:38154, server: i-app-ecs-0003.novalocal/97.2.171.140:2181 (org.apache.zookeeper.ClientCnxn) [2025-06-04 16:15:58,093] INFO Session establishment complete on server i-app-ecs-0003.novalocal/97.2.171.140:2181, session id = 0x108ea97a7a70000, negotiated timeout = 18000 (org.apache.zookeeper.ClientCnxn) [2025-06-04 16:15:58,098] INFO [ZooKeeperClient Kafka server] Connected. (kafka.zookeeper.ZooKeeperClient) [2025-06-04 16:15:58,184] ERROR Fatal error during KafkaServer startup. Prepare to shutdown (kafka.server.KafkaServer) org.apache.zookeeper.KeeperException$InvalidACLException: KeeperErrorCode = InvalidACL for /brokers/ids at org.apache.zookeeper.KeeperException.create(KeeperException.java:128) at org.apache.zookeeper.KeeperException.create(KeeperException.java:54) at kafka.zookeeper.AsyncResponse.maybeThrow(ZooKeeperClient.scala:566) at kafka.zk.KafkaZkClient.createRecursive(KafkaZkClient.scala:1728) at kafka.zk.KafkaZkClient.makeSurePersistentPathExists(KafkaZkClient.scala:1626) at kafka.zk.KafkaZkClient.$anonfun$createTopLevelPaths$1(KafkaZkClient.scala:1618) at kafka.zk.KafkaZkClient.$anonfun$createTopLevelPaths$1$adapted(KafkaZkClient.scala:1618) at scala.collection.immutable.List.foreach(List.scala:431) at kafka.zk.KafkaZkClient.createTopLevelPaths(KafkaZkClient.scala:1618) at kafka.server.KafkaServer.initZkClient(KafkaServer.scala:501) at kafka.server.KafkaServer.startup(KafkaServer.scala:203) at kafka.Kafka$.main(Kafka.scala:109) at kafka.Kafka.main(Kafka.scala) [2025-06-04 16:15:58,187] INFO shutting down (kafka.server.KafkaServer) [2025-06-04 16:15:58,189] INFO [ZooKeeperClient Kafka server] Closing. (kafka.zookeeper.ZooKeeperClient) [2025-06-04 16:15:58,295] INFO Session: 0x108ea97a7a70000 closed (org.apache.zookeeper.ZooKeeper) [2025-06-04 16:15:58,296] INFO EventThread shut down for session: 0x108ea97a7a70000 (org.apache.zookeeper.ClientCnxn) [2025-06-04 16:15:58,298] INFO [ZooKeeperClient Kafka server] Closed. (kafka.zookeeper.ZooKeeperClient) [2025-06-04 16:15:58,301] INFO App info kafka.server for 0 unregistered (org.apache.kafka.common.utils.AppInfoParser) [2025-06-04 16:15:58,302] INFO shut down completed (kafka.server.KafkaServer) [2025-06-04 16:15:58,302] ERROR Exiting Kafka. (kafka.Kafka$) [2025-06-04 16:15:58,302] INFO shutting down (kafka.server.KafkaServer)
最新发布
06-06
<think>首先,用户在问如何解决Kafka服务器启动时的错误:"KafkaServerstartuperrorInvalidACLExceptionKeeperErrorCode=InvalidACLfor/brokers/ids"。这是在Zookeeper的路径`/brokers/ids`上发生权限问题。从站内引用看:-引用[1]说:"ACLsontheKafkaznodesarenotremovedwhiledisablingKerberos."这解释了错误可能是因为在禁用Kerberos时Znode的ACL没有被移除。-其他引用涉及SASL认证、SSL认证、fetchsize问题,和用户队列后缀,不太直接相关。但引用[2]提到SASL权限认证可能相关,引用[4]是关于用户队列的,不直接相关。用户的错误提到`InvalidACLException`和`/brokers/ids`,这表明Zookeeper的ACL无效或损坏。我的回答应该:-系统指令:使用正确的LaTeX格式。比如行内数学用$...$,独立公式用$$...$$。-使用中文回答。-生成相关问题。-引用段落末尾自然地加引用标识,如[^1]。-回答结构清晰,真实可靠。步骤解决这个问题:1.**理解错误**:`InvalidACLException`for`/brokers/ids`通常是因为Zookeeper中的ACL不正确。可能的原因包括:-ACL被意外修改或损坏。-当集群配置变更(如启用或禁用安全机制)时,ACL没有被正确更新。-从引用[1],禁用Kerberos时,ACL可能没被移除。2.**解决方案**:-连接到Zookeeper服务器。-删除或修复`/brokers/ids`的ACL。-具体步骤:-使用Zookeeper的CLI(如`zkCli.sh`)连接到集群。-检查`/brokers/ids`路径:`ls/brokers/ids`,然后`get/brokers/ids`查看ACL。-删除无效ACL:参考引用[1],需要移除ACL。可能用`delete`命令删除节点并重建,或者用`setAcl`重置ACL。-设置合适的ACL:如果启用了安全认证,ACL应该正确配置;如果没启用,可以设置为开放权限。-在禁用Kerberos后,可能需要清除所有Zookeeper上与ACL相关的内容。来自引用[1]的建议:移除Kafkaznode上的ACL。一个常见的方法是删除Zookeeper中的`/brokers/ids`节点,并让Kafka在启动时重新创建它。但这可能会导致数据丢失,如果BrokerIDs有信息。更安全的做法是用`setAcl`设置默认权限。一般步骤:-**停止Kafka服务器**。-**备份Zookeeper数据**(可选但推荐)。-**连接到Zookeeper**:`./bin/zkCli.sh-serverlocalhost:2181`(调整端口)。-**检查路径**:`ls/brokers/ids`,应该列出BrokerIDs。-**重置ACL**:可能用`setAcl/brokers/idsworld:anyone:cdrwa`设置为开放权限。但如果集群有安全认证,不能这样;安全模式下需要设置认证用户的ACL。-或者,完全删除节点:`delete/brokers/ids`–但`/brokers/ids`可能有数据。如果有子节点,用`rmr/brokers/ids`(删除递归)。删除后,Kafka服务器在启动时会重新创建它。-**重启Kafka服务器**。在禁用安全功能后:-确保所有Zookeeper路径的ACL被清除。参考引用[1],运行工具或命令来移除ACL。可能用脚本或使用`kafka-configs.sh`工具。其他参考:搜索类似问题,标准方案是删除Zookeeper节点或修复ACL。在回答中,结构化:-解释错误原因。-提供解决步骤。-给出预防建议。引用来源:从引用[1],直接在提到时加[^1]。最后,生成相关问题:-KafkaACL是如何工作的?-如何避免在Kafka启动时出现ACL问题?-Kafka和Zookeeper之间的认证有哪些最佳实践?使用中文回答。</think> ### Kafka服务器启动错误 "InvalidACLException KeeperErrorCode=InvalidACL for /brokers/ids" 解决方案 这个错误通常发生在 Kafka 服务器启动时,涉及 Zookeeper 路径 `/brokers/ids` 的访问控制列表(ACL)无效或损坏。根据错误信息和参考内容(尤其是引用[1]),主要原因可能是: - **ACL 未正确清除**:在禁用 Kerberos 或更改安全配置时,Kafka znodes(如 `/brokers/ids`)的 ACL 可能未被完全移除,导致启动时 Zookeeper 拒绝访问[^1]。 - **ACL 配置冲突**:如果集群安全机制(如 SASL 或 SSL)被修改后,Zookeeper 中的 ACL 权限未同步更新,会出现权限无效问题。 以下是完整解决方法,逐步操作以修复错误: --- ### 步骤 1: 停止 Kafka 服务并备份 在操作前,确保 Kafka 集群停止运行,以避免数据不一致。 1. **停止 Kafka Broker**:运行 `bin/kafka-server-stop.sh`(Linux)或相应脚本停止所有 Kafka 节点。 2. **备份 Zookeeper 数据**(推荐): - 连接到 Zookeeper:`bin/zkCli.sh -server localhost:2181`(替换为您的 Zookeeper 地址)。 - 导出节点数据:`get /brokers/ids > backup.txt` 保存为备份。 这能防止意外操作导致数据丢失。 --- ### 步骤 2: 修复 ACL 权限 使用 Zookeeper CLI 修复 `/brokers/ids` 的无效 ACL: 1. **连接到 Zookeeper**: ```bash bin/zkCli.sh -server zookeeper_host:port # 替换为实际地址,如 localhost:2181 ``` 2. **检查问题路径**: - 列出路径:`ls /brokers/ids`,确认节点存在。 - 查看当前 ACL:`getAcl /brokers/ids`。如果显示 `InvalidACL`,说明权限损坏。 3. **重置 ACL 为默认权限**: - 设置为开放权限(无安全认证时适用): ```bash setAcl /brokers/ids world:anyone:cdrwa # 设置全局读写权限[^1] ``` - 如果启用安全认证(如 SASL),使用认证用户设置: ```bash setAcl /brokers/ids sasl:user:kafka-admin:cdrwa # 替换为您的 Kafka 管理员用户 ``` 4. **可选:递归修复子节点**(如果错误涉及所有 Broker ID): ```bash rmr /brokers/ids # 删除整个节点(Kafka 启动时自动重建) ``` 警告:此操作会删除 Broker ID 元数据。Kafka 重启后 Broker 会重新注册新 ID,但需确保 Zookeeper 中无其他依赖错误。 --- ### 步骤 3: 重启并验证 1. **重启 Zookeeper**:执行 `bin/zkServer.sh restart` 确保权限生效。 2. **重启 Kafka**:运行 `bin/kafka-server-start.sh config/server.properties`。 3. **验证修复**: - 检查日志:`tail -f logs/server.log`。无 `InvalidACLException` 错误即成功。 - 测试功能:用 `bin/kafka-broker-api-versions.sh --bootstrap-server localhost:9092` 确认 Broker 状态正常。 --- ### 预防措施 - **安全配置变更时清理 ACL**:禁用 Kerberos 或 SASL 后,运行官方工具(如 `kafka-configs.sh`)显式清除 znodes ACL[^1]。 - **定期监控 ACL**:通过 `getAcl /brokers/ids` 检查权限一致性,避免配置漂移。 - **引用相关建议**:配置 SASL/SSL 认证时,确保 Zookeeper ACL 与 Kafka 同步(参考引用[2]的安全文档)[^2]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值