Kafka 集群环境搭建

序言

        说明下安装环境.在centos7上安装Kafka集群环境.

        Kafka 依赖Java环境,所以需要提前配置.Kafka有自带的Zookeeper,但是一般不用.

        Zookeeper集群环境安装请看另一篇文章.这里只描述kafka的环境搭建.

 

名词解释

  1.  Broker——Kafka集群包含一个或多个服务器,这种服务器被称为broker ;  
  2. Topic——每条发布到Kafka集群的消息都有一个类别,这个类别被称为Topic(物理上不同Topic的消息分开存储,逻辑上一个Topic的消息虽然保存于一个或多个broker上但用户只需指定消息的Topic即可生产或消费数据而不必关心数据存于何处)  
  3. Partition——Partition是物理上的概念,每个Topic包含一个或多个Partition. 
  4. Producer——负责发布消息到Kafka broker 
  5. Consumer——消息消费者,向Kafka broker读取消息的客户端。  
  6. Consumer Group——每个Consumer属于一个特定的Consumer Group(可为每个Consumer指定group name,若不指定group name则属于默认的group)。 

      Kafka的topic可以看做是一个记录流 ("/orders", "/user-signups"),每个topic都有一个日志,它存储在磁盘上。

      每个topic又被分成多个partition(区),每个partition在存储层面是append log文件,任何发布到partition的消息都会被直接追加到日志文件的尾部,Kafka Producer API用于生成数据记录流,Kafka Consumer API用于使用Kafka的记录流。  

       topic与日志相关联,日志是存储在磁盘上的数据结构,Kafka将producer的记录附加到topic日志的末尾。topic日志由分布在多个文件上的许多分区组成,这些文件可以分布在多个Kafka集群节点上。Kafka在集群的不同节点上分发topic日志分区,以实现具有水平可伸缩性的高性能。Spreading 分区有助于快速写入数据,Kafka将分区复制到许多节点以提供故障转移。 

 

关于Kafka集群建通信的问题

      在Kafka集群中会有一个或者多个broker,其中有一个broker会被选举为控制器(Kafka Controller),它负责管理整个集群中所有分区和副本的状态。当某个分区的leader副本出现故障时,由控制器负责为该分区选举新的leader副本。当检测到某个分区的ISR集合发生变化时,由控制器负责通知所有broker更新其元数据信息。当使用kafka-topics.sh脚本为某个topic增加分区数量时,同样还是由控制器负责分区的重新分配。
     这里请注意 kafka集群其实有两种类型的Leader,切都是由zookeeper选举产生的.即:Broker的Controller,Partition的Leader.

关于Kafka的高可用性

       引入Replication之后,同一个Partition可能会有多个Replica,而这时需要在这些Replication之间选出一个Leader,Producer和Consumer只与这个Leader交互,其它Replica作为Follower从Leader中复制数据。

  因为需要保证同一个Partition的多个Replica之间的数据一致性(其中一个宕机后其它Replica必须要能继续服务并且即不能造成数据重复也不能造成数据丢失)。如果没有一个Leader,所有Replica都可同时读/写数据,那就需要保证多个Replica之间互相(N×N条通路)同步数据,数据的一致性和有序性非常难保证,大大增加了Replication实现的复杂性,同时也增加了出现异常的机率。而引入Leader后,只有Leader负责数据读写,Follower只向Leader顺序Fetch数据(N条通路),系统更加简单且高效。

       为了更好的做负载均衡,Kafka尽量将所有的Partition均匀分配到整个集群上。一个典型的部署方式是一个Topic的Partition数量大于Broker的数量。同时为了提高Kafka的容错能力,也需要将同一个Partition的Replica尽量分散到不同的机器。实际上,如果所有的Replica都在同一个Broker上,那一旦该Broker宕机,该Partition的所有Replica都无法工作,也就达不到HA的效果。同时,如果某个Broker宕机了,需要保证它上面的负载可以被均匀的分配到其它幸存的所有Broker上。

       Producer在发布消息到某个Partition时,先通过ZooKeeper找到该Partition的Leader,然后无论该Topic的Replication Factor为多少,Producer只将该消息发送到该Partition的Leader。Leader会将该消息写入其本地Log。每个Follower都从Leader pull数据。这种方式上,Follower存储的数据顺序与Leader保持一致。Follower在收到该消息并写入其Log后,向Leader发送ACK。一旦Leader收到了ISR中的所有Replica的ACK,该消息就被认为已经commit了,Leader将增加HW并且向Producer发送ACK。

