zookeeper+kafka群集

一.消息队列

1.什么是消息队列

消息队列(Message Queue)是一种应用间的通信方式,消息发送后可以立即返回,由消息系统来确保消息的可靠传递。消息发布者只管把消息发布到 MQ 中而不用管谁来取,消息使用者只管从 MQ 中取消息而不管是谁发布的。这样发布者和使用者都不用知道对方的存在。

2.消息队列的特征

(1)存储

消息队列通常将消息存储在某种类型的缓冲区中,直到目标进程读取这些消息或将其从消息队列中显式移除为止。

(2)异步

消息队列通过缓冲消息可以在应用程序中公开一定程度的异步性,允许源进程发送消息并在队列中累积消息,而目标进程则可以挑选消息进行处理。 这样,应用程序就可以在某些故障情况下运行,例如连接断断续续或源进程或目标进程故障。

路由:消息队列还可以提供路由功能,其中多个进程可以在同一队列中读取或写入消息,从而实现广播或单播通信模式。

3.为什么需要消息队列

(1)解耦

允许你独立的扩展或修改两边的处理过程,只要确保它们遵守同样的接口约束。

(2)冗余

消息队列把数据进行持久化直到他们已经被完全处理,通过这一方式规避了数据丢失风险。

(3)扩展性

因为消息队列解耦了你的处理过程,所以增大消息入队和处理的频率是很容易的,只要另外增加处理过程即可。

(4)灵活性&峰值处理能力

在访问量剧增的情况下,应用仍然需要继续发挥作用,但是这样的突发流量并不常见。如果为以能处理这类峰值访问为标准来投入资源随时待命无疑是巨大的浪费。使用消息队列能够使关键组件顶住突发的访问压力,而不会因为突发的超负荷的请求而完全崩溃。

(5)可恢复性

系统的一部分组件失效时,不会影响到整个系统。消息队列降低了进程间的耦合度,所以即使一个处理消息的进程挂掉,加入队列中的消息仍然可以在系统恢复后被处理。

(6)顺序保证

大部分消息队列本来就是排序的,并且能保证数据会按照特定的顺序来处理。(Kafka 保证一个 Partition 内的消息的有序性)

(7)缓冲

有助于控制和优化数据流经过系统的速度,解决生产消息和消费消息的处理速度不一致的情况。

(8)异步通信

很多时候,用户不想也不需要立即处理消息。消息队列提供了异步处理机制,允许用户把一个消息放入队列,但并不立即处理它。想向队列中放入多少消息就放多少,然后在需要的时候再去处理它们。

二.Kafka基础与入门

1.kafka基本概念

Kafka是一种高吞吐量的分布式发布/订阅消息系统,是Apache组织下的一个开源系统,它的最大的特性就是可以实时的处理大量数据以满足各种需求场景:比如基于hadoop平台的数据分析、低时延的实时系统、storm/spark流式处理引擎等。kafka现在它已被多家大型公司作为多种类型的数据管道和消息系统使用。

2.kafka角色术语

kafka的一些核心概念和角色

  1. Broker:Kafka集群包含一个或多个服务器,每个服务器被称为broker。
  2. Topic:每条发布到Kafka集群的消息都有一个分类,这个类别被称为Topic(主题)。
  3. Producer:指消息的生产者,负责发布消息到kafka broker。
  4. Consumer:指消息的消费者,从kafka broker拉取数据,并消费这些已发布的消息。
  5. Partition:Partition是物理上的概念,每个Topic包含一个或多个Partition,每个partition都是一个有序的队列。partition中的每条消息都会被分配一个有序的id(offset)。
  6. Consumer Group:消费者组,可以给每个Consumer指定消费组,若不指定消费者组,则属于默认的group。
  7. Message:消息,通信的基本单位,每个producer可以向一个topic发布一些消息。

3.kafka拓扑架构

一个典型的kafka集群包含了若干个Producer,若干broker、若干Consumer Group,以及一个Zookeeper集群。Kafka通过Zookeeper管理集群配置,选举leader,以及在Consumer Group发生变化时进行rebalance。Producer使用push模式将消息发布到broker,Consumer使用pull模式从broker订阅并消费消息。典型架构如下图所示:

 从图中可以看出,典型的消息系统有生产者(Producer),存储系统(broker)和消费者(Consumer)组成,Kafka作为分布式的消息系统支持多个生产者和多个消费者,生产者可以将消息分布到集群中不同节点的不同Partition上,消费者也可以消费集群中多个节点上的多个Partition。在写消息时允许多个生产者写到同一个Partition中,但是读消息时一个Partition只允许被一个消费组中的一个消费者所消费,而一个消费者可以消费多个Partition。也就是说同一个消费组下消费者对Partition是互斥的,而不同消费组之间是共享的

