kafka原理与起步使用 (+zookeeper)

kafka原理与起步使用 (+zookeeper)

https://www.jianshu.com/p/d3e963ff8b70
https://blog.csdn.net/java_66666/article/details/81015302
http://kafka.apachecn.org/quickstart.html

https://blog.csdn.net/liyiming2017/article/details/83035157

https://www.cnblogs.com/ultranms/p/9585191.html

kafka原理

Kafka是一个分布式流处理平台,是一种高吞吐量的分布式发布订阅消息系统。
它适合两大类别的应用:
1.构造实时流数据管道,它可以在系统或应用之间可靠地获取数据。 (相当于message queue)
2.构建实时流式应用程序,对这些流数据进行转换或者影响。 (就是流处理,通过kafka stream topic和topic之间内部进行变化)

kafka原理与起步使用 (+zookeeper)_第1张图片

kafka的特性及背后的方法支持

为了理解Kafka是如何做到以上所说的功能,从下面开始,我们将深入探索Kafka的特性。
首先是一些概念:
1.Kafka作为一个集群,运行在一台或者多台服务器上.
2.Kafka 通过 topic 对存储的流数据进行分类。
3.每条记录中包含一个key,一个value和一个timestamp(时间戳)。
Kafka有四个核心的API:
1.The Producer API 允许一个应用程序发布一串流式的数据到一个或者多个Kafka topic。
2.The Consumer API 允许一个应用程序订阅一个或多个 topic ,并且对发布给他们的流式数据进行处理。
3.The Streams API 允许一个应用程序作为一个流处理器,消费一个或者多个topic产生的输入流,然后生产一个输出流到一个或多个topic中去,在输入输出流中进行有效的转换。
4.The Connector API 允许构建并运行可重用的生产者或者消费者,将Kafka topics连接到已存在的应用程序或者数据系统。比如,连接到一个关系型数据库,捕捉表(table)的所有变更内容。

Topics和日志

让我们首先深入了解下Kafka的核心概念:提供一串流式的记录— topic 。

Topic 就是数据主题,是数据记录发布的地方,可以用来区分业务系统。Kafka中的Topics总是多订阅者模式,一个topic可以拥有一个或者多个消费者来订阅它的数据。

对于每一个topic, Kafka集群都会维持一个分区日志,如下所示:
kafka原理与起步使用 (+zookeeper)_第2张图片
每个分区都是有序且顺序不可变的记录集,并且不断地追加到结构化的commit log文件。分区中的每一个记录都会分配一个id号来表示顺序,我们称之为offset,offset用来唯一的标识分区中每一条记录。

Kafka 集群保留所有发布的记录—无论他们是否已被消费—并通过一个可配置的参数——保留期限来控制. 举个例子, 如果保留策略设置为2天,一条记录发布后两天内,可以随时被消费,两天过后这条记录会被抛弃并释放磁盘空间。Kafka的性能和数据大小无关,所以长时间存储数据没有什么问题.
kafka原理与起步使用 (+zookeeper)_第3张图片
事实上,在每一个消费者中唯一保存的元数据是offset(偏移量)即消费在log中的位置.偏移量由消费者所控制:通常在读取记录后,消费者会以线性的方式增加偏移量,但是实际上,由于这个位置由消费者控制,所以消费者可以采用任何顺序来消费记录。例如,一个消费者可以重置到一个旧的偏移量,从而重新处理过去的数据;也可以跳过最近的记录,从"现在"开始消费。

这些细节说明Kafka 消费者是非常廉价的—消费者的增加和减少,对集群或者其他消费者没有多大的影响。比如,你可以使用命令行工具,对一些topic内容执行 tail操作,并不会影响已存在的消费者消费数据。

日志中的 partition(分区)有以下几个用途。第一,当日志大小超过了单台服务器的限制,允许日志进行扩展。每个单独的分区都必须受限于主机的文件限制,不过一个主题可能有多个分区,因此可以处理无限量的数据。第二,可以作为并行的单元集—关于这一点,更多细节如下

分布式

日志的分区partition (分布)在Kafka集群的服务器上。每个服务器在处理数据和请求时,共享这些分区。每一个分区都会在已配置的服务器上进行备份,确保容错性.