为了提高性能,每个Follower在接收到数据后就立马向Leader发送ACK,而非等到数据写入Log中。因此,对于已经commit的消息,Kafka只能保证它被存于多个Replica的内存中,而不能保证它们被持久化到磁盘中,也就不能完全保证异常发生后该条消息一定能被Consumer消费。

Consumer读消息也是从Leader读取,只有被commit过的消息才会暴露给Consumer。

安装集群

下载kafka,并解压.

[root@localhost cuiyaonan]# wget https://mirrors.tuna.tsinghua.edu.cn/apache/kafka/2.3.0/kafka_2.11-2.3.0.tgz

[root@[email protected] kafka]# tar -zxvf kafka_2.11-2.3.0.tgz 

[root@[email protected] kafka]# cp -rf kafka_2.11-2.3.0 kafka-01

[root@[email protected] kafka]# cp -rf kafka_2.11-2.3.0 kafka-02

[root@[email protected] kafka]# cp -rf kafka_2.11-2.3.0 kafka-03

 

然后依次修改config/server.properties 

# kafka服务器监听IP和端口,这里也可以写域名,只要能解析就行
listeners=PLAINTEXT://192.168.2.63:9092 

# 三台服务器的ID不能相同,第一台是1,第二台是2,第三台是3
broker.id=1

# 日志路径 依次类推k1,k2,k3
log.dirs=/home/cuiyaonan/kafka/logs/k1

# Zookeeper连接参数
zookeeper.connect=192.168.2.64:2181,192.168.2.64:2182,192.168.2.64:2183

 

另外其他的配置信息如下:

broker.id=0  #当前机器在集群中的唯一标识,和zookeeper的myid性质一样

port=19092 #当前kafka对外提供服务的端口默认是9092

host.name=192.168.7.100 #这个参数默认是关闭的,在0.8.1有个bug,DNS解析问题,失败率的问题。

num.network.threads=3 #这个是borker进行网络处理的线程数

num.io.threads=8 #这个是borker进行I/O处理的线程数

log.dirs=/opt/kafka/kafkalogs/ #消息存放的目录,这个目录可以配置为“,”逗号分割的表达式,上面的

num.io.threads要大于这个目录的个数这个目录,如果配置多个目录,新创建的topic他把消息持久化的地方是,当前以逗号分割的目录中,那个分区数最少就放那一个

socket.send.buffer.bytes=102400 #发送缓冲区buffer大小,数据不是一下子就发送的,先回存储到缓冲区了到达一定的大小后在发送,能提高性能

socket.receive.buffer.bytes=102400 #kafka接收缓冲区大小,当数据到达一定大小后在序列化到磁盘

socket.request.max.bytes=104857600 #这个参数是向kafka请求消息或者向kafka发送消息的请请求的最大数,这个值不能超过java的堆栈大小

num.partitions=1 #默认的分区数,一个topic默认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失效时间
(log.retention.hours=168 ),到目录查看是否有过期的消息如果有,删除

log.cleaner.enable=false #是否启用log压缩,一般不用启用,启用的话可以提高性能

zookeeper.connect=192.168.7.100:12181,192.168.7.101:12181,192.168.7.107:1218 
#设置zookeeper的连接端口

依次启动kafka

[root@[email protected] bin]# ./kafka-server-start.sh -daemon ../config/server.properties

 

创建与查看Topic

创建命令如下,其中zookeeper 如果是集群随便一个就行

[root@cuiyaonan2000 bin]# ./kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 3 --partitions 3 --topic testTopic

查看命令如下(换了个zookeeper查看)

[root@cuiyaonan2000 bin]#  ./kafka-topics.sh --list --zookeeper localhost:2182

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章