kafka支持消息持久化存储,持久化数据保存在kafka的日志文件中,在生产者生产消息后,kafka不会直接把消息传递给消费者,而是先要在broker中进行存储,为了减少磁盘写入的次数,broker会将消息暂时缓存起来,当消息的个数或尺寸、大小达到一定阀值时,再统一写到磁盘上,这样不但提高了kafka的执行效率,也减少了磁盘IO调用次数。

kafka中每条消息写到partition中,是顺序写入磁盘的,这个很重要,因为在机械盘中如果是随机写入的话,效率将是很低的,但是如果是顺序写入,那么效率却是非常高,这种顺序写入磁盘机制是kafka高吞吐率的一个很重要的保证。

4.Topic和partition

Kafka中的topic(主题)是以partition的形式存放的,每一个topic都可以设置它的partition数量,Partition的数量决定了组成topic的log的数量。推荐partition的数量一定要大于同时运行的consumer的数量。另外,建议partition的数量要小于等于集群broker的数量,这样消息数据就可以均匀的分布在各个broker中

5.produce生产机制

Producer是消息和数据的生产者,它发送消息到broker时,会根据Paritition机制选择将其存储到哪一个Partition。如果Partition机制设置的合理,所有消息都可以均匀分布到不同的Partition里,这样就实现了数据的负载均衡。

6.consumer消费机制

kafka发布消息通常有两种模式:队列模式(queuing)和发布/订阅模式(publish-subscribe)。在队列模式下,只有一个消费组,而这个消费组有多个消费者,一条消息只能被这个消费组中的一个消费者所消费;而在发布/订阅模式下,可有多个消费组,每个消费组只有一个消费者,同一条消息可被多个消费组消费。  

Kafka中的Producer和consumer采用的是push、pull的模式,即producer向 broker进行push消息,comsumer从bork进行pull消息,push和pull对于消息的生产和消费是异步进行的。pull模式的一个好处是consumer可自主控制消费消息的速率,同时consumer还可以自己控制消费消息的方式是批量的从broker拉取数据还是逐条消费数据。

三.zookeeper概念介绍

ZooKeeper是一种分布式协调技术,所谓分布式协调技术主要是用来解决分布式环境当中多个进程之间的同步控制,让他们有序的去访问某种共享资源,防止造成资源竞争(脑裂)的后果。脑裂是指在主备切换时,由于切换不彻底或其他原因,导致客户端和Slave误以为出现两个activemaster,最终使得整个集群处于混乱状态

1.zookeeper应用举例

(1)什么是单点故障问题

所谓单点故障,就是在一个主从的分布式系统中,主节点负责任务调度分发,从节点负责任务的处理,而当主节点发生故障时,整个应用系统也就瘫痪了,那么这种故障就称为单点故障。那我们的解决方法就是通过对集群master角色的选取,来解决分布式系统单点故障的问题。

(2)传统的方式是怎么解决单点故障的?以及有哪些缺点呢?

  传统的方式是采用一个备用节点,这个备用节点定期向主节点发送ping包,主节点收到ping包以后向备用节点发送回复Ack信息,当备用节点收到回复的时候就会认为当前主节点运行正常,让它继续提供服务。而当主节点故障时,备用节点就无法收到回复信息了,此时,备用节点就认为主节点宕机,然后接替它成为新的主节点继续提供服务。

  这种传统解决单点故障的方法,虽然在一定程度上解决了问题,但是有一个隐患,就是网络问题,可能会存在这样一种情况:主节点并没有出现故障,只是在回复ack响应的时候网络发生了故障,这样备用节点就无法收到回复,那么它就会认为主节点出现了故障,接着,备用节点将接管主节点的服务,并成为新的主节点,此时,分布式系统中就出现了两个主节点(双Master节点)的情况,双Master节点的出现,会导致分布式系统的服务发生混乱。这样的话,整个分布式系统将变得不可用。为了防止出现这种情况,就需要引入ZooKeeper来解决这种问题。

2.zookeeper的工作原理

(1)master启动

  在分布式系统中引入Zookeeper以后,就可以配置多个主节点,这里以配置两个主节点为例,假定它们是 主节点A 和 主节点B,当两个主节点都启动后,它们都会向ZooKeeper中注册节点信息。我们假设 主节点A 锁注册的节点信息是 master00001 , 主节点B 注册的节点信息是 master00002 ,注册完以后会进行选举,选举有多种算法,这里以编号最小作为选举算法,那么编号最小的节点将在选举中获胜并获得锁成为主节点,也就是 主节点A 将会获得锁成为主节点,然后 主节点B 将被阻塞成为一个备用节点。这样,通过这种方式Zookeeper就完成了对两个Master进程的调度。完成了主、备节点的分配和协作。

