kafka zookeeper 集群 部署 参数 配置 以及 单机安装单进程zookeeper 和 kafka
kafka zookeeper 集群 部署 参数 配置 以及 单机安装单进程zookeeper 和 kafka
20180929 Chenxin
zookeeper
参考:
http://www.importnew.com/24411.html zookeeper入门
https://www.cnblogs.com/zhangjianbin/p/6285596.html zookeeper安装与配置
zookeeper概念
zookeeper到底是什么?
yahoo开发的,用于分布式中一致性处理的框架。
最初其作为研发Hadoop时的副产品。由于分布式系统中一致性处理较为困难,其他的分布式系统没有必要 费劲重复造轮子,故随后的分布式系统中大量应用了zookeeper,以至于zookeeper成为了各种分布式系统的基础组件,其地位之重要,可想而知。
著名的hadoop、kafka、dubbo 都是基于zookeeper而构建。
要想理解zookeeper到底是做啥的,那首先得理解清楚,什么是一致性。
hadoop
鼻祖级应用,ResourceManager在整个hadoop中算是单点,为了实现其高可用,分为主备ResourceManager,zookeeper在其中管理整个ResourceManager。
可以想象,主备ResourceManager最初是主RM提供服务,如果一切安好,则zookeeper无用武之地。
然而,总归会出现主RM提供不了服务的情况。于是会出现主备切换的情况,而zookeeper正是为主备切换保驾护航。
zookeeper又是如何解决脑裂问题的呢?
- zookeeper作为第三方集群参与到主备节点中去,当主备启动时会在zookeeper上竞争创建一个临时锁节点,争用成功者则充当主机,其余备机;
- 所有备机会监听该临时锁节点,一旦主机与zookeeper间session失效,则临时节点被删除;
- 一旦临时节点被删除,备机开始重新申请创建临时锁节点,重新争用为主机;
- 用zookeeper如何解决脑裂?实际上主机争用到节点后通过对根节点做一个ACL权限控制,则其他抢占的机器由于无法更新临时锁节点,只有放弃成为备机。
dubbo
作为业界知名的分布式SOA框架,dubbo的主要的服务注册发现功能便是由zookeeper来提供的。
zookeeper提供的原语服务
- 创建节点
- 删除节点
- 更新节点
- 获取节点信息
- 权限控制
- 事件监听
zookeeper安装与配置
参考:
https://www.cnblogs.com/zhangjianbin/p/6285596.html
下载安装包
http://mirror.bit.edu.cn/apache/zookeeper/zookeeper-3.4.13/zookeeper-3.4.13.tar.gz
解压到合适目录即可
这里使用3台机器构建集群.内网IP分别为: 10.0.0.99/170/238
这里考虑到开发人员可能会临时调整参数(测试阶段),故考虑将应用放置在/home/xbzj/用户目录下.
zookeeper配置
zoo.cfg
/home/xbzj/zookeeper/conf/zoo.cfg 文件是zookeeper配置文件 在conf目录里。
/home/xbzj/zookeeper/conf/log4j.properties 文件是zk的日志输出文件 在conf目录里.用java写的程序基本上有个共同点日志都用log4j,来进行管理。
[xbzj@ip-10-0-0-99 conf]$ cat /home/xbzj/zookeeper/conf/zoo.cfg |grep -v "#"
tickTime=2000 #基本时间单位, 毫秒值.
initLimit=5 #集群中多台server, 一台为leader, 其余为follower.初始化连接时, follower和leader之间的最长心跳数. 设置为5, 说明时间限制为5倍tickTime, 即5*2000=10s.
syncLimit=2 #配置leader和follower之间发送消息, 请求和应答的最大时间长度. 设置为2, 说明时间限制为2倍tickTime, 即4000ms.
dataDir=/home/xbzj/zookeeper/data #数据目录. 可以是任意目录.
dataLogDir=/home/xbzj/zookeeper/logs #log目录, 同样可以是任意目录. 如果没有设置该参数, 将使用和dataDir相同的设置.
clientPort=4180 #监听client连接的端口号.
server.99=10.0.0.99:2888:3888 #server.X=A:B:C 其中X是一个数字, 表示这是几号server. A是该server所在的IP地址.
server.170=10.0.0.170:2888:3888 #B(2888)配置该机器与集群中的leader交换消息所使用的端口. C(3888)配置选举leader时所使用的端口.
server.238=10.0.0.238:2888:3888
注意: 配置文件里不可以在同一行包含注释
myid
在dataDir中新建myid文件, 写入一个数字, 该数字表示这是几号server. 该数字必须和zoo.cfg文件中的server.X中的X对应.
[xbzj@ip-10-0-0-99 zookeeper]$ cat /home/xbzj/zookeeper/data/myid
99
myid文件和server.myid(自动生成的) 标识本台服务器的标志,是整个zk集群用来发现彼此的一个重要标识。
[xbzj@ip-10-0-0-99 zookeeper]$ cat /home/xbzj/zookeeper/data/zookeeper_server.pid
5233 #自动的,不用管
zookeeper启动
分别到3台机器上
cd /home/xbzj/zookeeper/ && bin/zkServer.sh start #主管理程序文件.启动会在当前目录下有zookeeper.out文件落盘.
其他文件说明
/home/xbzj/zookeeper/bin/zkEnv.sh #是主要配置,zookeeper集群启动时配置环境变量的文件.(暂未配置,采用默认)
/home/xbzj/zookeeper/zookeeper.out #为控制台输出文件
zookeeper状态查看
/home/xbzj/zookeeper/bin/zkServer.sh status
输出:
ZooKeeper JMX enabled by default
Using config: /home/xbzj/zookeeper/bin/../conf/zoo.cfg
Mode: follower #leader为领导者,follower为追随者.
zk集群只有一个leader,多个follower.
主响应客户端的读写请求,从主同步数据,当主挂掉之后就会从follower里投票选举一个leader出来.
可以用“jps”查看zk的进程,这个是zk的整个工程的main
[xbzj@ip-10-0-0-99 ~]$ jps
5233 QuorumPeerMain
8940 Jps
6861 Kafka
zookeeper测试与确认集群
启动client连接server, 执行脚本:
/home/xbzj/zookeeper/bin/zkCli.sh -server localhost:4180 #这里也可以是其他IP
zookeeper关闭
/home/xbzj/zookeeper/bin/zkServer.sh stop
zookeeper日志清理
注意
zookeeper不会主动的清除旧的快照和日志文件.但可通过命令或配置定期清理.
第一种(推荐使用第一种方法,将日志清理工作独立出来,便于统一管理也更可控)
!/bin/bash
snapshot file dir
dataDir=/home/xbzj/zookeeper/data/version-2
tran log dir
dataLogDir=/home/xbzj/zookeeper/logs/version-2
Leave 66 files
count=66
count=$[$count+1]
ls -t $dataLogDir/log.* | tail -n +$count | xargs rm -f #ls -t 按照修改时间顺序;tail -n +2最新的1个不显示;tail -n -2显示最旧的2个.
ls -t $dataDir/snapshot.* | tail -n +$count | xargs rm -f
以上这个脚本定义了删除对应两个目录中的文件,保留最新的66个文件,可以将他写到crontab中,设置为每天凌晨2点执行一次就可以了。
第二种
ZK自己已经写好了脚本,在bin/zkCleanup.sh中,所以直接使用这个脚本也是可以执行清理工作的。
第三种
从3.4.0开始,zookeeper提供了自动清理snapshot和事务日志的功能,通过配置autopurge.purgeInterval和autopurge.snapRetainCount 参数实现定时清理.
两个参数在zoo.cfg中配置(默认是注释的):
autopurge.purgeInterval=1 #默认是0,不开启.清理频率,单位是小时,需要填写一个1或更大的整数,默认是0,表示不开启自己清理功能。
autopurge.snapRetainCount=3 #默认注释.这个参数和上面的参数搭配使用,这个参数指定了需要保留的文件数目。默认是保留3个。
zookeeper端口说明
2888 leader机器上开启的
3888 所有zk机器上都会开启
kafka
kafka概念
参考: https://www.jianshu.com/p/09ffb78d1de7
kafka是什么
Apache Kafka是一个开源消息系统,由Scala写成。是由Apache软件基金会开发的一个开源消息系统项目,该项目的目标是为处理实时数据提供一个统一、高通量、低等待的平台。
Kafka是一个分布式消息队列:生产者、消费者的功能。
Kafka对消息保存时根据Topic进行归类,发送消息者称为Producer,消息接受者称为Consumer,此外kafka集群有多个kafka实例组成,每个实例(server)称为broker。无论是kafka集群,还是producer和consumer都依赖于zookeeper集群保存一些meta信息,来保证系统可用性.
kafka特性
高吞吐率:即使在普通的节点上每秒钟也能处理成百上千的 message。
显式分布式:即所有的 producer、broker 和 consumer 都会有多个,均为分布式的。
易于扩展:可以由一个节点扩展至数千个节点,不需要停止集群。
kafka组件
Producer: 消息生产者,产生的消息将会被发送到某个topic.消息生产者,就是向kafka broker发消息的客户端。
Consumer: 消息消费者,消费的消息内容来自某个topic.消息消费者,向kafka broker取消息的客户端.
Topic: 消息根据topic进行归类,topic其本质是一个目录,即将同一主题消息归类到同一个目录.可以理解为一个队列.
Broker: 每一个kafka实例(或者说每台kafka服务器节点)就是一个broker,一个broker可以有多个topic.
Consumer Group(CG): 这是kafka用来实现一个topic消息的广播(发给所有的consumer)和单播(发给任意一个consumer)的手段。一个topic可以有多个CG。topic的消息会复制(不是真的复制,是概念上的)到所有的CG,但每个partion只会把消息发给该CG中的一个consumer。如果需要实现广播,只要每个consumer有一个独立的CG就可以了。要实现单播只要所有的consumer在同一个CG。用CG还可以将consumer进行自由的分组而不需要多次发送消息到不同的topic。
Partition: 为实现扩展性,一个大的topic可以分布到多个broker(即服务器)上,一个topic可以分为多个partition,每个partition是一个有序的队列。partition中的每条消息都会被分配一个有序的id(offset).kafka只保证按一个partition中的顺序将消息发给consumer,不保证一个topic的整体(多个partition间)的顺序。
Zookeeper: zookeeper集群不属于kafka内的组件,但kafka依赖zookeeper集群保存meta信息.
Kafka数据处理步骤
1Producer产生消息,发送到Broker中.
2Leader状态的Broker接收消息,写入到相应topic中.
3Leader状态的Broker接收完毕以后,传给Follow状态的Broker作为副本备份.
4Consumer消费Broker中的消息.
原理
Kafka 使用文件存储消息(append only log),这就直接决定了 kafka 在性能上严重依赖文件系统的本身特性。为了减少磁盘写入的次数,broker 会将消息暂时缓存起来,当消息的个数(或尺寸)达到一定阀值时,再一起刷新到磁盘,这样会减少磁盘 IO 调用的次数。
Producer 将会和 topic 下所有 partition leader 保持 socket 连接。消息由 producer 直接通过 socket 发送到 broker,中间不会经过任何“路由层”。事实上,消息被路由到哪个 partition 上,由 producer 客户端决定,默认方式为“轮询”。
Consumer 端向 broker 发送 “fetch” 请求,并告知其获取消息的 offset,此后 consumer 将会获得一定条数的消息。Consumer 端也可以重置 offset 来重新消费消息。
Kafka 将每个 partition 数据复制到多个 server 上,任何一个 partition 都有一个 leader 和多个 follower (可以没有)。
备份的个数可以通过 broker 配置文件来设定,其中 leader 处理所有的读写请求,follower 需要和 leader 保持同步。
当 leader 失效时,需在 followers 中重新选取出新的 leader,可能此时 follower 落后于 leader,因此需要选择一个 “up-to-date” 的 follower。选择 follower 时需要兼顾一个问题,就是新的 leader server 上所已经承载的 partition leader 的个数,如果一个 server 上有过多的 partition leader,意味着此 server 将承受着更多的 IO 压力,因此在选举新 leader 时,需要考虑到“负载均衡”。
Kafka 中所有的 topic 内容都是以日志的形式存储在 broker 上。如果一个 topic 的名称为 “my_topic”,它有 2 个 partitions,那么日志将会保存在 my_topic_0 和 my_topic_1 两个目录中。
部署架构
Kafka 集群、producer 和 consumer 都依赖于 zookeeper 来保证系统的可用性,保存一些元数据信息。
kafka 集群几乎不需要维护任何 consumer 和 producer 状态信息,这些信息由 zookeeper 保存,因此 producer 和 consumer 的客户端实现非常轻量级,它们可以随意离开,而不会对集群造成额外的影响。
Broker 端使用 zookeeper 来注册 broker 信息,监测 partition leader 存活性。
Producer 端使用 zookeeper 来发现 broker 列表,以及和 Topic 下每个 partition leader 建立 socket 连接并发送消息。
Consumer 端使用zookeeper 来注册consumer信息,其中包括consumer消费的partition列表等,同时也用来发现broker列表,并和partition leader建立socket 连接,获取消息.
kafka下载安装
参考(官方) https://kafka.apache.org/quickstart
cd /home/xbzj/
wget https://www.apache.org/dyn/closer.cgi?path=/kafka/2.0.0/kafka_2.11-2.0.0.tgz
tar -xzf kafka_2.11-2.0.0.tgz
mv kafka_2.11-2.0.0 kafka
cd kafka_2.11-2.0.0
启动zookeeper集群
请参考zookeeper
kafka hostname绑定
分别在3台机器上绑定主机名和IP(kafka会自动使用主机名)
[xbzj@ip-10-0-0-99 ~]$ cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost6 localhost6.localdomain6
10.0.0.99 ip-10-0-0-99
10.0.0.170 ip-10-0-0-170
10.0.0.238 ip-10-0-0-238
配置kafka集群
3台机器上配置文件注意区别(kafka版本2.0.0的默认配置文件与1.0.2相同)
参考 https://blog.csdn.net/l1028386804/article/details/79194929 Kafka配置文件server.properties
参考 https://www.jianshu.com/p/f56f58d99be3
[xbzj@ip-10-0-0-99 ~]$ cat /home/xbzj/kafka/config/server.properties
broker.id=99 # The id of the broker. This must be set to a unique integer for each broker
port=9092 #(弃用此格式)kafka监听端口,最好用 listeners = PLAINTEXT://ip-10-0-0-99:9092 应该就是需要配置绑定hosts的原因 (套接字服务器监听的地址.如果没有配置,就使用java.net.InetAddress.getCanonicalHostName()的返回值)
listeners = PLAINTEXT://10.0.0.99:9092 #绑定IP
listeners = PLAINTEXT://:9092 #默认绑定主机名(如果是NAT,客户端直接在本地绑定host即可访问集群)
log.dirs=/home/xbzj/kafka/logs #日志
num.network.threads=3 #服务器用来接收请求或者发送响应的线程数
num.io.threads=8 #服务器用来处理请求的线程数,可能包括磁盘IO
socket.send.buffer.bytes=102400 #套接字服务器使用的发送缓冲区大小
socket.receive.buffer.bytes=102400 #套接字服务器使用的接收缓冲区大小
socket.request.max.bytes=104857600 #单个请求最大能接收的数据量
num.partitions=3 #每个主题的日志分区的默认数量1.更多的分区允许更大的并行操作,但是它会导致节点产生更多的文件.生成环境建议3
num.recovery.threads.per.data.dir=1 #带raid的可以增加这个值.每个数据目录中的线程数,用于启动时的日志恢复和关闭时的刷新
offsets.topic.replication.factor=3 #生产环境建议3
transaction.state.log.replication.factor=3 #生产环境建议3
transaction.state.log.min.isr=3 #生产环境建议3
log.retention.hours=168 #Log Retention Policy. 数据保留168小时(一周)?超过的删除?
log.segment.bytes=1073741824 # 最大 log segment file. 达到后a new log segment will be created.
log.retention.check.interval.ms=300000 #log文件的5分钟检测间隔,单位ms
zookeeper.connect=10.0.0.99:4180,10.0.0.170:4180,10.0.0.238:4180 #zk地址端口
zookeeper.connection.timeout.ms=6000 #连接zk的超时时间
group.initial.rebalance.delay.ms=0 #这里生产环境调整为了3000
delete.topic.enable = false # 不允许删除topic(待生产环境测试是否可用).这个参数默认就是false.
启动kafka集群
在3台机器上执行
cd /home/xbzj/kafka/ && nohup /home/xbzj/kafka/bin/kafka-server-start.sh /home/xbzj/kafka/config/server.properties >nohup.out 2>&1 &
验证kafka集群 状态检查 创建topic 生产数据 消费数据
创建一个topic
[xbzj@ip-10-0-0-99 kafka]$ /home/xbzj/kafka/bin/kafka-topics.sh --create --zookeeper localhost:4180 --replication-factor 3 --partitions 1 --topic my-replicated-topic
描述检查
[xbzj@ip-10-0-0-99 kafka]$ /home/xbzj/kafka/bin/kafka-topics.sh --describe --zookeeper 10.0.0.238:4180 --topic my-replicated-topic
Topic:my-replicated-topic PartitionCount:1 ReplicationFactor:3 Configs:
Topic: my-replicated-topic Partition: 0 Leader: 99 Replicas: 99,170,238 Isr: 99
[xbzj@ip-10-0-0-99 kafka]$ /home/xbzj/kafka/bin/kafka-topics.sh --list --zookeeper 10.0.0.99:4180 #也可以是其他地址10.0.0.170/238
my-replicated-topic
生产数据
/home/xbzj/kafka/bin/kafka-console-producer.sh --broker-list localhost:9092 --topic my-replicated-topic
输入
my test message 1
my test message 2
消费数据
/home/xbzj/kafka/bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --from-beginning --topic my-replicated-topic
输出:
my test message 1
my test message 2
停掉kafka集群
在3台机器上执行
/home/xbzj/kafka/bin/kafka-server-stop.sh
kafka的JVM参数配置
在/home/xbzj/kafka/bin/kafka-server-start.sh 文件里.配置不要太大,太大gc时间也比较久,影响效率.一般是4GB以下.
默认是1G: KAFKA_HEAP_OPTS="-Xmx1G -Xms1G"
端口说明
9092 所有kf机器上都会开启
其他配置文件与参数文件说明
配置文件(含部分字典)
https://blog.csdn.net/Dream_Flying_BJ/article/details/73188662 broker、producter、consumer三个不同的配置
https://blog.csdn.net/baiducheng/article/details/78663571 producter、consumer
字典
http://kafka.apache.org/documentation/#brokerconfigs 参数列表说明
https://blog.csdn.net/zo_184/article/details/52177014 broker config
涉及文件
broker #貌似没有这个配置文件呢
producer.properties
consumer.properties
需要修改的基本都可以在server.properties 配置文件里完成.
单机安装单进程zookeeper 和 kafka 即 单broker安装与测试
2018/12/05 陈信
占用资源说明
默认配置文件启动后,占用内存 zookeeper为 512M, kafka为1GB.
安装程序
kafka自带zookeeper程序,所以只需要安装kafka就可以了.zookeeper的启动使用kafka自带的zookeeper.
cd /opt/;
wget http://mirror.bit.edu.cn/apache/kafka/2.0.0/kafka_2.11-2.0.0.tgz
tar xzvf kafka_2.11-2.0.0.tgz
mv kafka_2.11-2.0.0 /usr/local/kafka
对应JDK版本
java -version
java version "1.8.0_181"
tail /etc/profile
export JAVA_HOME=/usr/local/jvm
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.😒{JAVA_HOME}/lib:${JRE_HOME}/lib
export PATH=${JAVA_HOME}/bin:$PATH
export PATH=/usr/local/mysql/bin:/usr/local/mysql/lib:$PATH
配置文件
[root@ip-10-0-1-23 config]# ls /usr/local/kafka/
bin config libs LICENSE NOTICE site-docs 以下均采用默认配置文件(不更改config下文件,默认开启 zookeeper的2181 kafka的9092 端口)
启动进程
cd /usr/local/kafka/
启动zookeeper server(kafka自带的zookeeper)
nohup bin/zookeeper-server-start.sh config/zookeeper.properties > zk-nohup.out 2>&1 &
启动kafka server
nohup bin/kafka-server-start.sh config/server.properties > kfk-nohup.out 2>&1 &
遇到报错:
[2018-12-05 11:29:57,610] ERROR [KafkaServer id=0] Fatal error during KafkaServer startup. Prepare to shutdown (kafka.server.KafkaServer)
java.net.UnknownHostException: ip-10-0-1-23: ip-10-0-1-23: Name or service not known
需要绑定host:
[root@ip-10-0-1-23 kafka]# tail /etc/hosts
10.0.1.23 ip-10-0-1-23
创建主题(以下命令与参数同集群模式一样)
名称“test”、复制数目为1、partitions为1的topic主题
bin/kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic test
参数说明
replication-factor :
复制数目,提供failover机制;1代表只在一个broker上有数据记录,一般值都大于1,代表一份数据会自动同步到其他的多个broker,防止某个broker宕机后数据丢失。
partitions :
一个topic可以被切分成多个partitions,一个消费者可以消费多个partitions,但一个partitions只能被一个消费者消费,所以增加partitions可以增加消费者的吞吐量。kafka只保证一个partitions内的消息是有序的,多个一个partitions之间的数据是无序的。
查看已经创建的主题
bin/kafka-topics.sh --list --zookeeper localhost:2181
启动生产者
bin/kafka-console-producer.sh --broker-list localhost:9092 --topic test
启动后,在命令行下每输入一些字符串按下回车时,就作为一个消息并发送的kafka
启动消费者
新版本: bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --from-beginning --topic test
老版本: bin/kafka-console-consumer.sh --zookeeper localhost:2181 --topic test --from-beginning (已弃用)
启动消费者时,建议另开一个ssh窗口,方便一遍通过生产者命令行输入消息,一遍观察消费者消费的数据
查看两边数据
当在生产者下输入消息并回车后,在消费者窗口下就能立即看到对应的消息,这就说明环境搭建成功。
关闭程序
bin/kafka-server-stop.sh
bin/zookeeper-server-stop.sh
附录
单主机下的配置文件
[xbzj@ip-10-0-0-80 kafka]$ cat /home/xbzj/kafka/config/zookeeper.properties
clientPort=2181
clientPort=4180
maxClientCnxns=0
[xbzj@ip-10-0-0-80 kafka]$ cat /home/xbzj/kafka/config/server.properties
broker.id=0
port=9092
listeners = PLAINTEXT://10.0.0.99:9092
listeners = PLAINTEXT://:9092
num.network.threads=3
num.io.threads=8
socket.send.buffer.bytes=102400
socket.receive.buffer.bytes=102400
socket.request.max.bytes=104857600
log.dirs=/home/xbzj/kafka/logs
num.partitions=3
num.recovery.threads.per.data.dir=1
offsets.topic.replication.factor=1
transaction.state.log.replication.factor=1
transaction.state.log.min.isr=1
log.retention.hours=168
log.segment.bytes=1073741824
log.retention.check.interval.ms=300000
zookeeper.connect=localhost:4180
zookeeper.connection.timeout.ms=6000
group.initial.rebalance.delay.ms=3000