**每个分区都有一台 server 作为 “leader”,零台或者多台server作为 follwers 。leader server 处理一切对 partition (分区)的读写请求,而follwers只需被动的同步leader上的数据。**当leader宕机了,followers 中的一台服务器会自动成为新的 leader。每台 server 都会成为某些分区的 leader 和某些分区的 follower,因此集群的负载是平衡的。

生产者

生产者可以将数据发布到所选择的topic(主题)中。生产者负责将记录分配到topic的哪一个 partition(分区)中。可以使用循环的方式来简单地实现负载均衡,也可以根据某些语义分区函数(例如:记录中的key)来完成。下面会介绍更多关于分区的使用。

消费者

消费者使用一个 消费组 名称来进行标识,发布到topic中的每条记录被分配给订阅消费组中的一个消费者实例.消费者实例可以分布在多个进程中或者多个机器上。

如果所有的消费者实例在同一消费组中,消息记录会负载平衡到每一个消费者实例.

如果所有的消费者实例在不同的消费组中,每条消息记录会广播到所有的消费者进程.
kafka原理与起步使用 (+zookeeper)_第4张图片
如图,这个 Kafka 集群有两台 server 的,四个分区(p0-p3)和两个消费者组。消费组A有两个消费者,消费组B有四个消费者。

通常情况下,每个 topic 都会有一些消费组,一个消费组对应一个"逻辑订阅者"。一个消费组由许多消费者实例组成,便于扩展和容错。这就是发布和订阅的概念,只不过订阅者是一组消费者而不是单个的进程。

在Kafka中实现消费的方式是将日志中的分区划分到每一个消费者实例上,以便在任何时间,每个实例都是分区唯一的消费者。维护消费组中的消费关系由Kafka协议动态处理。如果新的实例加入组,他们将从组中其他成员处接管一些 partition 分区;如果一个实例消失,拥有的分区将被分发到剩余的实例。这张图实际上就是描述了这个消费关系的整理,通过这个机制我们可以想见,如果我们想要一个应用的进程来对数据进行处理那么我们只需要在一个只有一个消费者(我们的进程)的消费组里面订阅对应的topic,上面P1-4分区就会全部进入那个消费者组中的那个消费者,也就是说所有的数据都会进入同一个消费者进行处理,而我们的应用也是一个分布式的系统,那么就可以通过这种匹配方式,各自负责 一部分的分区。下面这张图很好的说明了它的工作机制。
kafka原理与起步使用 (+zookeeper)_第5张图片

大概用法就是,Producers往Brokers里面的指定Topic中写消息,Consumers从Brokers里面拉去指定Topic的消息,然后进行业务处理。
图中有两个topic,topic 0有两个partition,topic 1有一个partition,三副本备份。只有一个Broker实际上在进行对某个分区的读写操作称为leader,其他Broker只是在同步这个数据称为follower。当leader节点挂掉就选举一个follower当这个分区的leader。然后以消费组为单位向topic进行订阅,每个消费组获得订阅topic的所有数据,自动平衡负载到里面的消费者节点。某个topic的某个分区只能发送到对应消费组一个消费者节点上。以便在任何时间,每个实例都是分区唯一的消费者。

Kafka 只保证分区内的记录是有序的,而不保证主题中不同分区的顺序。每个 partition 分区按照key值排序足以满足大多数应用程序的需求。但如果你需要总记录在所有记录的上面,可使用仅有一个分区的主题来实现,这意味着每个消费者组只有一个消费者进程。

生产流程

kafka原理与起步使用 (+zookeeper)_第6张图片创建一条记录,记录中一个要指定对应的topic和value,key和partition可选。 先序列化,然后按照topic和partition,放进对应的发送队列中。kafka produce都是批量请求,会积攒一批,然后一起发送,不是调send()就进行立刻进行网络发包。
如果partition没填,那么情况会是这样的:

1.key有填
按照key进行哈希,相同key去一个partition。(如果扩展了partition的数量那么就不能保证了)
2.key没填
round-robin来选partition
这些要发往同一个partition的请求按照配置,攒一波,然后由一个单独的线程一次性发过去。

