Zookeeper是一种在分布式系统中被广泛用来作为:分布式状态管理、分布式协调管理、分布式配置管理、和分布式锁服务的集群
zookeeper功能非常强大,可以实现诸如分布式应用配置管理、统一命名服务、状态同步服务、集群管理等功能,我们这里拿比较简单的分布式应用配置管理为例来说明。
假设我们的程序是分布式部署在多台机器上,如果我们要改变程序的配置文件,需要逐台机器去修改,非常麻烦,现在把这些配置全部放到zookeeper上去,保存在 zookeeper 的某个目录节点中,然后所有相关应用程序对这个目录节点进行监听,一旦配置信息发生变化,每个应用程序就会收到 zookeeper 的通知,然后从 zookeeper 获取新的配置信息应用到系统中。
kafka增加和减少服务器都会在Zookeeper节点上触发相应的事件
kafka系统会捕获这些事件,进行新一轮的负载均衡,客户端也会捕获这些事件来进行新一轮的处理
Kafka集群是把状态保存在Zookeeper中的,首先要部署Zookeeper集群
环境
操作系统: centos7.3
软件版本: zookeeper-3.4.12.tar.gz
三台服务器:
192.168.10.21
192.168.10.22
192.168.10.23
Zookeeper集群的工作是超过半数才能对外提供服务,成员数量一般为奇数台
1.布署java环境
tar xf jdk-8u181-linux-x64.tar.gz -C /usr/local/
ln -s /usr/local/jdk1.8.0_181/ /usr/local/java
cat /etc/profile.d/java.sh
export JAVA_HOME=/usr/local/java
export PATH=$JAVA_HOME/bin:$PATH
运行脚本
source /etc/profile.d/java.sh
java -version
java version “1.8.0_181”
Java™ SE Runtime Environment (build 1.8.0_181-b13)
Java HotSpot™ 64-Bit Server VM (build 25.181-b13, mixed mode)
java 环境部署成功
2.安装zookeeper
[root@host2 ~]# tar xf zookeeper-3.4.12.tar.gz -C /usr/local/
[root@host2 ~]# ln -s /usr/local/zookeeper-3.4.12/ /usr/local/zookee
3.修改配置文件
[root@host1 conf]# cd /usr/local/zookeeper/conf
[root@host1 conf]# cp zoo_sample.cfg zoo.cfg
4.创建数据目录及服务器id(每台机器都要做,并且id不一样)
[root@host1 conf]# mkdir /data/zookeeper/data{,log} -p
[root@host1 conf]# echo 1 > /data/zookeeper/data/myid
5.在所有机器上启动服务并查看
[root@host1 ~]# /usr/local/zookeeper/bin/zkServer.sh start #启动服务
ZooKeeper JMX enabled by default
Using config: /usr/local/zookeeper/bin/…/conf/zoo.cfg
Mode: leader
zk集群一般只有一个leader,多个follower,主一般是相应客户端的读写请求,而从主同步数据,当主挂掉之后就会从follower里投票选举一个leader出来
[root@host3 ~]# netstat -tanp |grep -E "2888|3888"
tcp6 0 0 192.168.10.23:3888 :: LISTEN 10865/java
tcp6 0 0 192.168.10.23:34380 192.168.10.21:3888 ESTABLISHED 10865/java
tcp6 0 0 192.168.10.23:46914 192.168.10.22:3888 ESTABLISHED 10865/java
tcp6 0 0 192.168.10.23:34188 192.168.10.22:2888 ESTABLISHED 10865/java
[root@host2 ~]# jps #查看运行的进程号
10948 Jps
10431 QuorumPeerMain
6.几点重要说明
1)、myid文件和server.myid 在快照目录下存放的标识本台服务器的文件,他是整个zk集群用来发现彼此的一个重要标识。
2)、zoo.cfg 文件是zookeeper配置文件在conf目录里。
3)、log4j.properties文件是zk的日志输出文件, 在conf目录里. 用java写的程序基本上有个共同点:日志都用log4j来进行管理。
4)、zkEnv.sh和zkServer.sh文件
zkServer.sh 主管理程序文件
zkEnv.sh 是主要配置zookeeper集群启动时配置环境变量的文件
5)、还有一个需要注意: zookeeper不会主动的清除旧的快照和日志文件,这个是操作者的责任。
清理方法:
一. 脚本+计划任务清理
二. 使用bin/zkCleanup.sh这个脚本清理,具体使用方法找官方文档
三. 从3.4.0开始,zookeeper提供了自动清理snapshot和事务日志的功能,通过在zoo.cfg中配置两个参数实现:
autopurge.purgeInterval 清理频率,单位是小时,默认是0,表示不开启自动清理功能
autopurge.snapRetainCount 需要保留的文件数目, 默认是保留3个
环境
已经搭建好的zookeeper集群(虽然kafka中集成了zookeeper,但还是建议使用独立的zk集群)
软件版本kafka_2.12-2.1.0.tgz
以下操作在三台机器上都进行
[root@host1 ~]# tar xf kafka_2.12-2.1.0.tgz -C /usr/local/
[root@host1 ~]# ln -s /usr/local/kafka_2.12-2.1.0/ /usr/local/kafka
创建数据目录
[root@host1 ~]# mkdir /data/kafka-logs
[root@host1 ~]# vim /usr/local/kafka/config/server.properties
注意不同颜色标记的部分
broker.id=1 #当前机器在集群中的唯一标识,和zookeeper的myid性质一样
listeners=PLAINTEXT://192.168.10.21:9092 #监听套接字
num.network.threads=3 #这个是borker进行网络处理的线程数
num.io.threads=8 #这个是borker进行I/O处理的线程数
socket.send.buffer.bytes=102400 #发送缓冲区buffer大小,数据不是一下子就发送的,先回存储到缓冲区了到达一定的大小后在发送,能提高性能
socket.receive.buffer.bytes=102400 #kafka接收缓冲区大小,当数据到达一定大小后在序列化到磁盘
socket.request.max.bytes=104857600 #这个参数是向kafka请求消息或者向kafka发送消息的请请求的最大数,这个值不能超过java的堆栈大小
log.dirs=/data/kafka-logs #消息存放的目录,这个目录可以配置为“,”逗号分割的表达式,上面的num.io.threads要大于这个目录的个数
#如果配置多个目录,新创建的topic把消息持久化在分区数最少那一个目录中
num.partitions=1 #默认的分区数,一个topic默认1个分区数
num.recovery.threads.per.data.dir=1 #在启动时恢复日志和关闭时刷新日志时每个数据目录的线程的数量,默认1
offsets.topic.replication.factor=2
transaction.state.log.replication.factor=1
transaction.state.log.min.isr=1
log.retention.hours=168 #默认消息的最大持久化时间,168小时,7天
message.max.byte=5242880 #消息保存的最大值5M
default.replication.factor=2 #kafka保存消息的副本数
replica.fetch.max.bytes=5242880 #取消息的最大字节数
log.segment.bytes=1073741824 #这个参数是:因为kafka的消息是以追加的形式落地到文件,当超过这个值的时候,kafka会新起一个文件
log.retention.check.interval.ms=300000 #每隔300000毫秒去检查上面配置的log失效时间,到目录查看是否有过期的消息如果有,删除
zookeeper.connect=192.168.10.21:2181,192.168.10.22:2181,192.168.10.23:2181
zookeeper.connection.timeout.ms=6000
group.initial.rebalance.delay.ms=0
启动kafka
[root@host1 ~]# /usr/local/kafka/bin/kafka-server-start.sh /usr/local/kafka/config/server.properties &
查看启动情况
[root@host1 ~]# jps
10754 QuorumPeerMain
11911 Kafka
12287 Jps
创建topic来验证
[root@host1 ~]# /usr/local/kafka/bin/kafka-topics.sh --create --zookeeper 192.168.10.21:2181 --replication-factor 2 --partitions 1 --topic qianfeng
Created topic "qianfeng".
在一台服务器上创建一个发布者
[root@host2 ~]# /usr/local/kafka/bin/kafka-console-producer.sh --broker-list 192.168.10.22:9092 --topic qianfeng
> hello kafka
> ni hao ya
>
在另一台服务器上创建一个订阅者
[root@host3 ~]# /usr/local/kafka/bin/kafka-console-consumer.sh --bootstrap-server 192.168.10.21:9092 --topic qianfeng --from-beginning
...
hello kafka
ni hao ya
如果都能接收到,说明kafka部署成功
[root@host3 ~]# /usr/local/kafka/bin/kafka-topics.sh --zookeeper 192.168.10.23:2181 --list #查看所有topic
[root@host3 ~]# /usr/local/kafka/bin/kafka-topics.sh --describe --zookeeper 192.168.10.23:2181 --topic qianfeng #查看指定topic的详细信息
Topic:qianfeng PartitionCount:1 ReplicationFactor:2 Configs:
Topic: qianfeng Partition: 0 Leader: 2 Replicas: 2,3 Isr: 2,3
[root@host3 ~]# /usr/local/kafka/bin/kafka-topics.sh --delete --zookeeper 192.168.10.23:2181 --topic qianfeng #删除topic
Topic qianfeng is marked for deletion.
Note: This will have no impact if delete.topic.enable is not set to true.
下面我们将logstash的输出改到kafka上面,将数据写入到kafka中
不要过滤, logstash会将message内容写入到队列中
# cat logstash-kafka.conf
input {
file {
type => "sys-log"
path => "/var/log/messages"
start_position => beginning
}
}
output {
kafka {
bootstrap_servers => "192.168.10.21:9092,192.168.10.22:9092,192.168.10.23:9092" #输出到kafka集群
topic_id => "sys-log-messages" #主题名称
compression_type => "snappy" #压缩类型
codec => "json"
}
}
启动logstash
# /usr/local/logstash/bin/logstash -f logstash-kafka.conf
在kafka上查看主题,发现已经有了sys-log-messages,说明写入成功了
[root@host2 ~]# /usr/local/kafka/bin/kafka-topics.sh --zookeeper 192.168.10.22:2181 --list
__consumer_offsets
qianfeng
sys-log-messages
[root@host2 ~]# /usr/local/kafka/bin/kafka-topics.sh --describe --zookeeper 192.168.10.22:2181 --topic sys-log-messages
Topic:sys-log-messages PartitionCount:1 ReplicationFactor:2 Configs:
Topic: sys-log-messages Partition: 0 Leader: 3 Replicas: 3,2 Isr: 3,2
接下来我们怎么将kafka中的内容写入到es集群中呢? 还是要利用logstash
# cat kafka-es.conf
input {
kafka {
bootstrap_servers => "192.168.10.21:9092,192.168.10.22:9092,192.168.10.23:9092"
topics => "output-test"
codec => "json"
auto_offset_reset => "earliest"
}
}
output {
elasticsearch {
hosts => ["192.168.10.11:9200","192.168.10.12:9200"]
index => "kafka-%{type}-%{+YYYY.MM.dd}"
}
}