继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

kafka-02-Kafka安装运行

黑桃SEVEN_PIG
关注TA
已关注
手记 46
粉丝 11
获赞 8

1、安装Java 7或以上版本

省略…

2、安装 Zookeeper

Kafka 使用 Zookeeper 保存 集群的元数据信息消费者信息
可以到 apache 官网下载zookeeper:https://zookeeper.apache.org/releases.html

2.1 单机服务

安装zookeeper

[root@docker01 ~]#cd /usr/local/
bin  etc  games  include  lib  lib64  libexec  sbin  share  src
[root@docker01 local]# ls
bin  etc  games  include  lib  lib64  libexec  sbin  share  src apache-zookeeper-3.6.1-bin.tar.gz
[root@docker01 local]# tar -zxvf apache-zookeeper-3.6.1-bin.tar.gz 
[root@docker01 local]# mv apache-zookeeper-3.6.1-bin zookeeper-3.6.1
[root@docker01 local]# ls
bin  etc  games  include  lib  lib64  libexec  sbin  share  src apache-zookeeper-3.6.1-bin.tar.gz  zookeeper-3.6.1
[root@docker01 local]# cd zookeeper-3.6.1/conf/
[root@docker01 conf]# ls
configuration.xsl  log4j.properties  zoo_sample.cfg
# zookeeper 需要一个名为 zoo.cfg 配置文件,
# 我们可以复制默认配置文件zoo_sample.cfg并命名为 zoo.cfg
[root@docker01 conf]# cp zoo_sample.cfg zoo.cfg
[root@docker01 conf]# mkdir -p /var/lib/zookeeper
[root@docker01 conf]# vim zoo.cfg 
tickTime=2000
initLimit=10
syncLimit=5
#修改zookeeper的数据目录为 /var/lib/zookeeper
dataDir=/var/lib/zookeeper 
clientPort=2181

并启动 zookeeper

# linux 下通过 zkServer.sh start 启动
[root@docker01 conf]# /usr/local/zookeeper-3.6.1/bin/zkServer.sh start
ZooKeeper JMX enabled by default
Using config: /usr/local/zookeeper-3.6.1/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED
# 启动成功,通过 netstat 命令查看 zookeeper的 2181 端口是否启用
[root@docker01 conf]# netstat -nultp | grep 2181
tcp6       0      0 :::2181                 :::*                    LISTEN      14749/java          
[root@docker01 conf]# 

2.2 Zookeeper 群组

Zookeeper 集群被称为群组。 Zookeeper 使用的是一致性协议,所以建议每个群组里应该包含奇数个节点(比如 3 个、 5 个等),因为只有当群组里的大多数节点(也就是法定人数 )处于可用状态,Zookeeper 才能处理外部的请求。也就是说,如果你有一个包含 3 个节点的群组,那么它允许一个节点失效。如果群组包含 5 个节点,那么它允许 2 个节点失效。

群组需要有一些公共配置,下面列出了所有服务器的清单,并且每个服务器还要在数据目录(下面配置的是/var/lib/zookeeper)中创建一 个 myid 文件,用于指明自己的 ID 。如果群组里服务器的机器名是 zoo1.example.com 、 zoo2.example.com 、 zoo3.example.com ,那么配置文件可能是这样的:

tickTime=2000
initLimit=10
syncLimit=5
#修改zookeeper的数据目录为 /var/lib/zookeeper
dataDir=/var/lib/zookeeper 
clientPort=2181
server.1=zoo1.example.com:2888:3888 
server.2=zoo2.example.com:2888:3888 
server.3=zoo3.example.com:2888:3888 

在这个配置中,
initLimit 表示用于在从节点与主节点之间建立初始化连接的时间上限,
syncLimit 表示允许从节点与主节点处于不同步状态的时间上限。

这两个值都是 tickTime 的倍数,所以 initLimit 是 10*2000ms ,也就是 20s 。
配置里还列出了群组中所有服务器的地址。
服务器地址遵循 server.X=hostname:peerPort:leaderPort 格式,
各个参数说明如下:

  • X
    服务器的 ID ,它必须是一个整数,不过不一定要从 0 开始,也不要求是连续的;
  • hostname
    服务器的机器名或 IP 地址:
  • peerPort
    用于节点间通信的 TCP 端口;
  • leader Port
    用于首领选举的 TCP 端口。