保证

high-level Kafka给予以下保证:

1.生产者发送到特定topic partition 的消息将按照发送的顺序处理。 也就是说,如果记录M1和记录M2由相同的生产者发送,并先发送M1记录,那么M1的偏移比M2小,并在日志中较早出现
2.一个消费者实例按照日志中的顺序查看记录.
3.对于具有N个副本的主题,我们最多容忍N-1个服务器故障,从而保证不会丢失任何提交到日志中的记录.

kafka作为消息系统

Kafka streams的概念与传统的企业消息系统相比如何?

传统的消息系统有两个模块: 队列 和 发布-订阅。 在队列中,消费者池从server读取数据,每条记录被池子中的一个消费者消费; 在发布订阅中,记录被广播到所有的消费者。两者均有优缺点。 队列的优点在于它允许你将处理数据的过程分给多个消费者实例,使你可以扩展处理过程。 不好的是,队列不是多订阅者模式的—一旦一个进程读取了数据,数据就会被丢弃。 而发布-订阅系统允许你广播数据到多个进程,但是无法进行扩展处理,因为每条消息都会发送给所有的订阅者。

消费组在Kafka有两层概念。在队列中,消费组允许你将处理过程分发给一系列进程(消费组中的成员)。 在发布订阅中,Kafka允许你将消息广播给多个消费组。

Kafka的优势在于每个topic都有以下特性—可以扩展处理并且允许多订阅者模式—不需要只选择其中一个.

Kafka相比于传统消息队列还具有更严格的顺序保证

传统队列在服务器上保存有序的记录,如果多个消费者消费队列中的数据, 服务器将按照存储顺序输出记录。 虽然服务器按顺序输出记录,但是记录被异步传递给消费者, 因此记录可能会无序的到达不同的消费者。这意味着在并行消耗的情况下, 记录的顺序是丢失的。因此消息系统通常使用“唯一消费者”的概念,即只让一个进程从队列中消费, 但这就意味着不能够并行地处理数据。

Kafka 设计的更好。topic中的partition是一个并行的概念。 Kafka能够为一个消费者池提供顺序保证和负载平衡,是通过将topic中的partition分配给消费者组中的消费者来实现的, 以便每个分区由消费组中的一个消费者消耗。通过这样,我们能够确保消费者是该分区的唯一读者,并按顺序消费数据。 众多分区保证了多个消费者实例间的负载均衡。但请注意,消费者组中的消费者实例个数不能超过分区的数量。

kafka作为存储系统

许多消息队列可以发布消息,除了消费消息之外还可以充当中间数据的存储系统。那么Kafka作为一个优秀的存储系统有什么不同呢?

数据写入Kafka后被写到磁盘,并且进行备份以便容错。直到完全备份,Kafka才让生产者认为完成写入,即使写入失败Kafka也会确保继续写入

Kafka使用磁盘结构,具有很好的扩展性—50kb和50TB的数据在server上表现一致。

可以存储大量数据,并且可通过客户端控制它读取数据的位置,您可认为Kafka是一种高性能、低延迟、具备日志存储、备份和传播功能的分布式文件系统。

关于Kafka提交日志存储和备份设计的更多细节,可以阅读 这页 。

kafka做流处理

Kafka 流处理不仅仅用来读写和存储流式数据,它最终的目的是为了能够进行实时的流处理。

在Kafka中,流处理器不断地从输入的topic获取流数据,处理数据后,再不断生产流数据到输出的topic中去。

例如,零售应用程序可能会接收销售和出货的输入流,经过价格调整计算后,再输出一串流式数据。

简单的数据处理可以直接用生产者和消费者的API。对于复杂的数据变换,Kafka提供了Streams API。 Stream API 允许应用做一些复杂的处理,比如将流数据聚合或者join。

这一功能有助于解决以下这种应用程序所面临的问题:处理无序数据,当消费端代码变更后重新处理输入,执行有状态计算等。

Streams API建立在Kafka的核心之上:它使用Producer和Consumer API作为输入,使用Kafka进行有状态的存储, 并在流处理器实例之间使用相同的消费组机制来实现容错。

