目录

一次ZK、Kafka连接慢的问题排查

目录

我们搭建了大数据集群系统。发现有些环境上ZooKeeper、Kafka、以及HDFS的ZKFC、HBase,他们服务状态作时好时坏,频繁出现不能提供服务。从稍微底层的ZK开始排查。

每次手动尝试用zkCli.sh命令行工具连接ZK时,总需要等待三四秒后,才能成功连上。按道理内网速度不应该这么慢。连上后,过了几秒也会有自动断连的现象。除了这两个奇怪的现象以外,没有其他发现。

上层服务ZKFC的日志显示,ZK不停闪断超时重连……导致它所管理的NameNode无法选主。

随后尝试在使用zkCli.sh工具连接ZK,在卡住的时候,使用JDK工具(jstack)抓出了线程堆栈信息。

结合源码里与客户端建立连接的部分来看,找到了卡住的线程,定位到了堆栈停留的点:

java.security.jgss/sun/security/krb5/PrincipalName.java:414

java.net.InetAddress#getByName(java.lang.String)

此处使用了Kerberos的域名进行了DNS查询,本地DNS查不到会去上游递归查询,最终导致耗时过长。

/posts/20220825005632/8bac5ac052a2424b9ef90128e81b1e7a.png

解决此方法有4种:

  1. 在DNS服务器处配置恰当的IP和主机名的关系,使其快速返回
  2. 本机/etc/resolv.conf清空,但这会使本机DNS功能失效
  3. 将Kerberos域名配置到/etc/hosts中,IP为一个本地局域网内无法连通的IP,如1.1.1.1 hadoop.hadoop.com
  4. 若使用的是JDK12版本,在krb5.conf配置文件中配置以下内容可以规避此类问题,关于此配置项的解释可以参考MIT Kerberos Documentation
1
2
[libdefaults]
dns_canonicalize_hostname = false

最早可以在JDK12版本中找到此补丁的合入8210821: Support dns_canonicalize_hostname in krb5.conf

/posts/20220825005632/75584712f22d408db91cabf15ffdebd7.png

/posts/20220825005632/019049dcdd1a42cba50d59943f324c1c.png