(2)master故障

  如果  主节点A 发生了故障,这时候它在ZooKeeper所注册的节点信息会被自动删除,而ZooKeeper会自动感知节点的变化,发现 主节点A  故障后,会再次发出选举,这时候  主节点B  将在选举中获胜,替代  主节点A  成为新的主节点,这样就完成了主、被节点的重新选举。

(3)master恢复

  如果主节点恢复了,它会再次向ZooKeeper注册自身的节点信息,只不过这时候它注册的节点信息将会变成 master00003 ,而不是原来的信息。ZooKeeper会感知节点的变化再次发动选举,这时候 主节点B 在选举中会再次获胜继续担任  主节点 , 主节点A 会担任备用节点。

zookeeper就是通过这样的协调、调度机制如此反复的对集群进行管理和状态同步的。

3.zookeeper的集群架构

zookeeper集群主要角色有server和client,其中server又分为leader、follower和observer三个角色,每个角色的含义如下:

Leader:领导者角色,主要负责投票的发起和决议,以及更新系统状态。

follower:跟随着角色,用于接收客户端的请求并返回结果给客户端,在选举过程中参与投票。

observer:观察者角色,用户接收客户端的请求,并将写请求转发给leader,同时同步leader状态,但是不参与投票。Observer目的是扩展系统,提高伸缩性。

client:客户端角色,用于向zookeeper发起请求。

4.zookeeper的工作流程

Zookeeper修改数据的流程:Zookeeper集群中每个Server在内存中存储了一份数据,在Zookeeper启动时,将从实例中选举一个Server作为leader,Leader负责处理数据更新等操作,当且仅当大多数Server在内存中成功修改数据,才认为数据修改成功。

Zookeeper写的流程为:客户端Client首先和一个Server或者Observe通信,发起写请求,然后Server将写请求转发给Leader,Leader再将写请求转发给其它Server,其它Server在接收到写请求后写入数据并响应Leader,Leader在接收到大多数写成功回应后,认为数据写成功,最后响应Client,完成一次写操作过程。

四.Zookeeper在Kafka中的作用

1.Broker注册

Broker是分布式部署并且相互之间相互独立,但是需要有一个注册系统能够将整个集群中的Broker管理起来,此时就使用到了Zookeeper。在Zookeeper上会有一个专门用来进行Broker服务器列表记录的节点:

/brokers/ids

每个Broker在启动时,都会到Zookeeper上进行注册,即到/brokers/ids下创建属于自己的节点,如/brokers/ids/[0...N]。

Broker创建的节点类型是临时节点,一旦Broker宕机,则对应的临时节点也会被自动删除。

2.Topic注册

3.生产者负载均衡

由于同一个Topic消息会被分区并将其分布在多个Broker上,因此,生产者需要将消息合理地发送到这些分布式的Broker上,那么如何实现生产者的负载均衡,Kafka支持传统的四层负载均衡,也支持Zookeeper方式实现负载均衡。

(1) 四层负载均衡

根据生产者的IP地址和端口来为其确定一个相关联的Broker。通常,一个生产者只会对应单个Broker,然后该生产者产生的消息都发往该Broker。这种方式逻辑简单,每个生产者不需要同其他系统建立额外的TCP连接,只需要和Broker维护单个TCP连接即可。但是,其无法做到真正的负载均衡,因为实际系统中的每个生产者产生的消息量及每个Broker的消息存储量都是不一样的,如果有些生产者产生的消息远多于其他生产者的话,那么会导致不同的Broker接收到的消息总数差异巨大,同时,生产者也无法实时感知到Broker的新增和删除。

(2) 使用Zookeeper进行负载均衡

由于每个Broker启动时,都会完成Broker注册过程,生产者会通过该节点的变化来动态地感知到Broker服务器列表的变更,这样就可以实现动态的负载均衡机制。

4.消费者负载均衡

与生产者类似,Kafka中的消费者同样需要进行负载均衡来实现多个消费者合理地从对应的Broker服务器上接收消息,每个消费者分组包含若干消费者,每条消息都只会发送给分组中的一个消费者,不同的消费者分组消费自己特定的Topic下面的消息,互不干扰。

5.分区与消费者的关系