zookeeper

当完成了上面内容的学习,准备kafka起步,以为和Flink一样就是直接下载安装包解压运行就可以看到kafka实例,结果在文档起步部分第一句话是:Kafka 使用 ZooKeeper 如果你还没有ZooKeeper服务器,你需要先启动一个ZooKeeper服务器。
那么zookeeper又是什么呢?

ZooKeeper是用于分布式应用程序的高性能协调服务。它在一个简单的界面中公开了常见的服务,例如命名,配置管理,同步和组服务,因此不必从头开始编写它们。用户可以现成使用它来实现共识,组管理,领导者选举和状态协议。用户可以根据自己的特定需求在此基础上构建。

最常见的用法有:

1.配置管理2.名字服务3.分布式锁4.集群管理。

Znode

也就是说它是用来帮忙管理集群的工具,先说它的结构,它维护一个这样的类似文件系统的数据结构。:

img

每个子目录项 都被称作为 znode(目录节点),和文件系统一样,我们能够自由的增加、删除znode,在一个znode下增加、删除子znode,唯一的不同在于znode是可以存储数据的。

根节点/包含4个子节点,其中三个拥有下一级节点。有的叶子节点存储了信息。

节点上没有存储数据,也有着重要的含义。比如在主从模式中,当/master节点没有数据时,代表分布式应用的主节点还没有选举出来。

znode节点存储的数据为字节数组。存储数据的格式zookeeper不做限制,也不提供解析,需要应用自己实现。

实际上图就是主从模式存储数据的示例,这里先简单讲解:

/master,存储了当前主节点的信息
/workers,下面的每个子znode代表一个从节点,子znode上存储的数据,如“foo.com:2181”,代表从节点的信息。
/tasks,下面的每个子znode代表一个任务,子znode上存储的信息如“run cmd”,代表该内务内容
/assign,下面每个子znode代表一个从节点的任务集合。如/assign/worker-1,代表worker-1这个从节点的任务集合。/assign/worker-1下的每个子znode代表分配给worker-1的一个任务。

持久节点(persistent)和临时节点(ephemeral)

持久节点只能通过delete删除。临时节点在创建该节点的客户端崩溃或关闭时,自动被删除。

前面例子中的/master应该使用临时节点,这样当主节点失效或者退出时,该znode被删除,其他节点知道主节点崩溃了,开始进行选举的逻辑。另外/works/worker-1也应该是临时节点,在此从节点失效的时候,该临时节点自动删除。

在目前的版本,由于临时znode会因为创建者会话过期被删除,所以不允许临时节点拥有子节点。

有序节点

znode可以被设置为有序(sequential)节点。有序znode节点被分配唯一一个单调递增的证书。如果创建了个一有序节点为/workers/worker-,zookeeper会自动分配一个序号1,追加在名字后面,znode名称为/workers/worker-1。通过这种方式,可以创建唯一名称znode,并且可以直观的看到创建的顺序。

znode支持的操作及暴露的API

create /path data

创建一个名为/path的znode,数据为data。

delete /path

删除名为/path的znode。

exists /path

检查是否存在名为/path的znode

setData /path data

设置名为/path的znode的数据为data

getData /path

返回名为/path的znode的数据

getChildren /path

返回所有/path节点的所有子节点列表

观察与通知

分布式应用需要及时知道zookeeper中znode的变化,从而了解到分布式应用整体的状况,如果采用轮询方式,代价太大,绝大多数查询都是无效的。因此,zookeeper采用了通知的机制。客户端向zookeeper请求,在特定的znode设置观察点(watch)。当该znode发生变化时,会触发zookeeper的通知,客户端收到通知后进行业务处理。观察点触发后立即失效。所以一旦观察点触发,需要再次设置新的观察点。

img

假设我们的程序是分布式部署在多台机器上,如果我们要改变程序的配置文件,需要逐台机器去修改,非常麻烦,现在把这些配置全部放到zookeeper上去,保存在 zookeeper 的某个目录节点中,然后所有相关应用程序对这个目录节点进行监听,一旦配置信息发生变化,每个应用程序就会收到 zookeeper 的通知,然后从 zookeeper 获取新的配置信息应用到系统中。zookeeper可以定义不同的观察类型。例如观察znode数据变化,观察znode子节点变化,观察znode创建或者删除。Zookeeper只能保证最终的一致性,而无法保证强一致性。

