基于Kubernetes在AWS上部署Kafka时遇到的一些问题
作者:Jack47
转载请保留作者和原文出处
欢迎关注我的微信公众账号程序员杰克,两边的文章会同步,也可以添加我的RSS订阅源。
交代一下背景:我们的后台系统是一套使用Kafka消息队列的数据处理管线:Kafka->Logstash->Elasticsearch。这些组件都跑在Docker的容器环境里,我们是基于Kubernetes来编排整个后端的数据处理管线上的容器。Kafka需要暴露在外网里,接收Kafka Producer(filebeat, collectd)发过来的消息。本文是记录基于Kubernetes在AWS上部署Kafka 0.9.x版本时遇到的问题和排查思路。
为了能够在外网也能访问Kafka,Kafka组件对应的Kubernetes ServiceType选用的是NodePort,Kafka集群有三个节点,即Kafka Server有三个Broker。对外暴露的端口是39092,三个Broker对应的外网IP分别是 59.64.11.21,59.64.11.22,59.64.11.23。Kafka组件部署完成后,使用Kafka producer连接Server,配置的kafka bootstrap_servers是 59.64.11.22:39092。这里之所以端口使用的是 39092,而非9092,是因为Kubernetes对外暴露的端口,分配的是39092。接着往下看,你会发现这样会有问题。
connection refused
Kafka client的日志里报错:
2016-11-22T07:23:33.312102145Z 2016-11-22T07:23:33Z WARN Failed to connect to broker 59.64.11.21:30791: dial tcp 52.198.148.31:30791: getsockopt: connection refused
2016-11-22T07:23:33.312102145Z
2016-11-22T07:23:33.312102145Z 2016-11-22T07:23:33Z WARN kafka message: client/metadata got error from broker while fetching metadata:%!(EXTRA *net.OpError=dial tcp 52.198.148.31:30791: getsockopt: connection refused)
第一反应是去看AWS实例的安全组(Security Group),发现忘了允许39092这个端口的接入。配置完成后,重启Kafka client。
No available broker
接下来遇到了这个错误:
2016-11-22T07:23:33.312102145Z 2016-11-22T07:23:33Z WARN kafka message: client/metadata no available broker to send metadata request to
2016-11-22T07:23:33.312102145Z 2016-11-22T07:23:33Z WARN client/brokers resurrecting 1 dead seed brokers
Google一番,然后通过阅读Kafka的文档(一定要注意查看对应版本的文档),发现原因了。
当Kafka broker启动时,它会在ZK上注册自己的IP和端口号,客户端就通过这个IP和端口号来连接。在AWS这种IaaS环境下,由于java.net.InetAddress.getCanonicalHostName调用拿到的HostName是类似ip-172-31-10-199这样的只有内网才能访问到的主机名,所以默认注册到ZK上的IP是内网才能访问的内网IP。此时就需要显示指定 advertised.host.name, advertised.listeners参数,让注册到ZK上的IP是外网IP。
例如对于 59.64.11.22 IP对应的broker,需要在 server.properties 配置文件里增加如下三个配置:
advertised.listeners=PLAINTEXT://59.64.11.22:9092
advertised.host.name=59.64.11.22
advertised.port=9092
估计读者们也会跟我一样犯迷糊,为什么需要三个参数来配置IP和端口号呢,用一个advertised.listeners不就搞定了吗?后来发现最新版本0.10.x broker配置弃用了advertised.host.name 和 advertised.port 这两个个配置项,就配置advertised.listeners就可以了。:joy
found some partitions to be leaderless
2016-11-22T02:58:36Z WARN kafka message: client/metadata found some partitions to be leaderless
又是 Read The Fucking Manual,发现Kafka生产者会先连接 bootstrap_servers列表里的某个节点,这台机器只是用来获取集群的元数据(meta data):拿到topics,partitions和 replicas的信息。查到写入的topic对应的leader节点(可能不是刚才的那个节点)后,与之建立连接,然后发送实际的数据给leader。有了这个背景知识,上面的这个错误信息就不难理解了,说明获取元数据没问题,但是连不到对应的leader节点。经过跟同事探讨,发现了问题所在:Kafka使用的Kubernetes ServiceType是NodePort,而NodePort这种服务类型是有负载均衡的,所以Kafka producer连接 leader节点时,由于有负载均衡,所以实际会连到其他节点上。把Kafka从Kubernetes的普通服务改为了无头服务(Headless),然后端口要从NodePort改为HostPort这种类型。这样就没有负载均衡,同时又能从外网访问Kafka节点。
还是不行
上述改动改完后,发现还是报 found some partitions to be leaderless 的错。实在不行,那就只能去zk上去看看到底broker是什么状态了。
root@kafka-0:/usr/share/easemon/kafka/bin# ./zookeeper-shell.sh 10.10.18.3
ls /brokers/ids
[1012, 1013, 1014]
可以看到 有三个broker,id分别是 1012,1013,1014。然后接着看看这些broker注册的IP地址(接着在 zookeeper-shell里执行命令):
get /brokers/ids/1012
{"jmx_port":-1,"timestamp":"1480404348685","endpoints":["PLAINTEXT://59.64.11.22:9092"],"host":"59.64.11.22","version":2,"port":9092}
看起来也符合预期,注册到 59.64.11.22的9092端口上了。
那就看看filebeat这个topic相关的信息吧:
/usr/share/easemon/kafka/bin/kafka-topics.sh --zookeeper localhost:2181 --describe --topic filebeat
Topic:filebeat PartitionCount:3 ReplicationFactor:1 Configs:
Topic: filebeat Partition: 0 Leader: 1005 Replicas: 1005 Isr: 1005
Topic: filebeat Partition: 1 Leader: 1006 Replicas: 1006 Isr: 1006
Topic: filebeat Partition: 2 Leader: 1007 Replicas: 1007 Isr: 1007
等等,这里三个分区的leader怎么是1005,1006,1007呢,应该是1012,1013,1014才对。然后想到应该是Kafka的数据(通过配置项log.dirs指定位置)没有放到持久存储上,而是放到了Docker容器内,导致每次重新部署后,原来的数据都丢了,节点都注册到新的brokerID上去了。修改完成后,重新部署,发现Kafka上终于有数据了。
关于 Broker id
多说两句,我们环境中Kafka的Broker id是使用默认自动生成的id,所以都是1000以上的。而如果你的环境中如果是手工指定的,必须在1000以下,否则根据这篇文章,Kafka不报错,会直接退出。
自动创建Topic
auto.create.topics.enable 参数可以用来配置Kafka Server是否自动创建topic,但这个是针对Producer而言的,如果Consumer消费某个不存在的topic时,是不会触发自动创建的逻辑的。所以当Consumer消费某个不存在的topic时,由于具体的实现不一样,可能会出现报错的情况。
参考资料:
如果您看了本篇博客,觉得对您有所收获,请点击右下角的“推荐”,让更多人看到!
基于Kubernetes在AWS上部署Kafka时遇到的一些问题的更多相关文章
- 解读与部署(三):基于 Kubernetes 的微服务部署即代码
在基于 Kubernetes 的基础设施即代码一文中,我概要地介绍了基于 Kubernetes 的 .NET Core 微服务和 CI/CD 动手实践工作坊使用的基础设施是如何使用代码描述的,以及它的 ...
- 在Kubernetes上部署应用时我们常忽略的几件事
根据我的经验,大多数人(使用Helm或手动yaml)将应用程序部署到Kubernetes上,然后认为他们就可以一直稳定运行. 然而并非如此,实际使用过程还是遇到了一些"陷阱",我希 ...
- 关于在eclipse上部署Tomcat时出现8080等端口被占用问题的解决方法
问题描述: 在eclipse中部署Tomcat时,出现如下错误. 解决方法如下: 方法一: 1.开始->cmd->输入命令netstat -ano出现下图所示(注意下边显示有些错位,最后一 ...
- 在ubuntu18.04上部署项目时遇到的问题总结
因为在实验室中,有几台空闲的机子,我便选了一台准备做一个本地的服务器,因为买的阿里云学生机和之前用于FQ的机子感觉都不太顺手,阿里的学生机配置稍低,FQ用的服务器延迟太高.开始在centos和ubun ...
- 在ubuntu上部署hadoop时出现的问题
1. 配置ssh登录 不须要改动/etc/ssh/sshd_config 2. 新建hadoop用户时,home以下没有hadoop文件夹 用以下命令创建 useradd -m hadoop 3. n ...
- aws上部署zabbix3.4
三台机器 10.0.0.149 AmazonLinux2.0 zabbix-server zabbix-agent 10.0.1.61 CentOS6.9 zabbix-agent 10.0.1.11 ...
- 在AWS中部署OpenShift平台
OpenShift是RedHat出品的PAAS平台.OpenShift做为PAAS平台最大的特点是它是完全容器化的PAAS平台,底层封装了Docker和Kubernetes,上层暴露了对开发者友好的接 ...
- Kafka实战(七) - 优雅地部署 Kafka 集群
既然是集群,必然有多个Kafka节点,只有单节点构成的Kafka伪集群只能用于日常测试,不可能满足线上生产需求. 真正的线上环境需要考量各种因素,结合自身的业务需求而制定.看一些考虑因素(以下顺序,可 ...
- Win10上部署Apollo配置中心
基于Docker在Win10上部署Apollo配置中心 https://www.jianshu.com/p/a1215056ce75 http://nobodyiam.com/2016/07/09/i ...
随机推荐
- npm 私有模块的管理使用
你可以使用 NPM 命令行工具来管理你在 NPM 仓库的私有模块代码,这使得在项目中使用公共模块变的更加方便. 开始前的工作 你需要一个 2.7.0 以上版本的 npm ,并且需要有一个可以登陆 np ...
- 关于 Chrome 浏览器中 onresize 事件的 Bug
我在写插件时用到了 onresize 事件,在反复地测试后发现该事件在 Chrome 及 Opera(内核基本与 Chrome 相同,以下统称 Chrome)浏览器打开时就会执行,这种情况也许不能算作 ...
- Java基础Map接口+Collections
1.Map中我们主要讲两个接口 HashMap 与 LinkedHashMap (1)其中LinkedHashMap是有序的 怎么存怎么取出来 我们讲一下Map的增删改查功能: /* * Ma ...
- JavaScript特性(attribute)、属性(property)和样式(style)
最近在研读一本巨著<JavaScript忍者秘籍>,里面有一篇文章提到了这3个概念. 书中的源码可以在此下载.我将源码放到了线上,如果不想下载,可以直接访问在线网址,修改页面名就能访问到相 ...
- Spark踩坑记——数据库(Hbase+Mysql)
[TOC] 前言 在使用Spark Streaming的过程中对于计算产生结果的进行持久化时,我们往往需要操作数据库,去统计或者改变一些值.最近一个实时消费者处理任务,在使用spark streami ...
- NLP点滴——文本相似度
[TOC] 前言 在自然语言处理过程中,经常会涉及到如何度量两个文本之间的相似性,我们都知道文本是一种高维的语义空间,如何对其进行抽象分解,从而能够站在数学角度去量化其相似性.而有了文本之间相似性的度 ...
- CentOS下mysql数据库常用命令总结
mysql数据库使用总结 本文主要记录一些mysql日常使用的命令,供以后查询. 1.更改root密码 mysqladmin -uroot password 'yourpassword' 2.远程登陆 ...
- 【uwp】浅谈China Daily 中划词翻译的实现
学习uwp开发也有一段时间了,最近上架了一个小应用(China Daily),现在准备将开发中所学到的一些东西拿出来跟大家分享交流一下. 先给出应用的下载链接:China Daily , 感兴趣的童鞋 ...
- Collection集合
一些关于集合内部算法可以查阅这篇文章<容器类总结>. (Abstract+) Collection 子类:List,Queue,Set 增: add(E):boolean addAll(C ...
- PHP设计模式(八)桥接模式(Bridge For PHP)
一.概述 桥接模式:将两个原本不相关的类结合在一起,然后利用两个类中的方法和属性,输出一份新的结果. 二.案例 1.模拟毛笔(转) 需求:现在需要准备三种粗细(大中小),并且有五种颜色的比 如果使用蜡 ...