客户端只需要通过 clientPort 就能连接到群组,而群组节点间的通信则需要同时用到这 3 个端口( peerPort 、 leaderPort 、 clientPort )。
除了公共的配置文件外,每个服务器都必须在 data Dir 数据目录中创建一个叫作 myid 的文件,文件里要包含服务器 ID , 这个 ID 要与配置文件里配置的 ID 保持一致。完成这些步骤后,就可以启动服务器,让它们彼此间进行通信了。

3 安装Kafka Broker

配置好 Java Zookeeper 之后 ,接下来就可以安装 Kafka 了。可以从 http://kafka.apache.org/downloads.html 下载最新版本的 Kafka 。

下面的例子将 Kafka 安装在 /usr/local/kafka 目录下,使用之前配置好的 Zookeeper ,并把消息日志保存在 /tmp/kafka-log 目录下。

解压完kafka的安装包后,config/server.properties 是Kafka Broker 的配置文件,默认的日志存放目录是 /tmp/kafka-logs

安装kafka:

[root@docker01 ~]# cd /usr/local/
[root@docker01 local]# ls
bin  etc  games  include  kafka_2.13-2.6.0.tgz  lib  lib64  libexec  sbin  share  src  zookeeper-3.6.1
[root@docker01 local]# tar -zxvf kafka_2.13-2.6.0.tgz 
[root@docker01 local]# ls
bin  etc  games  include  kafka_2.13-2.6.0  kafka_2.13-2.6.0.tgz  lib  lib64  libexec  sbin  share  src  zookeeper-3.6.1
# 启动kafka服务
[root@docker01 local]# kafka_2.13-2.6.0/bin/kafka-server-start.sh -daemon kafka_2.13-2.6.0/config/server.properties 
# 检查Kafka的默认端口 9092 是否启动
[root@docker01 local]# netstat -nultp | grep 9092
tcp6       0      0 :::9092                 :::*                    LISTEN      21538/java          
[root@docker01 local]# 

一旦 Kafka 创建完毕,就可以对这个集群做一些简单的操作来验证它是否安装正确,比如
创建 个测试主题,发布一些消息 ,然后读取它们。

创建并验证主题:

# 创建主题 test
[root@docker01 local]# /usr/local/kafka_2.13-2.6.0/bin/kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic test
Created topic test.
# 验证主题(查看刚刚创建的test主题的描述)
[root@docker01 local]# /usr/local/kafka_2.13-2.6.0/bin/kafka-topics.sh --zookeeper localhost:2181 --describe --topic test
Topic: test	PartitionCount: 1	ReplicationFactor: 1	Configs: 
	Topic: test	Partition: 0	Leader: 0	Replicas: 0	Isr: 0
[root@docker01 local]# 

往测试主题上发布消息:

[root@docker01 local]# /usr/local/kafka_2.13-2.6.0/bin/kafka-console-producer.sh --broker-list localhost:9092 --topic test
>test 1
>test 2
>
[root@docker01 local]# 

从测试主题上读取消息:

[root@docker01 local]# /usr/local/kafka_2.13-2.6.0/bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic test --from-beginning
test 1
test 2

4 broker配置:config/server.properties

Kafka 发行包里自带的配置样本可以用来安装单机服务,但并不能满足大多数安装场景的要求。 Kafka 有很多配置选项,涉及 安装和调优 的方方面面。不过大多数调优选项可以使用默认配置,除非你对调优有特别的要求。

4.1 常规配置

有一些配置选项,在单机安装时可以直接使用默认值,但在部署到其他环境时要格外小心。 这些参数是单个服务器最基本的配置,它们中的大部分需要经过修改后才能用在集群里

4.1.1. broker.id

每个 broker 都需要有 个标识符,使用 broker.id 来表示。它的默认值是 0,也可以被设成其它任意整数。 这个值在整个 kafka 集群里必须是唯一的。这个值可以任意选定 ,如果出于维护的需要,可以在服务器节点间交换使用这些 ID 。建议 把它们设置成与机器名具有相关性的整数,这样在进行维护时,将 ID 号映射到机器名就没那么麻烦了 例如,如机器名包含唯一性的数字(比如host1.example.com、 host2.example.com ),那么用这些数字来设置 broker.id 就再好不过了。