版本

每个znode都有版本号,随着每次数据变化自增。setData和delete,以版本号作为参数,当传入的版本号和服务器上不一致时,调用失败。当多个zookeeper客户端同时对一个znode操作时,版本将会起到作用,假设c1,c2同时往一个znode写数据,c1先写完后版本从1升为2,但是c2写的时候携带版本号1,c2会写入失败。

法定人数

zookeeper服务器运行于两种模式:独立模式和仲裁模式(集群)。仲裁模式下,会复制所有服务器的数据树。但如果让客户端等待所有复制完成,延迟太高。这里引入法定人数概念,指为了使zookeeper集群正常工作,必须有效运行的服务器数量。同时也是服务器通知客户端保存成功前,必须保存数据的服务器最小数。例如我们有一个5台服务器的zookeeper集群,法定人数为3,只要任何3个服务器保存了数据,客户端就会收到确认。只要有3台服务器存活,整个zookeeper集群就是可用的。

下图展示了客户端提交请求到收到回复的过程:

img

法定人数需要大于服务器数量的一半。也称为多数原则。举个例子说明,假如集群有5台服务器,法定人数为2,那么有2台服务器参与复制即可,若这2台server刚刚复制完/z这个znode,就挂掉了。此时剩下了3台server,大于法定人数2,所以zookeeper认为集群正常,但这三台服务器是无法发现/z这个znode的。如果法定人数大于服务器数量一半,那么法定人数复制完成,就可以确保集群存活时,至少有一台服务器有最新的znode,否则集群认为自己已经崩溃。

Zookeeper配置