消费组 (Consumer Group)下有多个 Consumer(消费者)。对于每个消费者组 (Consumer Group),Kafka都会为其分配一个全局唯一的Group ID,Group 内部的所有消费者共享该 ID。订阅的topic下的每个分区只能分配给某个 group 下的一个consumer(当然该分区还可以被分配给其他group)。
同时,Kafka为每个消费者分配一个Consumer ID,通常采用"Hostname:UUID"形式表示。

在Kafka中,规定了每个消息分区 只能被同组的一个消费者进行消费,因此,需要在 Zookeeper 上记录 消息分区 与 Consumer 之间的关系,每个消费者一旦确定了对一个消息分区的消费权力,需要将其Consumer ID 写入到 Zookeeper 对应消息分区的临时节点上

6.消息消费进度offset记录

在消费者对指定消息分区进行消息消费的过程中,需要定时地将分区消息的消费进度Offset记录到Zookeeper上,以便在该消费者进行重启或者其他消费者重新接管该消息分区的消息消费后,能够从之前的进度开始继续进行消息消费。Offset在Zookeeper中由一个专门节点进行记录,其节点路径为:

/consumers/[group_id]/offsets/[topic]/[broker_id-partition_id]

节点内容就是Offset的值。

五.单节点部署kafka

主机:

kafka1:192.168.10.101

1:安装zookeeper

[root@kafka1 ~]# yum -y install java

[root@kafka1 ~]# tar zxvf apache-zookeeper-3.6.0-bin.tar.gz

[root@kafka1 ~]# mv apache-zookeeper-3.6.0-bin /etc/zookeeper

[root@kafka1 ~]# cd /etc/zookeeper/conf

[root@kafka1 ~]# mv zoo_sample.cfg zoo.cfg

[root@kafka1 ~]# vim zoo.cfg

dataDir=/etc/zookeeper/zookeeper-data

[root@kafka1 ~]# cd /etc/zookeeper/

[root@kafka1 kafka]# mkdir /etc/zookeeper/zookeeper-data/

[root@kafka1 zookeeper]# ./bin/zkServer.sh start

[root@kafka1 zookeeper]# ./bin/zkServer.sh status

2:安装kafka

[root@kafka1 ~]# tar zxvf kafka_2.13-2.4.1.tgz

[root@kafka1 ~]# mv kafka_2.13-2.4.1 /etc/kafka

[root@kafka1 ~]# cd /etc/kafka/

[root@kafka1 kafka]# vim config/server.properties

log.dirs=/etc/kafka/kafka-logs #60行

[root@kafka1 kafka]# mkdir /etc/kafka/kafka-logs

[root@kafka1 kafka]# bin/kafka-server-start.sh  config/server.properties &

检查两个端口的开启状态

[root@kafka1 kafka]# netstat -anpt | grep 2181

[root@kafka1 kafka]# netstat -anpt | grep 9092

注意:启动时先启动zookeeper,关闭时先关闭kafka

如果要关闭zookeeper

[root@kafka1 zookeeper]# ./bin/zkServer.sh start

如果要关闭kafka

[root@192 kafka]# bin/kafka-server-stop.sh

如果关不了,就kill杀死该进程

3:测试

创建topic

bin/kafka-topics.sh --create --zookeeper kafka1:2181 --replication-factor 1 --partitions 1 --topic test

列出topic

bin/kafka-topics.sh --list --zookeeper kafka1:2181

查看topic

bin/kafka-topics.sh --describe --zookeeper kafka1:2181 --topic test

生产消息

bin/kafka-console-producer.sh --broker-list kafka1:9092 -topic test

消费消息

bin/kafka-console-consumer.sh --bootstrap-server kafka1:9092 --topic test

删除topic

bin/kafka-topics.sh --delete --zookeeper kafka1:2181 --topic test

五:群集部署kafka

主机

kafka1:192.168.10.101

kafka2:192.168.10.102

kafka3:192.168.10.103

1:zookeeper的部署

(1)安装zookeeper(三个节点的配置相同)

[root@kafka1 ~]# yum -y install java

[root@kafka1 ~]# tar zxvf apache-zookeeper-3.6.0-bin.tar.gz

[root@kafka1 ~]# mv apache-zookeeper-3.6.0-bin /etc/zookeeper

(2)创建数据保存目录(三个节点的配置相同)

[root@kafka1 ~]# cd /etc/zookeeper/

[root@kafka1 zookeeper]# mkdir zookeeper-data

(3)修改配置文件(三个节点的配置相同)

[root@kafka1 zookeeper]# cd /etc/zookeeper/conf

[root@kafka1 ~]# mv zoo_sample.cfg zoo.cfg