4.1.2. port

如果使用配置样本来启动 Kafka ,它会监听 9092 端口。修改 port 配置参数可以把它设置成其他任意可用的端口。要注意,如果使用 1024 以下的端口,需要使用 root 权限启动Kafka ,不过不建议这么做。

4.1.3. zookeeper.connect

用于保存 broker 元数据的 zookeeper 地址是通过 zookeeper.connect 来指定的。
localhost:2181 表示这个 zookeeper 是运行在本地的 2181 端口上。该配置参数是用 分号 分隔的 hostname:port/path 列表,每部分的含义如下

  • hostname 是 Zookeeper 服务器的机器名或 IP 地址:
  • port 是 Zookeeper 的客户端连接端口
  • /path 是可选的 Zookeeper 路径,作为 Kafka 集群的 chroot 环境。如果不指定,默认使用根路径。
    如果指定的 chroot 路径不存在, broker 会在启动的时候创建它。

最好是在配置文件里指定一组 Zookeeper 服务器,用 分号 把它们隔开。一旦有一个zookeeper 服务器宕机,broker 可以连接到 zookeeper 群组的另一个节点上。

4.1.4. log.dirs

Kafka 把所有消息都保存在磁盘上 ,存放这些日志片段的目录是通过 log.dirs 指定的。它是组用 逗号 分隔的本地文件系统路径。
如果指定了多个路径,那么 broker 会根据“最少使用”原则,把同个分区的日志片段保存到同一个路径下。
要注意, broker 会往拥有 最少分区数目的路径新增分区 ,而不是往拥有最小磁盘空间的路径新增分区。

4.1.5. num.recover.threads.per.data.dir

对于如下3种情况, Kafka 会使用可配置的线程池来处理日志片段:

  • 服务器正常启动,用于打开每个分区的日志片段
  • 服务器崩溃后重启,用于检查和截断每个分区的日志片段:
  • 服务器正常关闭,用于关闭日志片段。

默认情况下,每个日志目录只使用一个线程。因为这些线程只是在服务器启动和关闭时会用到 ,所以完全可以设置大量的线程来达到并行操作的目的。特别是对于包含大量分区的服务器来说,一旦发生崩溃,在进行恢复时使用并行操作可能会省下数小时的时间。设置此参数时需要注意,所配置的数字对应的是 log.dirs 指定的单个日志目录。 就是说,如 num.recover. threads.per.data.dir 被设为8,并且 log.dir 指定了 3 个路径,那么总共需 24 个线程。

4.1.6. auto.create.topics.enable

默认情况下, Kafka 会在如下几种情形下自动创建主题:

  • 当一个生产者开始往主题写入消息时
  • 当一个消费者开始从主题读取消息时
  • 任意一个客户端向主题发送元数据请求时。

很多时候,这些行为都是非预期的。而且,根据 Kafka 协议,如果一个主题不先被创建,根本无法知道它是否已经存在。如果显式地创建主题 不管是手动创建还是通过其它配置系统来创建,都可以把 auto.create.topics.enable 设为 false。

4.2 主题的默认配置

Kafka 为新创建的主题提供了很多默认配置参数。可以通过 管理工具 为每个主题单独配置一部分参数,比如 分区个数数据保留策略 。服务器提供的默认配置可以作为基准,它们适用于大部分主题。

4.2.1. num.partitions

num.partitions 参数指定了新创建的主题将包含多少个分区。如果启用了主题自动创建功能(该功能默认是启用的),主题分区的个数就是该参数指定的值。该参数的默认值是1
要注意,我们可以增加主题分区的个数,但不能减少分区的个数。所以,如果要让一个主题的分区个数少于num.partitions 指定的值,需要手动创建该主题。
Kafka 集群通过分区对主题进行横向扩展,所以当有新的 broker 加入集群时,可以通过分区个数来实现集群的负载均衡。为了能让分区分布到所有 broker 上, 主题分区的个数必须要大于 broker 的个数。