(参考: [java_66666]: https://blog.csdn.net/java_66666/article/details/81015302 “Zookeeper入门看这篇就够了”)

由于手上只有一个阿里云主机,那么就在这个阿里云主机上模拟一个集群的搭建。本例搭建的是伪集群模式,即一台机器上启动三个zookeeper实例组成集群,真正的集群模式无非就是实例IP地址不同,搭建方法没有区别

首先是JDK的安装,建议安装JDK8。这里对java环境的安装不做更多说明。 检验环境:java -version。
接下来是安装zookeeper,随便找一个zookeeper的安装包通过xftp发送到对应的文件夹中。

也可以用下面这种方式直接使用wget获得安装包但是地址有可能发生了变化。


# cd /usr/local
# wget http://mirror.bit.edu.cn/apache/zookeeper/stable/zookeeper-3.4.12.tar.gz
# tar -zxvf zookeeper-3.4.12.tar.gz
# cd zookeeper-3.4.12

复制conf文件夹中的zoo_sample.cfg文件:

# cp conf/zoo_sample.cfg conf/zoo-1.cfg

修改配置文件zoo-1.cfg,原配置文件里有的,修改成下面的值,没有的则加上


# vim conf/zoo-1.cfg
dataDir=/tmp/zookeeper-1
clientPort=2181
server.1=127.0.0.1:2888:3888
server.2=127.0.0.1:2889:3889
server.3=127.0.0.1:2890:3890

配置说明:

  • tickTime:这个时间是作为 Zookeeper 服务器之间或客户端与服务器之间维持心跳的时间间隔,也就是每个 tickTime 时间就会发送一个心跳。
  • initLimit:这个配置项是用来配置 Zookeeper 接受客户端(这里所说的客户端不是用户连接 Zookeeper 服务器的客户端,而是 Zookeeper 服务器集群中连接到 Leader 的 Follower 服务器)初始化连接时最长能忍受多少个心跳时间间隔数。当已经超过 10个心跳的时间(也就是 tickTime)长度后 Zookeeper 服务器还没有收到客户端的返回信息,那么表明这个客户端连接失败。总的时间长度就是 10*2000=20 秒
  • syncLimit:这个配置项标识 Leader 与 Follower 之间发送消息,请求和应答时间长度,最长不能超过多少个 tickTime 的时间长度,总的时间长度就是 5*2000=10秒
  • dataDir:顾名思义就是 Zookeeper 保存数据的目录,默认情况下,Zookeeper 将写数据的日志文件也保存在这个目录里。
  • clientPort:这个端口就是客户端连接 Zookeeper 服务器的端口,Zookeeper 会监听这个端口,接受客户端的访问请求。
  • server.A=B:C:D:其中 A 是一个数字,表示这个是第几号服务器;B 是这个服务器的 ip 地址;C 表示的是这个服务器与集群中的 Leader 服务器交换信息的端口;D 表示的是万一集群中的 Leader 服务器挂了,需要一个端口来重新进行选举,选出一个新的 Leader,而这个端口就是用来执行选举时服务器相互通信的端口。如果是伪集群的配置方式,由于 B 都是一样,所以不同的 Zookeeper 实例通信端口号不能一样,所以要给它们分配不同的端口号。

再从zoo-1.cfg复制两个配置文件zoo-2.cfg和zoo-3.cfg,只需修改dataDir和clientPort(2181 2182 2183 )不同即可,然后修改id:

# mkdir /tmp/zookeeper-1
# mkdir /tmp/zookeeper-2
# mkdir /tmp/zookeeper-3
# cd /tmp/zookeeper-1
# vim myid
1
# cd /tmp/zookeeper-2
# vim myid
2
# cd /tmp/zookeeper-3
# vim myid

启动三个zookeeper实例

# bin/zkServer.sh start conf/zoo-1.cfg
# bin/zkServer.sh start conf/zoo-2.cfg
# bin/zkServer.sh start conf/zoo-3.cfg

检测集群状态,也可以直接用命令“zkCli.sh -server IP:PORT”连接zookeeper服务端检测

# bin/zkCli.sh

或者

# bin/zkServer.sh status conf/zoo-1.cfg
# bin/zkServer.sh status conf/zoo-2.cfg
# bin/zkServer.sh status conf/zoo-3.cfg

kafka原理与起步使用 (+zookeeper)_第7张图片

可以使用以下代码来对zookeeper的使用进行认识:

通过ls检查文件目录,接下来通过create 创建一个名为zkPro的节点,节点内容是 myData然后通过get命令去获取该节点内容。然后可以通过set命令改变值。delete命令删除节点。这里包含了zookeeper的一个基本的使用方式。s

[zk: localhost:2181(CONNECTED) 5] ls /
[zookeeper]
[zk: localhost:2181(CONNECTED) 6] create /zkPro myData 
Created /zkPro
[zk: localhost:2181(CONNECTED) 7] ls /
[zookeeper, zkPro]
[zk: localhost:2181(CONNECTED) 8] get /zkPro
myData
cZxid = 0x100000002
ctime = Thu May 21 12:30:52 CST 2020
mZxid = 0x100000002
mtime = Thu May 21 12:30:52 CST 2020
pZxid = 0x100000002
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 6
numChildren = 0
[zk: localhost:2181(CONNECTED) 9] set /zkPro myData123
cZxid = 0x100000002
ctime = Thu May 21 12:30:52 CST 2020
mZxid = 0x100000003
mtime = Thu May 21 12:31:52 CST 2020
pZxid = 0x100000002
cversion = 0
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 9
numChildren = 0
[zk: localhost:2181(CONNECTED) 10] delete /zkPro
[zk: localhost:2181(CONNECTED) 11] ls /
[zookeeper]
[zk: localhost:2181(CONNECTED) 12] 

kafka配置

如上解压到对应目录,然后打开环境变量文件,配置环境变量。

#set kafka environment
export KAFKA_HOME=/usr/local/kafka
PATH=${KAFKA_HOME}/bin:$PATH

保存文件后让环境变量生效:

source /etc/profile

如果是单机模式那么我们进入/usr/local/App/kafka_2.11-2.0.0下的config文件夹里 修改 server.properties中的zookeeper.connect。这里有两种方法,一种是改成我们上面配置好了的zookeeper节点和端口比如:

kafka原理与起步使用 (+zookeeper)_第8张图片

zookeeper.connect=localhost:2181

另一种是使用自带的zookeeper,可以在config文件夹里面看到一个叫做zookeeper.properities的文件这就是自带的zookeeper的配置文件我们可以做上面zookeeper配置过程中同样的处理,就不用另外配置zookeeper集群了。这里由于我们配置好了。像上面一样修改为对应ip:端口即可。

如果是集群模式那么在每一个主机中的配置中vim /usr/local/kafka/config/server.properties,修改配置如下(IP地址应该根据实际情况填写)

broker.id=1
listeners=PLAINTEXT://192.168.1.42:9092
zookeeper.connect=192.168.1.41:2181,192.168.1.42:2181,192.168.1.47:2181
broker.id=2
listeners=PLAINTEXT://192.168.1.41:9092
zookeeper.connect=192.168.1.41:2181,192.168.1.42:2181,192.168.1.47:2181
broker.id=3
listeners=PLAINTEXT://192.168.1.47:9092
zookeeper.connect=192.168.1.41:2181,192.168.1.42:2181,192.168.1.47:2181

启动kafka(要确保zookeeper已启动)

在每台主机上分别启动kafka:

/usr/local/kafka/bin/kafka-server-start.sh -daemon config/server.properties 

kafka相关命令

开启kafka自带zookeeper:

前台运行:

bin/zookeeper-server-start.sh config/zookeeper.properties

后台运行:

nohup bin/zookeeper-server-start.sh config/zookeeper.properties > zookeeper-run.log 2>&1 &

(关于后台启动命令,可看我的另一篇博客:《Linux后台运行进程》)

 

开启kafka:

前台运行:

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

后台运行:

nohup bin/kafka-server-start.sh config/server.properties > kafka-run.log 2>&1 &

 

创建kafka主题:

bin/kafka-topics.sh --create --zookeeper 10.45.xx.xx:2191 --replication-factor 1 --partitions 1 --topic test

 

显示kafka所有主题:

bin/kafka-topics.sh -list -zookeeper 10.45.xx.xx:2191

 

创建kafka生产者:

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

 

创建kafka消费者:

bin/kafka-console-consumer.sh --zookeeper 10.45.xx.xx:2191 --topic test --from-beginning

上面是老版本的使用方式 在最新版本的kafka中取消了这个命令使用以下命令:

bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic test --from-beginning
 

解释:

--zookeeper:后面接的是你配置的zookeeper地址

--broker-list:默认端口为9092.可自行更改

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hdStWIUt-1590045568216)(C:\Users\z\AppData\Roaming\Typora\typora-user-images\image-20200521145322693.png)]

