|
|
楼主 |
发表于 2022-12-30 09:07:15
|
显示全部楼层
在了解完 Kafka 的基本概念之后,我们通过搭建 Kafka 集群来进一步深刻认识一下 Kafka。7 `+ T5 r, y7 r" a. u3 f3 U
( F& g1 [; p w' ?/ a确保安装环境* p) w; p* h4 X p
安装 Java 环境
4 K8 D; Y% d% S在安装 Kafka 之前,先确保Linux 环境上是否有 Java 环境,使用 java -version 命令查看 Java 版本,推荐使用Jdk 1.8 ,如果没有安装 Java 环境的话,可以按照这篇文章进行安装(https://www.cnblogs.com/zs-notes/p/8535275.html)+ o: ?0 N" r* C" a& ?/ U
# x& q* M9 r3 _+ i# t# v) l5 D
安装 Zookeeper 环境' Z$ m* }# b/ ^ w5 p$ s0 W
Kafka 的底层使用 Zookeeper 储存元数据,确保一致性,所以安装 Kafka 前需要先安装 Zookeeper,Kafka 的发行版自带了 Zookeeper ,可以直接使用脚本来启动,不过安装一个 Zookeeper 也不费劲% e" k, a/ D; A& \9 A r
# ]5 b3 n6 e+ r; W; f/ rZookeeper 单机搭建. E! Z) G* c+ d
Zookeeper 单机搭建比较简单,直接从 https://www.apache.org/dyn/closer.cgi/zookeeper/ 官网下载一个稳定版本的 Zookeeper ,这里我使用的是 3.4.10,下载完成后,在 Linux 系统中的 /usr/local 目录下创建 zookeeper 文件夹,使用xftp 工具(xftp 和 xshell 工具都可以在官网 https://www.netsarang.com/zh/xshell/ 申请免费的家庭版)把下载好的 zookeeper 压缩包放到 /usr/local/zookeeper 目录下。
. p- i$ N- w8 A# z( Q0 |9 v% `- q8 S8 b, I
如果下载的是一个 tar.gz 包的话,直接使用 tar -zxvf zookeeper-3.4.10.tar.gz解压即可5 y6 S! E" _% u0 I" T) S
' w" ^, Z' x( j- B3 B5 n如果下载的是 zip 包的话,还要检查一下 Linux 中是否有 unzip 工具,如果没有的话,使用 yum install unzip 安装 zip 解压工具,完成后使用 unzip zookeeper-3.4.10.zip 解压即可。 L c$ ^: W8 R9 d
. R+ ~" q/ f7 n5 G. {解压完成后,cd 到 /usr/local/zookeeper/zookeeper-3.4.10 ,创建一个 data 文件夹,然后进入到 conf 文件夹下,使用 mv zoo_sample.cfg zoo.cfg 进行重命名操作
2 ~% h2 ^/ G5 C- @ C1 M% J2 U* o* C; U$ v. Q
然后使用 vi 打开 zoo.cfg ,更改一下dataDir = /usr/local/zookeeper/zookeeper-3.4.10/data ,保存。
9 O Z5 L% x! Z+ H. M& k' r p& a* ]( A# o' o$ e" G. [
进入bin目录,启动服务输入命令 ./zkServer.sh start 输出下面内容表示搭建成功
4 ^9 z- V7 X) b8 @* k
r- l% |7 s* Q# H! Y) c关闭服务输入命令,./zkServer.sh stop
3 F+ c* ^( D0 w2 M0 m. |& {6 J, {9 `& j& [3 Y
7 {* ] i8 s6 h5 V- l! x$ N& r* i
% z! y- M) [ P- }使用 ./zkServer.sh status 可以查看状态信息。
& s. t( w$ \' p* A5 H+ k' ~6 V4 P- U; c
Zookeeper 集群搭建
3 t$ G$ q+ W+ l& g5 K% ?& W准备条件+ U2 A6 }, s. H d% w- _
准备条件:需要三个服务器,这里我使用了CentOS7 并安装了三个虚拟机,并为各自的虚拟机分配了1GB的内存,在每个 /usr/local/ 下面新建 zookeeper 文件夹,把 zookeeper 的压缩包挪过来,解压,完成后会有 zookeeper-3.4.10 文件夹,进入到文件夹,新建两个文件夹,分别是 data 和 log 文件夹
# j6 W- n" ?. j* b3 J$ C1 k- g" b. G3 P4 R
注:上一节单机搭建中已经创建了一个data 文件夹,就不需要重新创建了,直接新建一个 log 文件夹,对另外两个新增的服务需要新建这两个文件夹。1 @2 X; \* F( P8 T
" W* o8 h1 r j3 Y+ U设置集群/ L, P- V) h# l: }0 ]+ y5 A1 c
新建完成后,需要编辑 conf/zoo.cfg 文件,三个文件的内容如下
( o( t) _! t, X5 i) x. U) m! m8 `. X5 C) i) u+ w- a# s! ~
tickTime=2000: C/ X3 q' k* U2 S
initLimit=10- a. \6 R+ `4 j
syncLimit=5
. C9 m* K# z8 EdataDir=/usr/local/zookeeper/zookeeper-3.4.10/data, b9 c2 ~& _1 Z: q
dataLogDir=/usr/local/zookeeper/zookeeper-3.4.10/log
$ ~; ]: A' T4 T5 tclientPort=12181
6 r( ]# Y' T- d7 M6 ~2 Eserver.1=192.168.1.7:12888:13888
5 @7 T8 b6 q9 ~& \7 ^server.2=192.168.1.8:12888:13888
4 H5 _5 q4 e# h1 w. @1 \server.3=192.168.1.9:12888:13888
0 o e) v" a2 b4 ?$ fserver.1 中的这个 1 表示的是服务器的标识也可以是其他数字,表示这是第几号服务器,这个标识要和下面我们配置的 myid 的标识一致可以。
9 m$ k4 j% H+ ?* D4 R/ o6 D- l: c+ b9 n! B8 ~
192.168.1.7:12888:13888 为集群中的 ip 地址,第一个端口表示的是 master 与 slave 之间的通信接口,默认是 2888,第二个端口是leader选举的端口,集群刚启动的时候选举或者leader挂掉之后进行新的选举的端口,默认是 3888
8 g* I L4 ]6 z* h+ R
# F' r9 f! c" g) c现在对上面的配置文件进行解释9 }1 N- u" T& W* h: h9 n" ?. p& i
( A) W; @0 M. H2 f! x
tickTime: 这个时间是作为 Zookeeper 服务器之间或客户端与服务器之间维持心跳的时间间隔,也就是每个 tickTime 时间就会发送一个心跳。
5 b; S1 ~3 }0 S: o$ S$ f8 A
/ F- Q' D# V p1 d# h( \initLimit:这个配置项是用来配置 Zookeeper 接受客户端(这里所说的客户端不是用户连接 Zookeeper 服务器的客户端,而是 Zookeeper 服务器集群中连接到 Leader 的 Follower 服务器)初始化连接时最长能忍受多少个心跳时间间隔数。当已经超过 5个心跳的时间(也就是 tickTime)长度后 Zookeeper 服务器还没有收到客户端的返回信息,那么表明这个客户端连接失败。总的时间长度就是 5*2000=10 秒
6 h( y1 F/ u( p- j
- `7 ~( u1 ~ ], xsyncLimit: 这个配置项标识 Leader 与Follower 之间发送消息,请求和应答时间长度,最长不能超过多少个 tickTime 的时间长度,总的时间长度就是5*2000=10秒9 |) f+ I$ `3 S6 W
/ N4 k" m* m1 b0 N
dataDir: 快照日志的存储路径
' g7 n& [7 K: y
1 ~! m- S) k" zdataLogDir: 事务日志的存储路径,如果不配置这个那么事务日志会默认存储到dataDir指定的目录,这样会严重影响zk的性能,当zk吞吐量较大的时候,产生的事务日志、快照日志太多7 X4 H2 k$ O+ f0 u* J
' i7 [+ U# C% Q% I$ U# RclientPort: 这个端口就是客户端连接 Zookeeper 服务器的端口,Zookeeper 会监听这个端口,接受客户端的访问请求。
/ {. y! K# X, {2 Z( M, |5 M6 ^! @- ?' C, ]& b, g) L2 M
创建 myid 文件
" l% u! {- w, \9 y在了解完其配置文件后,现在来创建每个集群节点的 myid ,我们上面说过,这个 myid 就是 server.1 的这个 1 ,类似的,需要为集群中的每个服务都指定标识,使用 echo 命令进行创建. L! @: ?( q: c0 d6 j
2 O# n* J4 r0 L) s2 q9 y# F# server.1
4 Y Q% U) |+ _echo "1" > /usr/local/zookeeper/zookeeper-3.4.10/data/myid+ @* C7 s/ b, ~% [4 }8 c
# server.2
; K) a0 M0 s. m; ~3 s3 S* recho "2" > /usr/local/zookeeper/zookeeper-3.4.10/data/myid& @( q8 _9 h% U, h1 T4 y ?
# server.3 F! c" u+ s3 B# W9 y1 ^
echo "3" > /usr/local/zookeeper/zookeeper-3.4.10/data/myid
+ a" R1 y; x8 E. G- [+ H启动服务并测试
, `" Y# {: [7 r6 L配置完成,为每个 zk 服务启动并测试,我在 windows 电脑的测试结果如下: {5 }6 ^ x& b' c4 m
6 o" H2 ^! N) j$ _2 i5 W1 f
启动服务(每台都需要执行)
, y/ i! f! n5 p; q" ]5 O4 w
& W* U8 j% N# p4 N( Zcd /usr/local/zookeeper/zookeeper-3.4.10/bin/ X3 d+ B& K& E. _$ ?
./zkServer.sh start3 ?- X( v J) P4 p7 A
检查服务状态. x/ u' Z* p* `, g! Z6 a* Z0 ?
2 O* z% s) P, d+ T
使用 ./zkServer.sh status 命令检查服务状态
7 z6 ^9 _& r5 F& ^ c( C& {
3 k% L6 |% J1 d( Y- S2 x( g8 g% `. k% n192.168.1.7 — follower
& T; ?; W! i' s8 ^
% X0 I5 J: B) r$ U0 j" Y
: {# m; d J! v5 _6 O! [8 v: e( Z
; T$ i& m' T4 `! j192.168.1.8 — leader/ }2 f, {, n/ i3 l2 X9 L( X
6 l+ B5 ]3 ]! Q2 u
3 f6 @- @! W. b# u6 v L* }) v9 c) o
192.168.1.9 — follower
) T% J, U) Y( y# Y! v5 a0 h9 W6 k4 S5 y
" p: U% P! [8 V3 ]4 u! D
- L- G7 C2 u) X: {zk集群一般只有一个leader,多个follower,主一般是相应客户端的读写请求,而从主同步数据,当主挂掉之后就会从follower里投票选举一个leader出来。9 H- R2 P1 z% S* t, h+ g
1 L3 v0 U9 I. b F5 _Kafka 集群搭建
. y" }" |9 o0 m4 C% w" `6 J准备条件4 Y- i$ E, e7 `* i8 N# c3 W
搭建好的 Zookeeper 集群* t0 e% f/ e: \
Kafka 压缩包 (https://www.apache.org/dyn/close ... afka_2.12-2.3.0.tgz)
( h, ]) j, e- Y* [在 /usr/local 下新建 kafka 文件夹,然后把下载完成的 tar.gz 包移到 /usr/local/kafka 目录下,使用 tar -zxvf 压缩包 进行解压,解压完成后,进入到 kafka_2.12-2.3.0 目录下,新建 log 文件夹,进入到 config 目录下
- n" z! ]/ Q, n6 _' r" ], w1 M* ^: m8 L" \% w4 |
我们可以看到有很多 properties 配置文件,这里主要关注 server.properties 这个文件即可。/ V+ p+ T9 n ^: \6 G7 l
8 `. z+ }, ?/ o& B# V% y( ]. p* Q3 D3 B+ z. A) N) |" ~) U# E
& ?1 x; C5 i/ C3 w0 Rkafka 启动方式有两种,一种是使用 kafka 自带的 zookeeper 配置文件来启动(可以按照官网来进行启动,并使用单个服务多个节点来模拟集群http://kafka.apache.org/quickstart#quickstart_multibroker),一种是通过使用独立的zk集群来启动,这里推荐使用第二种方式,使用 zk 集群来启动
. W | \! E: f: f% p: f H
3 u0 V# v& h4 p/ T3 |' l( u$ f修改配置项# D; F/ w6 P5 Y; ^( g( k5 a7 Y
需要为每个服务都修改一下配置项,也就是server.properties, 需要更新和添加的内容有
. Z' `& m8 s1 X4 d5 a8 z
6 L$ N" i& N: c: D cbroker.id=0 //初始是0,每个 server 的broker.id 都应该设置为不一样的,就和 myid 一样 我的三个服务分别设置的是 1,2,3
! P9 f. U2 r0 V2 n8 y1 Glog.dirs=/usr/local/kafka/kafka_2.12-2.3.0/log# U( k* W; m7 y8 p
9 s9 z, k9 n. F
#在log.retention.hours=168 下面新增下面三项
7 r$ W9 C* N2 n2 B" w1 Jmessage.max.byte=5242880( S6 _2 Y: _7 o. z0 i8 {9 v K B
default.replication.factor=2& V: G3 a) ~: k7 m1 `2 r& M
replica.fetch.max.bytes=52428802 x% D4 U4 B7 z( g" O
+ u H6 s }: @
#设置zookeeper的连接端口$ e- a: p$ v9 s! [* E- Z
zookeeper.connect=192.168.1.7:2181,192.168.1.8:2181,192.168.1.9:2181
5 X4 @3 f2 A6 W9 ?3 q. U" O# @- ]配置项的含义6 e4 {( t: o- Z
- p, K. i1 w+ L/ [. \
broker.id=0 #当前机器在集群中的唯一标识,和zookeeper的myid性质一样& j2 N( [! u# d
port=9092 #当前kafka对外提供服务的端口默认是9092
2 y2 G4 ]) v0 y4 w% Uhost.name=192.168.1.7 #这个参数默认是关闭的,在0.8.1有个bug,DNS解析问题,失败率的问题。
' w+ Z% k3 {& V2 B* v6 Rnum.network.threads=3 #这个是borker进行网络处理的线程数
4 K2 |1 r0 a& p8 Q8 K, Rnum.io.threads=8 #这个是borker进行I/O处理的线程数
6 ~/ G" Q9 ]5 b. a1 Vlog.dirs=/usr/local/kafka/kafka_2.12-2.3.0/log #消息存放的目录,这个目录可以配置为“,”逗号分割的表达式,上面的num.io.threads要大于这个目录的个数这个目录,如果配置多个目录,新创建的topic他把消息持久化的地方是,当前以逗号分割的目录中,那个分区数最少就放那一个# m# [4 d3 O2 g; L# F/ K
socket.send.buffer.bytes=102400 #发送缓冲区buffer大小,数据不是一下子就发送的,先回存储到缓冲区了到达一定的大小后在发送,能提高性能# P& J, J! G. ]
socket.receive.buffer.bytes=102400 #kafka接收缓冲区大小,当数据到达一定大小后在序列化到磁盘, B K' F' L9 O/ F6 R# N
socket.request.max.bytes=104857600 #这个参数是向kafka请求消息或者向kafka发送消息的请请求的最大数,这个值不能超过java的堆栈大小
# f2 k1 d% B* H+ ?num.partitions=1 #默认的分区数,一个topic默认1个分区数; k( W; V5 v+ Q. E0 o: Y6 [
log.retention.hours=168 #默认消息的最大持久化时间,168小时,7天0 `3 }- W# Z3 |6 P* B- q* P
message.max.byte=5242880 #消息保存的最大值5M4 [# _( a. Z$ L8 A, _4 ?
default.replication.factor=2 #kafka保存消息的副本数,如果一个副本失效了,另一个还可以继续提供服务 F" X! A9 Y3 l( N3 [# J5 m
replica.fetch.max.bytes=5242880 #取消息的最大直接数' m6 p! A; c4 U% [* u
log.segment.bytes=1073741824 #这个参数是:因为kafka的消息是以追加的形式落地到文件,当超过这个值的时候,kafka会新起一个文件
, f' c4 G3 ]# a% f5 tlog.retention.check.interval.ms=300000 #每隔300000毫秒去检查上面配置的log失效时间(log.retention.hours=168 ),到目录查看是否有过期的消息如果有,删除9 D8 g. Q) ?5 G) m! q- M
log.cleaner.enable=false #是否启用log压缩,一般不用启用,启用的话可以提高性能
' x3 L+ c! P* Hzookeeper.connect=192.168.1.7:2181,192.168.1.8:2181,192.168.1.9:2181 #设置zookeeper的连接端口
0 Q1 }; T( Q' W7 N启动 Kafka 集群并测试6 s P; l" Z4 t/ a8 Z
启动服务,进入到 /usr/local/kafka/kafka_2.12-2.3.0/bin 目录下1 J, ~" b, Q x, X6 x3 }2 e
# 启动后台进程0 ]) U6 g7 h' i/ y7 ]3 u* r% [
./kafka-server-start.sh -daemon ../config/server.properties' G( D# j; a1 y0 c& h4 Q7 y
检查服务是否启动. Q' a4 A; a' d3 \
# 执行命令 jps
4 f1 @ p0 H4 `! C$ R" N6201 QuorumPeerMain
) {! W5 h" U" T7035 Jps& G' ^; g' T7 C. G
6972 Kafka
9 T. b% s* P: z" G2 [" f# w( Q3 E( ~kafka 已经启动3 A: e I1 W3 v9 T
创建 Topic 来验证是否创建成功
- Y9 H4 d8 p- r3 F V# cd .. 往回退一层 到 /usr/local/kafka/kafka_2.12-2.3.0 目录下4 `) w' ]2 I" V& z9 a0 j8 l
bin/kafka-topics.sh --create --zookeeper 192.168.1.7:2181 --replication-factor 2 --partitions 1 --topic cxuan, Q3 T/ @* ^' F4 o
对上面的解释8 [7 j/ i0 q* R7 ~# R- [
' t$ `/ N' K' i( v( T ?9 l! v–replication-factor 2 复制两份
' r) v. E. Y1 v k& f1 N+ Q1 u# H. |/ I% l; f0 e* T2 x1 A- F
–partitions 1 创建1个分区: N+ j$ D7 {- H; i) Y* W
0 X% d8 p+ [# @; i–topic 创建主题& K. C H* i2 O+ t+ v; a1 t
9 e& N, U! Q% @3 {; r; j# T- k# f查看我们的主题是否出创建成功! I8 o6 W5 Y: { l7 u, Z
5 C K3 K1 ]% S I
bin/kafka-topics.sh --list --zookeeper 192.168.1.7:21817 b2 [7 y! M+ v: } Z! Q( q+ k
; b4 d+ \0 ~ N! ?& q
, A, o3 j4 W% O4 q" I" E3 U启动一个服务就能把集群启动起来/ a+ Q r3 N* q
0 D2 D' s* A J6 N; {
在一台机器上创建一个发布者
2 A6 h( Z+ |' l( V: U( o2 Z: x6 [" |. k' T$ A: y
# 创建一个broker,发布者4 v! Z! T. X: c7 O2 u* D1 p
./kafka-console-producer.sh --broker-list 192.168.1.7:9092 --topic cxuantopic
! U7 U! a. u$ k! H' m在一台服务器上创建一个订阅者8 e7 Y, } |, a3 }! H) x7 x
% t: k/ c. B Q* N: O' G2 @" B$ T3 v# 创建一个consumer, 消费者; J% J' Q9 j. g, M( Q6 ~
bin/kafka-console-consumer.sh --bootstrap-server 192.168.1.7:9092 --topic cxuantopic --from-beginning
7 W# f% |3 H% v4 r注意:这里使用 –zookeeper 的话可能出现 zookeeper is not a recognized option 的错误,这是因为 kafka 版本太高,需要使用 --bootstrap-server 指令
% z: {7 B: E7 j# a' w: z8 b' I! P# ]" c2 A# [ ?
测试结果, ~! e3 v( l* ~) [* w: w2 N* f7 y: g
" M. V; r, B" \. p& z发布% h' E% v/ n" T* l1 `8 M ?
- s# B- b+ ]+ }* j% i' `2 W d2 h. z) x* w! z! `1 S
* a, F- ]" L t) N8 @7 T) j消费
' @+ [& c4 M1 b0 J8 T2 p1 P& _4 x; \
% U, ]; `3 q, |* E/ R ^9 |$ c0 }) F. [, a$ y
其他命令
0 n2 a T1 L: j) b0 G& {显示 topic
; q1 D6 S- _- g. I+ }7 Y. w% q0 `7 v5 x* @% x
bin/kafka-topics.sh --list --zookeeper 192.168.1.7:21816 `- o7 i$ c2 C. e
( k# }) _+ J; E# U
# 显示
" Z+ V% s6 s$ l9 J% icxuantopic
v3 w% t" h9 ^0 r查看 topic 状态
/ Z8 V- v6 ^) X" Z" x `8 y2 J; F5 I, D) h& H4 ]4 G9 Z: g
bin/kafka-topics.sh --describe --zookeeper 192.168.1.7:2181 --topic cxuantopic
. E" h: r2 y8 {2 E6 P
- a- x" X7 M' [6 W5 K, ^% [# 下面是显示的详细信息
0 G& Y: S9 L. I% `Topic:cxuantopic PartitionCount:1 ReplicationFactor:2 Configs:( O. J' u& [5 ?+ F$ @( y
Topic: cxuantopic Partition: 0 Leader: 1 Replicas: 1,2 Isr: 1,2
/ S. O; e; J! `5 e# Y' o6 \" _- O2 t. e8 y/ A& I' Z, e
# 分区为为1 复制因子为2 主题 cxuantopic 的分区为0
6 {, b3 ?- Z0 b- V! n# Replicas: 0,1 复制的为1,2% I. C0 F7 T8 B* A
Leader 负责给定分区的所有读取和写入的节点,每个节点都会通过随机选择成为 leader。
3 s+ q" T8 {* K7 j1 q. A& `) r
& u% x. f# X- M+ r" {% t2 a! }3 `6 r% t, ?2 oReplicas 是为该分区复制日志的节点列表,无论它们是 Leader 还是当前处于活动状态。
3 c! L/ w& }; [6 E1 ?" g N/ z& \1 s: o, q" j+ e
Isr 是同步副本的集合。它是副本列表的子集,当前仍处于活动状态并追随Leader。2 I% b: k" d- Q0 d4 O- x: W7 \
2 \/ g" X( `0 [1 T. [( {- N至此,kafka 集群搭建完毕。" z1 q, F/ ]8 a' f8 O7 O
0 ^( {% d: [) x- y. X
验证多节点接收数据6 j5 ~7 B; ~1 s3 T" U0 T, Y8 v
刚刚我们都使用的是 相同的ip 服务,下面使用其他集群中的节点,验证是否能够接受到服务7 {+ M8 t( `' u9 D# t
+ c8 w& y& e0 V* Z. S$ k& u3 }
在另外两个节点上使用: g. g1 K4 B/ z: _
8 S9 L- M& S- R
bin/kafka-console-consumer.sh --bootstrap-server 192.168.1.7:9092 --topic cxuantopic --from-beginning
0 H8 ?6 V4 }4 N/ c6 c然后再使用 broker 进行消息发送,经测试三个节点都可以接受到消息。
8 |' J* q9 t* U- s3 b' G$ S
3 V \ }% ~1 S7 x# l1 i: M( P2 K7 o配置详解6 ~ @ E9 @# ?% X) e! N
在搭建 Kafka 的时候我们简单介绍了一下 server.properties 中配置的含义,现在我们来详细介绍一下参数的配置和概念
5 q' ^) ?3 y- j. a
/ \4 k+ B. @( c9 @) }常规配置0 `+ K: a9 q9 v; Z3 k8 L5 Z5 `$ \
这些参数是 kafka 中最基本的配置5 h$ T& N& X3 A- F6 ?
4 S, ^0 `$ }( c
broker.id% Y" Z7 [" g! X' c1 P; Q
每个 broker 都需要有一个标识符,使用 broker.id 来表示。它的默认值是 0,它可以被设置成其他任意整数,在集群中需要保证每个节点的 broker.id 都是唯一的。
2 p& E; b- w, q8 ^6 W5 h# H! t5 d Y# m+ M7 I7 i& Q" ]
port A. R1 @- @5 Z% K2 V' P9 A
如果使用配置样本来启动 kafka ,它会监听 9092 端口,修改 port 配置参数可以把它设置成其他任意可用的端口。
6 e0 V. t4 R" Y& t3 S T" S- G
2 v' q# J, S6 O' [$ {$ l( Qzookeeper.connect F0 O1 z8 K4 n" @- ]( S% A
用于保存 broker 元数据的地址是通过 zookeeper.connect 来指定。 localhost:2181 表示运行在本地 2181 端口。该配置参数是用逗号分隔的一组 hostname:port/path 列表,每一部分含义如下:
; ?8 \' \1 ~$ m' I/ |! n$ @4 K3 [2 R9 ]& P# x0 G
hostname 是 zookeeper 服务器的服务名或 IP 地址
y7 X) I: g+ Z& E$ {3 w4 i8 @3 I3 a8 P- h9 ~9 x
port 是 zookeeper 连接的端口2 v9 L3 x0 c( @ n+ P
- l" {% W# T/ }* A* U/path 是可选的 zookeeper 路径,作为 Kafka 集群的 chroot 环境。如果不指定,默认使用跟路径
/ z* n: ]4 O( M9 o" T, ? m% V7 k
- a2 A+ ?' M7 i' [log.dirs% D, K: [) K# u2 Y1 j
Kafka 把消息都保存在磁盘上,存放这些日志片段的目录都是通过 log.dirs 来指定的。它是一组用逗号分隔的本地文件系统路径。如果指定了多个路径,那么 broker 会根据 “最少使用” 原则,把同一分区的日志片段保存到同一路径下。要注意,broker 会向拥有最少数目分区的路径新增分区,而不是向拥有最小磁盘空间的路径新增分区。
% f6 X! u- g* @. F) L& g: G9 t, l. y* f
num.recovery.threads.per.data.dir5 ]- ^1 f5 P/ T4 W% A+ ~
对于如下 3 种情况,Kafka 会使用可配置的线程池来处理日志片段' e* W. H! I4 [9 b) g, }4 C
2 G+ u0 g5 c( k: d/ _- ]服务器正常启动,用于打开每个分区的日志片段;0 \9 o8 J; P" p2 ^
L% h; U& X; u5 J5 R2 W5 J9 X. p服务器崩溃后启动,用于检查和截断每个分区的日志片段;8 r9 }6 h( s' c7 [3 i- P/ n8 n8 H
) \) j6 E# O( C- {/ U( j' A. ~服务器正常关闭,用于关闭日志片段
" M+ N+ K& E8 O# f
1 N3 s* w) n. g5 O |默认情况下,每个日志目录只使用一个线程。因为这些线程只是在服务器启动和关闭时会用到,所以完全可以设置大量的线程来达到井行操作的目的。特别是对于包含大量分区的服务器来说,一旦发生崩愤,在进行恢复时使用井行操作可能会省下数小时的时间。设置此参数时需要注意,所配置的数字对应的是 log.dirs 指定的单个日志目录。也就是说,如果 num.recovery.threads.per.data.dir 被设为 8,并且 log.dir 指定了 3 个路径,那么总共需要 24 个线程。
1 n' o) a; s# f( C2 b- k5 z: l' ^& s; z1 C( l! ]! G
auto.create.topics.enable
$ p! i9 V6 |/ R* e6 ~# N默认情况下,Kafka 会在如下 3 种情况下创建主题
1 F6 p' j9 v! i1 Q& Y, o, a4 n& X- i9 C( i# p. B. I
当一个生产者开始往主题写入消息时
1 }: @( |. S4 v$ y; f+ G8 |1 k: Y7 ?9 ~9 t: z- c
当一个消费者开始从主题读取消息时7 \7 s% [8 y0 Z
" o# J2 R* `+ B' _, v
当任意一个客户向主题发送元数据请求时# y% c6 c1 K* _3 N+ H; l
3 p$ F( w9 D/ z+ o2 P- h' E1 m& y2 _
delete.topic.enable' B- N# K' r" H) p, q9 j2 s
如果你想要删除一个主题,你可以使用主题管理工具。默认情况下,是不允许删除主题的,delete.topic.enable 的默认值是 false 因此你不能随意删除主题。这是对生产环境的合理性保护,但是在开发环境和测试环境,是可以允许你删除主题的,所以,如果你想要删除主题,需要把 delete.topic.enable 设为 true。4 {/ J: |- H. Q
, S8 Q4 h" J9 q1 \( y主题默认配置9 W! T" t) J5 S7 u, {# G
Kafka 为新创建的主题提供了很多默认配置参数,下面就来一起认识一下这些参数( M2 o$ {; K0 z4 W
7 Z* A% h0 w, o+ y% j0 e* J& Knum.partitions. D. s9 r- P1 t3 \' t
num.partitions 参数指定了新创建的主题需要包含多少个分区。如果启用了主题自动创建功能(该功能是默认启用的),主题分区的个数就是该参数指定的值。该参数的默认值是 1。要注意,我们可以增加主题分区的个数,但不能减少分区的个数。5 I }9 \/ G E5 k ^
4 m' C8 A) p! R5 X
default.replication.factor9 g( K! c; \2 X) f$ H, z; O, b
这个参数比较简单,它表示 kafka保存消息的副本数,如果一个副本失效了,另一个还可以继续提供服务default.replication.factor 的默认值为1,这个参数在你启用了主题自动创建功能后有效。, S9 z, i4 |/ n' b: w
. ^ n7 g, R; |log.retention.ms/ x% w" n0 m2 ~* s
Kafka 通常根据时间来决定数据可以保留多久。默认使用 log.retention.hours 参数来配置时间,默认是 168 个小时,也就是一周。除此之外,还有两个参数 log.retention.minutes 和 log.retentiion.ms 。这三个参数作用是一样的,都是决定消息多久以后被删除,推荐使用 log.retention.ms。
$ K ^% |8 T0 b8 L& w0 }# ?9 s- }9 @2 J1 C' I
log.retention.bytes
' l2 F+ ?& {8 j* q# w: u另一种保留消息的方式是判断消息是否过期。它的值通过参数 log.retention.bytes 来指定,作用在每一个分区上。也就是说,如果有一个包含 8 个分区的主题,并且 log.retention.bytes 被设置为 1GB,那么这个主题最多可以保留 8GB 数据。所以,当主题的分区个数增加时,整个主题可以保留的数据也随之增加。
* x4 W+ \5 r5 [' {0 Q5 o$ N. L2 C1 X6 h/ O/ x% n
log.segment.bytes2 V, s V1 O$ _2 n0 s
上述的日志都是作用在日志片段上,而不是作用在单个消息上。当消息到达 broker 时,它们被追加到分区的当前日志片段上,当日志片段大小到达 log.segment.bytes 指定上限(默认为 1GB)时,当前日志片段就会被关闭,一个新的日志片段被打开。如果一个日志片段被关闭,就开始等待过期。这个参数的值越小,就越会频繁的关闭和分配新文件,从而降低磁盘写入的整体效率。6 t$ V W: l8 x# P
4 G- o2 R0 ?% N* {9 D
log.segment.ms, X' R: n6 `2 B/ a; N1 J8 K
上面提到日志片段经关闭后需等待过期,那么 log.segment.ms 这个参数就是指定日志多长时间被关闭的参数和,log.segment.ms 和 log.retention.bytes 也不存在互斥问题。日志片段会在大小或时间到达上限时被关闭,就看哪个条件先得到满足。
% @# e- l, C5 c9 D( }( z& {" }0 k
# T1 b0 n3 \) M; H! z0 b% h' ymessage.max.bytes) I {5 [2 b0 Z* w# u! n) }
broker 通过设置 message.max.bytes 参数来限制单个消息的大小,默认是 1000 000, 也就是 1MB,如果生产者尝试发送的消息超过这个大小,不仅消息不会被接收,还会收到 broker 返回的错误消息。跟其他与字节相关的配置参数一样,该参数指的是压缩后的消息大小,也就是说,只要压缩后的消息小于 mesage.max.bytes,那么消息的实际大小可以大于这个值4 r& T7 q: z# J; l
8 j; f. v* `- E: |/ I这个值对性能有显著的影响。值越大,那么负责处理网络连接和请求的线程就需要花越多的时间来处理这些请求。它还会增加磁盘写入块的大小,从而影响 IO 吞吐量。 |
|