如何选定分区数量考虑如下几个因素

  • 主题需要达到多大的吞吐量?例如,是希望每秒钟写入100KB 还是1GB?
  • 从单个分区读取数据的最大吞吐量是多少?每个分区一般都会有一个消费者,如果你知道消费者将数据写入数据库的速度不会超过每秒 50MB ,那么你也该知道,从一个分区读取数据的吞吐量不需要超过每秒 50MB 。
  • 可以通过类似的方法估算生产者向单个分区写入数据的吞吐量,不过生产者的速度一般比消费者快得多,所以最好为生产者多估算一些吞吐量。
  • 每个 broker 包含的分区个数、可用的磁盘空间和网络带宽。
  • 如果消息是按照不同的键来写入分区的,那么为已有的主题新增分区就会很困难。
  • 单个 broker 对分区个数是有限制的,因为分区越多,占用的内存越多,完成首领选举需要的时间也越长。

综合考虑以上几个因素,你需要很多分区,但不能太多。如果你估算出主题的吞吐量和消费者吞吐量,可以用 主题吞吐量除以消费者吞吐量算出分区的个数 。也就是说,如果每秒钟要从主题上写入和读取 1GB 的数据,并且每个消费者每秒钟可以处理 50MB的数据,那么至少需要 20 个分区。这样就可以让 20 个消费者同时读取这些分区,从而达到每秒钟 1GB 的吞吐量。

如果不知道这些信息,那么根据经验,把分区的大小限制在 25GB 以内可以得到比较理想的效果。

4.2.2. log.retention.ms

Kafka 通常根据时间来决定数据可以被保留多久 。默认使用 log.retention.hour 参数来配置时间 ,默认值为 168 小时,也就是一周。除此以外,还有其他两个参数log.retention.minuteslog.retention.ms 。这3个参数的作用是一样的,都是决定消息多久以后会被删除,不过还是推荐使用 log.retention.ms。如果指定了不止一个参数, Kafka 会优先使用具有 最小值 的那个参数。

根据时间保留数据和最后修改时间

根据时间保留数据是通过检查磁盘上 日志片段文件的最后修改时间 来实现的。最后修改时间指的就是日志片段的关闭时间,也就是 文件里最后一个消息的时间戳
不过,如果使用管理工具在服务器间移动分区,最后修改时间就不准确了。时间误差可能导致这些分区过多地保留数据。

4.2.3. log.retention.bytes

另一种方式是 通过保留的消息字节数来判断消息是否过期 。它的值通过参数 log.retention.bytes 来指定,作用在每一个分区。也就是说,如果有一个包含 8 个分区的主题,并且 log.retention.bytes 被设为 1GB ,那么这个主题最多可以保留 8GB 的数据。所以,当主题的分区个数增加时,整个主题可以保留的数据也随之增加

根据字节大小和时间保留数据

如果同时指定了 log.retention.byteslog.retention.ms (或者另 一 个时间参数),只要任意一个条件得到满足,消息就会被删除。例如,假设 log.retention.ms 设置为 86 400 000 (也就是 1 天),log.retention.bytes 设置为 1 000 000 000 (也就是 1GB ),如果消息字节总数在不到一天的时间就超过了 1GB ,那么多出来的部分就会被删除。相反,如果消息字节总数小于 1GB ,那么一天之后这些消息也会被删除,尽管分区的数据总量小于 1GB 。

4.2.4. log.segment.bytes

以上的设置都作用在日志片段上,而不是作用在单个消息上。 当消息到达 broker 时,它们被迫加到分区的当前日志片段上。当日志片段大小达到 log.segment.bytes 指定的上限( 默认是 1GB )时,当前日志片段就会被关闭,一个新的日志片段被打开。如果一个日志片段被关闭,就开始等待过期。

这个参数的值越小,就会越频繁地关闭和分配新文件,从而降低磁盘写入的整体效率。