https://www.cnblogs.com/qpf1/p/9161742.html

通过上面这个截图里面的信息,我们可以发现zookeeper和kafka联系之紧密。实际上zookeeper对kafka的作用主要是管理broker,consumer。创建Broker后,向zookeeper注册新的broker信息,实现在服务器正常运行下的水平拓展。具体的,通过注册watcher,获取partition的信息。

Topic的注册,zookeeper会维护topic与broker的关系,通/brokers/topics/topic.name节点来记录。

Producer向zookeeper中注册watcher,了解topic的partition的消息,以动态了解运行情况,实现负载均衡。Zookeepr不管理producer,只是能够提供当前broker的相关信息。

Consumer可以使用group形式消费kafka中的数据。所有的group将以轮询的方式消费broker中的数据,具体的按照启动的顺序。Zookeeper会给每个consumer group一个ID,即同一份数据可以被不同的用户ID多次消费。因此这就是单播与多播的实现。以单个消费者还是以组别的方式去消费数据,由用户自己去定义。Zookeeper管理consumer的offset跟踪当前消费的offset。

记得本文开始配置zookeeper时候,我们查看了zookeeper的节点,并且进行了新增和删除的操作,当我们新建了kafka的topic后再去查看zookeeper的节点我们发现多了kafka的内容并且可以找到对应的topic:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-S9iPHKC3-1590045568217)(C:\Users\z\AppData\Roaming\Typora\typora-user-images\image-20200521151028244.png)]
在这里插入图片描述

你可能感兴趣的:(学习记录,zookeeper,kafka,flink)