[root@kafka1 ~]# vim zoo.cfg

dataDir=/etc/zookeeper/zookeeper-data

clientPort=2181

server.1=192.168.10.114:2888:3888

server.2=192.168.10.115:2888:3888

server.3=192.168.10.116:2888:3888

注释:zookeeper只用的端口

2181:对cline端提供服务

3888:选举leader使用

2888:集群内机器通讯使用(Leader监听此端口)

(4)创建节点id文件(按server编号设置这个id,三个机器不同)

节点1:

[root@kafka1 conf]# echo '1' > /etc/zookeeper/zookeeper-data/myid

节点2:

[root@kafka2 conf]# echo '2' > /etc/zookeeper/zookeeper-data/myid

节点3:

[root@kafka3 conf]# echo '3' > /etc/zookeeper/zookeeper-data/myid

(5)三个节点启动zookeeper进程

[root@kafka1 conf]# cd /etc/zookeeper/

[root@kafka1 zookeeper]# ./bin/zkServer.sh start

[root@kafka1 zookeeper]# ./bin/zkServer.sh status

2:kafka的部署

(1)kafka的安装(三个节点的配置相同)

[root@kafka1 ~]# tar zxvf kafka_2.13-2.4.1.tgz

[root@kafka1 ~]# mv kafka_2.13-2.4.1 /etc/kafka

(2)修改配置文件

[root@kafka1 ~]# cd /etc/kafka/

[root@kafka2 kafka]# vim config/server.properties

broker.id=1 ##21行  修改,注意其他两个的id分别是2和3

listeners=PLAINTEXT://192.168.10.114:9092 #31行  修改,其他节点改成各自的IP地址

log.dirs=/etc/kafka/kafka-logs ## 60行  修改

num.partitions=1 ##65行 分片数量,不能超过节点数

zookeeper.connect=192.168.10.114:2181,192.168.10.115:2181,192.168.10.116:2181

注释:

9092是kafka的监听端口

(3)创建日志目录(三个节点的配置相同)

[root@kafka1 kafka]# mkdir /etc/kafka/kafka-logs

(3)在所有kafka节点上执行开启命令,生成kafka群集(三个节点的配置相同)

[root@kafka1 kafka]# ./bin/kafka-server-start.sh config/server.properties &

如果启动不了,可以将/etc/kafka/kafka-logs中的数据清除再试试

3:测试

创建topic(任意一个节点)

bin/kafka-topics.sh --create --zookeeper kafka1:2181 --replication-factor 1 --partitions 1 --topic test

列出topic(任意一个节点)

bin/kafka-topics.sh --list --zookeeper kafka1:2181

bin/kafka-topics.sh --list --zookeeper kafka2:2181

bin/kafka-topics.sh --list --zookeeper kafka3:2181

生产消息

bin/kafka-console-producer.sh --broker-list kafka1:9092 -topic test

消费消息

bin/kafka-console-consumer.sh --bootstrap-server kafka1:9092 --topic test

删除topic

bin/kafka-topics.sh --delete --zookeeper kafka1:2181 --topic test

扩展:将远程的logstash输出到kafka中

[root@logstash1 logstash]# vim conf.d/beats.conf

input {

  beats {

    port => "5044"

    codec => "json"

 }

}

output {

   kafka {

    bootstrap_servers => "192.168.10.114:9092,192.168.10.115:9092,192.168.10.116:9092"

    topic_id => "httpd-filebeat"

    batch_size => "5"

    codec => "json"

   }

}

在logstash中运行配置

[root@logstash1 logstash]# logstash -f /etc/logstash/conf.d/beats.conf

生产消息(任意一个节点)

bin/kafka-console-producer.sh --broker-list kafka1:9092 -topic test

消费消息(任意一个节点)

bin/kafka-console-consumer.sh --bootstrap-server kafka2:9092 --topic test

删除topic(任意一个节点)

bin/kafka-topics.sh --delete --zookeeper kafka1:2181 --topic test

重启kafka

/etc/kafka/bin/kafka-server-stop.sh

/etc/zookeeper/bin/zkServer.sh restart

/etc/kafka/bin/kafka-server-start.sh config/server.properties &

问题解决

错误提示:

 Failed to acquire lock on file .lock in /tmp/kafka-logs. A Kafka instance in another process or thread is using this directory.

解决方法:

[root@kafka1 kafka]# rm -rf /tmp/kafka-logs/*

[root@kafka1 kafka]# netstat -lnp|grep 9092

pkill杀死kafka的进程号

[root@kafka2 kafka]# ./bin/kafka-server-start.sh config/server.properties &

  • 10
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值