例子:
如果主题的消息量不大,那么如何调整这个参数的大小就变得尤为重要。例如,如果一个主题每天只接收 100MB 的消息,而 log.segment.bytes 使用默认设置,那么需要 10 天时间才能填满一个日志片段。因为在日志片段被关闭之前消息是不会过期的,所以如果 log.retention.ms 被设为 604 800 000 ( 也就是 1 周),那么日志片段最多需要 17 天才会过期。这是因为关闭日志片段需要 10 天的时间,而根据配置的过期时间,还需要再保留 7 天时间(要等到日志片段里的最后一个消息过期才能被删除) 。

使用时间戳获取偏移量

日志片段的大小会影响使用时间戳获取偏移量。在使用时间戳获取日志偏移量时, Kafka 会检查分区里最后修改时间大于指定时间戳的日志片段(已经被关闭的),该日志片段的前一个文件的最后修改时间小于指定时间戳。然后, Kafka 返回该日志片段(也就是文件名)开头的偏移量。对于使用时间戳获取偏移量的操作来说,日志片段越小,结果越准确。

4.2.5 . log.segment.ms

另 一个可以控制日志片段关闭时间的参数是 log.segment.ms ,它指定了多长时间之后日志片段会被关闭。就像 log.retention.byteslog.retention.ms这两个参数一样, log.segment.byteslog.segment.ms 这两个参数之间也不存在互斥问题。日志片段会在大小或时间达到上限时被关闭,就看哪个条件先得到满足。
默认情况下 ,log.segment.ms 没有设定值,所以只根据大小来关闭日志片段。

4.2.6 . message.max.bytes

broker 通过设置 message.max.bytes 参数来 限制单个消息的大小,默认值是 1 000 000 ,也就是 1 MB 。如果生产者尝试发送的消息超过这个大小,不仅消息不会被接收,还会收到 broker 返回的错误信息。跟其他与字节相关的配置参数一样 ,该参数指的是压缩后的消息、大小,也就是说,只要压缩后的消息小于 message.max.bytes 指定的值,消息的实际大小可以远大于这个值

这个值对性能有显著的影响。值越大,那么负责处理网络连接和请求的线程就需要花越多的时间来处理这些请求。它还会增加磁盘写入块的大小,从而影响 IO 吞吐量。

在服务端和客户端之间协调消息大小的配置

消费者客户端设置的 fetch.message.max.bytes必须与服务器端设置的消息大小进行协调。如果这个值比message.max.bytes 小,那么消费者就无法读取比较大的消息,导致出现消费者被阻塞的情况。在为集群里的 broker 配置 replica.fetch.max.bytes参数时 , 也遵循同样的原则。

5 Kafka 集群

集群最大的好处是可以跨服务器进行负载均衡,再则就是可以使用复制功能来避免因单点故障造成的数据丢失,在维护 Kafka 或底层系统时,使用集群可以确保为客户端提供高可用性

图片描述

下面只是介绍如何配置 Kafka 集群。

5.1 需要多少个broker,取决于以下几个因素

首先, 需要多少磁盘空间来保留数据,以及单个 broker 有多少空间可用 。如果整个集群需要保留 10TB 的数据, 每个broker 可以存储 2TB ,那么至少需要 5 个 broker 。如果启用了数据复制,那么至少还需要一倍的空间,不过这要取决于配置的复制系数是多少。 也就是说,如果启用 了数据复制,那么这个集群至少需要 10 个 broker 。

第二个要考虑的因素是 集群处理请求的能力 。这通常与网络接口处理客户端流量的能力有关,特别是当有多个消费者存在或者在数据保留期间流量发生波动(比如高峰时段的流量爆发)时。如果单个 broker 的网络接口在高峰时段可以达到 80% 的使用量,并且有两个消费者,那么消费者就无法保持峰值,除非有两个 broker 。如果集群启用了复制功能,则要把这个额外的消费者考虑在内。因磁盘吞吐量低和系统内存不足造成的性能问题,也可以通过扩展多个 broker 来解决。

5.2 broker配置

要把一个 broker 加入到集群里,只需要修改两个配置参数。
首先,所有 broker 都必须配置相同的 zookeeper.connect , 该参数指定了用于保存元数据的 Zookeeper 群组和路径。
其次,每个 broker 都必须为 broker.id 参数设置唯一的值如果两个 broker 使用相同的 broker.id,那么第二个 broker 就无法启动。

打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP