今天下午写了一会代码,然后帮同事解决了一个hbase相关的故障分析,定位了问题根源,觉得比较有代表性,记录一下。
先说一下问题的发生与背景。
这个故障其实是分为两个故障的,第一个比较简单,第二个相对复杂一些。
同事写了一个HBase相关的测试代码,使用Hbase原生Java API,编译打包后分别放在两台测试服务器测试,一台可以,另一台不可以。
第一个故障是发生在两台测试服务器的:
A服务器是正常连通的服务器,装了HBase,centos6
B服务器是无法连通的服务器,没装HBase,centos7
表象是在A服务器可以正常跑编译的jar包,B服务器无法正常跑,卡在连接Zookeeper获取table list的部分就不动了。
看到这知道了吧,其实跟服务器装没装HBase一点关系都没有。
首先怀疑是防火墙,先关掉B服务器的firewalld,没起作用,然后用netstat看了一下,发现A服务器连接Hbase走的是tcp,而B服务器是centos7,连接hbase走的是tcp6,而hbase集群是centos6,没有ipv6,禁用B服务器的tcp6,然后仍然没起作用。
netstat查看HBase ZK服务器,跟B服务器也建立连接了,也ESTABLISHED了,就是不返回数据。
之后,唉,在经过35次超时以后,报错日志出来了,是B服务器里缺少一条A主机名IP的映射的关系,而同事写的代码里又要连接B主机里那个并不存在的A主机,于是就卡在了查询主机名的过程中,将A主机加到/etc/hosts里面,故障解决。
然后第二个故障的判断是比较有意思的,仍然是这个程序,我们有两个集群,机房分别在无锡和杭州。该代码需要从杭州机房请求无锡机房的HBase集群取数据,然后跟第一个故障的表象一模一样,毫无区别,都是无法通过zookeeper获取table list,但是整个操作系统环境肯定是没问题。
虽然表象一样,但是原因相差十万八千里。注明一下:无锡的×××网段是10开头的A类地址,杭州是172开头的B类地址,需要跑数据的杭州服务器和无锡的HBase之间由运维同事做了×××链接。
然后我们动用了jstack,strace各种工具都看不出问题。
jstack提示卡在listTable的线程上,strace卡在FUTEX_WAIT上,看不出来,然后超出35次超时以后的报错也看不出啥问题。HBase的listtable方法只连接单台zk服务器,所以也没有映射全部HBase主机名到hosts的必要。
看了一眼netstat,发现杭州机房172发送了请求杭州机房10网段zk 2181端口的请求,记得是停在了SYN_SEND上,半天也没有ESTABLISHED,然后马上又看了一下无锡HBase的netstat,发现根本没有连接建立,立即大彻大悟。
跟同事分析了一下,应该是×××的隧道连接是单向路由或者以NAT方式连接的,我推测应该是无锡10网段的×××可能是NAT,是可以通过×××连接杭州172网段的,而杭州172网段无法连接无锡10网段,于是让同事在两边分别做了ping测试,结果和我预想的一样,杭州无法ping通无锡,而无锡可以ping通杭州。
因为做×××的运维同事不在,打电话问了一下,确实×××是单向路由,至此问题就算解决了,等着运维同事回来加路由表应该就好了。
两个问题的排查解决差不多一个多小时吧,没写完kerberos的principal/keytab管理页面就快下班了。这是另外一个集群的故事了。
说明40岁的老程序员还是有点作用的,还是能快速解决点问题,还是有活下去的价值的。
原创文章,作者:kepupublish,如若转载,请注明出处:https://blog.ytso.com/191454.html