kafka选举机制
当kafka集群中某分区中leader挂掉 ,我们需要followers选取新的leader保证该topic可用,但是有些follower本身可能处于落后或崩溃状态,所以为了必须要保证选举出来的新的leader是最新的有效的,kafka维护了一组实时同步leader的副本(ISR列表)。只有这组成员中才能当选leader。
分区副本管理
kafka会避免是单节点中保有大量分区副本,而是以循环的方式平衡集群中分区。也会平衡分配每个节点各分区副本的leader数,以使每个节点都是按比例分配其分区的leader。这样不会导致某些节点拥有leader过多而需要处理大量请求影响,而有些节点大量空闲,浪费整体资源。
日志压缩
kafka在数据保留方式中除了提供了在固定时间段后或日志达到某个预定大小后丢弃旧日志数据。以及更精细的保留机制(日志压缩),例如在一段时间对同一用户发生修改邮箱的操作,这些操作通过日志记录下来并且保存到kafka中:
123 => bill@microsoft.com
。。。。。
123 => bill@gatesfoundation.org。。。。。
123 => bill@gmail.comkafka可以保证我们至少保留每个主键的最新更新(例如日志压缩后会保留
123 => bill@gmail.com),日志压缩是一种提供更细粒度的每个记录保留的机制,而不是可以提供基于时间的粗粒度保留的机制。这个想法是有选择地删除具有相同主键的最新更新的记录。这样,可以确保日志至少具有每个键的最后状态。
配额
Kafka集群可以对请求强制执行配额,以控制客户端使用的代理资源,kafka broker 为每组客户(共享配额)强制执行两种类型的客户配额:
1.网络带宽配额 :定义字节速率阈值(从0.9开始)
2.请求速率配额:将CPU使用率阈值定义为网络和I / O线程的百分比(从0.11开始)
生产者和消费者有可能产生/消费大量数据或以非常高的速率生成请求,从而垄断broker。导致网络饱和,拥有配额可以避免这些问题,并且在大型多租户群集中尤为重要。
kafka client命令:
添加topic
> bin/kafka-topics.sh --bootstrap-server broker_host:port --create --topic my_topic_name \
--partitions 5 --replication-factor 3--config x=y
broker_host:portreplication-factor =3 代表往多少个副本中写入数据,3代表最多2台服务器发送故障,才失去对数据的访问权限(官网建议设置为2,3)
partitions =5 控制日志实际分区数,分区数量有几个影响。每个分区必须完全适合一台服务器。因此,如果有20个分区,则整个数据集(以及读写负载)将由不超过20台服务器(不计算副本)处理。分区数会影响使用者的最大并行度config 添加配置
修改主题:
>bin/kafka-topics.sh --bootstrap-server broker_host:port --alter --topic my_topic_name \
--partitions 40kafka目前不支持对partitions小于之前值的设置,Kafka也不会尝试以任何方式自动重新分配数据。。这样代表着如果使用
hash(key) % number_of_partitions 算法来进行数据分区,那么则原始分区数据可能会通过添加分区而被打乱。添加设置
> bin/kafka-configs.sh --bootstrap-server broker_host:port --entity-typetopics --entity-name my_topic_name --alter --add-config x=y修改设置
> bin/kafka-configs.sh --bootstrap-server broker_host:port --entity-type topics --entity-name my_topic_name --alter --delete-config x删除设置
> bin/kafka-configs.sh --bootstrap-server broker_host:port --entity-typetopics --entity-name my_topic_name --alter --delete-config x删除设置
> bin/kafka-topics.sh --bootstrap-server broker_host:port --delete --topic my_topic_name优雅关机
当服务器正常停止时,它会进行两项优化:
- 它将所有日志同步到磁盘上,以避免在重新启动时进行任何日志恢复(即,验证日志尾部所有消息的校验和)。日志恢复需要时间,因此可以加快有意重启的速度。
- 它将在关闭服务器之前将leader中数据迁移到其他副本。这将使leader层转移更快,并将每个分区不可用的时间减少到几毫秒。
只要服务器停止运行(不是通过强行终止),就会自动进行日志同步,受控leader迁移需要使用特殊设置
controlled.shutdown.enable=true
请注意,只有再broker所有分区都具有副本时(即复制因子大于1 并且这些副本中至少有一个处于活动状态),受控关闭才会成功
如果不正常关机会导致还在内存中为刷新到磁盘中数据丢失,以及leader中数据还没同步到所有flower中去。所以关闭kafka服务时尽量使用命令行形式而非kill -9暴力方式
leader自动平衡
开启自动leader自动平衡策略,避免集群因中某些服务器挂掉导致副本leader集中到某些节点。auto.leader.rebalance.enable=true
在集群中镜像数据
支持多个kafka集群之间copy镜像数据( 详细参考官网)
查看消费者offset位置
> bin/kafka-consumer-groups.sh --bootstrap-server localhost:9092 --describe --group my-group查看所有消费组
> bin/kafka-consumer-groups.sh --bootstrap-server localhost:9092 --list查看消费组详细信息
> bin/kafka-consumer-groups.sh --bootstrap-server localhost:9092 --describe --group my-group此外可添加附加参数获取更详细信息:
例如:
--members:此选项提供使用者组中所有活动成员的列表。
> bin/kafka-consumer-groups.sh --bootstrap-server localhost:9092 --describe --group my-group --members CONSUMER-ID HOST CLIENT-ID #PARTITIONS consumer1-3fc8d6f1-581a-4472-bdf3-3515b4aee8c1 /127.0.0.1 consumer1 2 consumer4-117fe4d3-c6c1-4178-8ee9-eb4a3954bee0 /127.0.0.1 consumer4 1 consumer2-e76ea8c3-5d30-4299-9005-47eb41f3d3c4 /127.0.0.1 consumer2 3 consumer3-ecea43e4-1f01-479f-8349-f9130b75d8ee /127.0.0.1 consumer3 0--members --verbose:除了上述“ --members”选项报告的信息之外,此选项还提供分配给每个成员的分区。
> bin/kafka-consumer-groups.sh --bootstrap-server localhost:9092 --describe --group my-group --members --verbose CONSUMER-ID HOST CLIENT-ID #PARTITIONS ASSIGNMENT consumer1-3fc8d6f1-581a-4472-bdf3-3515b4aee8c1 /127.0.0.1 consumer1 2 topic1(0), topic2(0) consumer4-117fe4d3-c6c1-4178-8ee9-eb4a3954bee0 /127.0.0.1 consumer4 1 topic3(2) consumer2-e76ea8c3-5d30-4299-9005-47eb41f3d3c4 /127.0.0.1 consumer2 3 topic2(1), topic3(0,1) consumer3-ecea43e4-1f01-479f-8349-f9130b75d8ee /127.0.0.1 consumer3 0 ---offsets:这是默认的describe选项,并提供与“ --describe”选项相同的输出。
--state:此选项提供有用的组级别信息
--delete 删除一个或多个消费者组
> bin/kafka-consumer-groups.sh --bootstrap-server localhost:9092 --delete --group my-group --group my-other-group Deletion of requested consumer groups ('my-group', 'my-other-group') was successful.--reset-offsets 重置消费者组
此选项需要定义以下范围:--all-topics或--topic,并且请确保消费者组实例处于非活动状态。
它具有3个执行选项:
- (默认)以显示要重置的偏移量。
- --execute:执行--reset-offsets完整过程。
- --export:将结果导出为CSV格式。
--reset-offsets还具有以下场景可供选择(必须选择至少一个场景):
- --to-datetime <String:datetime>:将偏移量重置为与datetime的偏移量。格式:“ YYYY-MM-DDTHH:mm:SS.sss”
- --to-最早:将偏移量重置为最早的偏移量。
- --to-latest:将偏移量重置为最新偏移量。
- --shift-by <Long:偏移数>:重置偏移量,将当前偏移量偏移为“ n”,其中“ n”可以为正或负。
- --from-file:将偏移量重置为CSV文件中定义的值。
- --to-current:将偏移量重置为当前偏移量。
- --by-duration <String:duration>:将偏移量重置为从当前时间戳记的持续时间偏移量。格式:“ PnDTnHnMnS”
- --to-offset:将偏移量重置为特定偏移量。
超出范围的偏移量将调整为最大偏移量。例如,如果偏移量结束为10,偏移量请求为15,则实际上将选择偏移量为10
> bin/kafka-consumer-groups.sh --bootstrap-server localhost:9092 --reset-offsets --group consumergroup1 --topic topic1 --to-latest TOPIC PARTITION NEW-OFFSET topic1 0 0对于旧的版本并组元数据存储在ZooKeeper中(即
offsets.storage=zookeeper),通过--zookeeper而不是bootstrap-server
扩展集群想要扩展kafka集群,只需要对新加入集群服务器分配唯一Id,然后启动服务器,但是kafka集群不会为这些新的自动分配任何数据分区,除非将分区移到新的服务器中,在创建新主题之前它们将不会做任何工作,通常在将计算机添加到群集时,您将需要将一些现有数据迁移到这些计算机。
分区重新分配工具可用于将某些主题从当前broker中移到新添加的brokers。这在扩展现有集群时通常很有用,因为与一次移动一个分区相比,将整个主题移至新的一组brokers更容易。用于执行此操作时,用户应提供应移至新的一组broker的主题列表和新brokers的目标列表。然后,该工具将给定主题列表中的所有分区平均分配到新的一组brokers中。在此过程中,主题的复制因子保持不变。实际上,主题输入列表的所有分区的副本都从旧的代理集移到了新添加的brokers.
例如,以下示例将主题foo1,foo2的所有分区移动到新的brokers(id为5,6)。在此步骤结束时,主题foo1和foo2的所有分区仅存在于id为brokers的5,6上。
第一步确定需要移动主题并输出为json文件。
由于该工具将主题的输入列表作为json文件,首先需要确定要移动的主题并按以下方式创建json文件:
> cat topics-to-move.json {"topics": [{"topic": "foo1"}, {"topic": "foo2"}], "version":1 }
第二步:由集群生成生成候选分配(--generate),由系统决定如何分配topic:
> bin/kafka-reassign-partitions.sh --zookeeper localhost:2181 --topics-to-move-json-file topics-to-move.json --broker-list "5,6" --generate Current partition replica assignment {"version":1, "partitions":[{"topic":"foo1","partition":2,"replicas":[1,2]}, {"topic":"foo1","partition":0,"replicas":[3,4]}, {"topic":"foo2","partition":2,"replicas":[1,2]}, {"topic":"foo2","partition":0,"replicas":[3,4]}, {"topic":"foo1","partition":1,"replicas":[2,3]}, {"topic":"foo2","partition":1,"replicas":[2,3]}] } Proposed partition reassignment configuration {"version":1, "partitions":[{"topic":"foo1","partition":2,"replicas":[5,6]}, {"topic":"foo1","partition":0,"replicas":[5,6]}, {"topic":"foo2","partition":2,"replicas":[5,6]}, {"topic":"foo2","partition":0,"replicas":[5,6]}, {"topic":"foo1","partition":1,"replicas":[5,6]}, {"topic":"foo2","partition":1,"replicas":[5,6]}] }第三步:执行分配
该工具先生成候选分配,该分配会将所有分区从主题foo1,foo2移至新的brokers5,6中。但是此时分区移动尚未开始,它仅告诉当前分配和建议的新分配。如果您想回滚到当前分配,则应将其保存。新的赋值应保存在json文件(例如,expand-cluster-reassignment.json)中,然后使用--execute选项输入到工具中,如下所示:
> bin/kafka-reassign-partitions.sh --zookeeper localhost:2181 --reassignment-json-file expand-cluster-reassignment.json --execute Current partition replica assignment {"version":1, "partitions":[{"topic":"foo1","partition":2,"replicas":[1,2]}, {"topic":"foo1","partition":0,"replicas":[3,4]}, {"topic":"foo2","partition":2,"replicas":[1,2]}, {"topic":"foo2","partition":0,"replicas":[3,4]}, {"topic":"foo1","partition":1,"replicas":[2,3]}, {"topic":"foo2","partition":1,"replicas":[2,3]}] } Save this to use as the --reassignment-json-file option during rollback Successfully started reassignment of partitions {"version":1, "partitions":[{"topic":"foo1","partition":2,"replicas":[5,6]}, {"topic":"foo1","partition":0,"replicas":[5,6]}, {"topic":"foo2","partition":2,"replicas":[5,6]}, {"topic":"foo2","partition":0,"replicas":[5,6]}, {"topic":"foo1","partition":1,"replicas":[5,6]}, {"topic":"foo2","partition":1,"replicas":[5,6]}] }最后一步验证最终分配结果
最后用--verify选项可与该工具一起使用,以检查分区的最新重新分配的状态。应将相同的expand-cluster-reassignment.json(与--execute选项一起使用)与--verify选项一起使用:
> bin/kafka-reassign-partitions.sh --zookeeper localhost:2181 --reassignment-json-file expand-cluster-reassignment.json --verify Status of partition reassignment: Reassignment of partition [foo1,0] completed successfully Reassignment of partition [foo1,1] is in progress Reassignment of partition [foo1,2] is in progress Reassignment of partition [foo2,0] completed successfully Reassignment of partition [foo2,1] completed successfully Reassignment of partition [foo2,2] completed successfully但是如果用户已经确定知道重新分配计划,则可以跳过上诉--generate()步骤的并直接进入--execute步骤
第一步是在json文件中手工制作自定义重新分配计划:
> cat custom-reassignment.json {"version":1,"partitions":[{"topic":"foo1","partition":0,"replicas":[5,6]},{"topic":"foo2","partition":1,"replicas":[2,3]}]}第二步 将json文件与--execute选项一起使用以开始重新分配过程:
> bin/kafka-reassign-partitions.sh --zookeeper localhost:2181 --reassignment-json-file custom-reassignment.json --execute Current partition replica assignment {"version":1, "partitions":[{"topic":"foo1","partition":0,"replicas":[1,2]}, {"topic":"foo2","partition":1,"replicas":[3,4]}] } Save this to use as the --reassignment-json-file option during rollback Successfully started reassignment of partitions {"version":1, "partitions":[{"topic":"foo1","partition":0,"replicas":[5,6]}, {"topic":"foo2","partition":1,"replicas":[2,3]}] }最后一步:验证
> bin/kafka-reassign-partitions.sh --zookeeper localhost:2181 --reassignment-json-file custom-reassignment.json --verify Status of partition reassignment: Reassignment of partition [foo1,0] completed successfully Reassignment of partition [foo2,1] completed successfully指定topic的某个分区添加新的副本
增加现有分区副本很容易。只需在自定义重新分配json文件中指定额外的副本,然后将其与--execute选项一起使用即可增加指定分区的副本。
例如,以下示例将主题foo的分区0的副本数据从1增加到3。在增加副本之前,该分区的唯一副本存在于代理5上。作为增加副本的一部分,我们将在经纪人6和7创建2,3副本
第一步:新建json文件中编写自定义重新分配计划:
> cat increase-replication-factor.json {"version":1, "partitions":[{"topic":"foo","partition":0,"replicas":[5,6,7]}]}第二步:将json文件与--execute选项一起使用以开始重新分配过程:
> bin/kafka-reassign-partitions.sh --zookeeper localhost:2181 --reassignment-json-file increase-replication-factor.json --execute Current partition replica assignment {"version":1, "partitions":[{"topic":"foo","partition":0,"replicas":[5]}]} Save this to use as the --reassignment-json-file option during rollback Successfully started reassignment of partitions {"version":1, "partitions":[{"topic":"foo","partition":0,"replicas":[5,6,7]}]}最后一步:验证
> bin/kafka-reassign-partitions.sh --zookeeper localhost:2181 --reassignment-json-file increase-replication-factor.json --verify Status of partition reassignment: Reassignment of partition [foo,0] completed successfully也可以通过kafka-topics工具验证
> bin/kafka-topics.sh --bootstrap-server localhost:9092 --topic foo --describe Topic:foo PartitionCount:1 ReplicationFactor:3 Configs: Topic: foo Partition: 0 Leader: 5 Replicas: 5,6,7 Isr: 5,6,7限制数据迁移期间网络带宽
Kafka允许对数据copy之间流量应用限制,在用于将副本在计算机之间移动的带宽上设置上限。当重新平衡群集,新增或删除broker很有用,因为它限制了这些数据密集型操作对用户的影响。
执行重新平衡时使用以下命令,它将以不超过50MB / s的速度移动分区
$ bin/kafka-reassign-partitions.sh --zookeeper localhost:2181 --execute --reassignment-json-file bigger-cluster.json —throttle 50000000 The throttle limit was set to 50000000 B/s Successfully started reassignment of partitions.重新修改带宽限制
$ bin/kafka-reassign-partitions.sh --zookeeper localhost:2181 --execute --reassignment-json-file bigger-cluster.json --throttle 700000000 There is an existing assignment running. The throttle limit was set to 700000000 B/s
重新平衡完成后,可以使用--verify选项检查重新平衡的状态。如果重新平衡完成,则需要通过--verify命令删除限制否则,可能会限制常规数据迁移。
> bin/kafka-reassign-partitions.sh --zookeeper localhost:2181 --verify --reassignment-json-file bigger-cluster.json Status of partition reassignment: Reassignment of partition [my-topic,1] completed successfully Reassignment of partition [mytopic,0] completed successfully Throttle was removed.查看各brokers宽带极限配置:
> bin/kafka-configs.sh --describe --zookeeper localhost:2181 --entity-type brokers Configs for brokers '2' are leader.replication.throttled.rate=700000000,follower.replication.throttled.rate=700000000 Configs for brokers '1' are leader.replication.throttled.rate=700000000,follower.replication.throttled.rate=700000000要查看集群中限制副本的topic列表:
> bin/kafka-configs.sh --describe --zookeeper localhost:2181 --entity-type topics Configs for topic 'my-topic' are leader.replication.throttled.replicas=1:102,0:101, follower.replication.throttled.replicas=1:101,0:102使用限制副本copy注意点:
1:重新分配完成后,应及时关闭限制(通过运行kafka-reassign-partitions -verify)。
2:确保限流阀值设置不能比写入各broker数据的速率小,需要根据实际情况调整此阀值
LinkedIn在使用kafka的一些基本配置
JVM配置:
-Xmx6g -Xms6g -XX:MetaspaceSize=96m -XX:+UseG1GC -XX:MaxGCPauseMillis=20 -XX:InitiatingHeapOccupancyPercent=35 -XX:G1HeapRegionSize=16M -XX:MinMetaspaceFreeRatio=50 -XX:MaxMetaspaceFreeRatio=80GC使用jdk1.8的G1,使得所有broker都具有90%的GC暂停时间(约21ms),并且每秒执行的 Yong GC少于1个
- 共60 brokers
- 共50k partitions (每个分区2副本)
- 800k messages/sec in(每秒80万条消息)
- 300 MB/sec inbound, 1 GB/sec+ outbound (入站300 MB /秒,出站1 GB /秒以上)
部署在linux系统上一些关于OS的配置优化:
- 增大文件描述符限制 (fd):Kafka将文件描述符用于日志段和打开的连接,建议100000个fd作为起点
- 增大最大套接字缓冲区大小:使数据在集群中心之间的实现高性能数据传输
- 最大虚拟内存区域数(vm.max_map_count文件包含限制一个进程可以拥有的VMA(虚拟内存区域)的数量。虚拟内存区域是一个连续的虚拟地址空间区域。在进程的生命周期中,每当程序尝试在内存中映射文件,链接到共享内存段,或者分配堆空间的时候,这些区域将被创建。调优这个值将限制进程可拥有VMA的数量。限制一个进程拥有VMA的总数可能导致应用程序出错,因为当进程达到了VMA上限但又只能释放少量的内存给其他的内核进程使用时,操作系统会抛出内存不足的错误。)。一般linux系统中对于一个进程最大的vm.max_map_count的值大约为65535。当我们创建一个分区时,每个分区分配的每个日志段都需要一对索引/时间索引文件,并且每个文件占用1个映射区域的话,一个分区的创建需要占用2个映射区域数,一个分区至少需要2个内存映射区域数,也就是说当一个broker中超过了32768个分区数时,可能导致broker在默认vm.max_map_count的系统上因OutOfMemoryError(映射失败)而崩溃。
后续会介绍:springboot+kafka一些应用场景。springCloud+kafka构建消息总线(springcloud bus)
参考官网:http://kafka.apache.org/documentation/
总结:学习一个新的技术最好的方法是直接去官网去了解最新最权威知识。
868

被折叠的 条评论
为什么被折叠?



