架构师之路-如何建立高可用消息中间件kafka?( 七 )


Kafka文档中提及GUID(Globally Unique Identifier)的概念 。通过客户端生成算法得到每个消息的unique id 。同时可映射至broker上存储的地址 。即通过GUID便可查询提取消息内容 。也便于发送方的幂等性保证 。需要在broker上提供此去重处理模块 。目前版本尚不支持 。
针对GUID, 如果从客户端的角度去重 。那么需要引入集中式缓存 。必然会增加依赖复杂度 。另外缓存的大小难以界定 。
不只是Kafka, 类似RabbitMQ以及RocketMQ这类商业级中间件也只保障at least once, 且也无法从自身去进行消息去重 。所以我们建议业务方根据自身的业务特点进行去重 。比如业务消息本身具备幂等性 。或者借助Redis等其他产品进行去重处理 。
4.3 高可靠性配置
Kafka提供了很高的数据冗余弹性 。对于需要数据高可靠性的场景 。我们可以增加数据冗余备份数(replication.factor) 。调高最小写入副本数的个数(min.insync.replicas)等等 。但是这样会影响性能 。反之 。性能提高而可靠性则降低 。用户需要自身业务特性在彼此之间做一些权衡性选择 。
要保证数据写入到Kafka是安全的 。高可靠的 。需要如下的配置:
topic的配置:replication.factor>=3,即副本数至少是3个;2<=min.insync.replicas<=replication.factor
broker的配置:leader的选举条件unclean.leader.election.enable=false
producer的配置:request.required.acks=-1(all) 。producer.type=sync
5 BenchMark
Kafka在唯品会有着很深的历史渊源 。根据唯品会消息中间件团队(VMS团队)所掌握的资料显示 。在VMS团队运转的Kafka集群中所支撑的topic数已接近2000 。每天的请求量也已达百亿级 。这里就以Kafka的高可靠性为基准点来探究几种不同场景下的行为表现 。以此来加深对Kafka的认知 。为大家在以后高效的使用Kafka时提供一份依据 。
5.1 测试环境
Kafka broker用到了4台机器 。分别为broker[0/1/2/3]配置如下:
CPU: 24core/2.6GHZ
Memory: 62G
Network: 4000Mb
OS/kernel: CentOs release 6.6 (Final)
Disk: 1089G
Kafka版本:0.10.1.0
broker端JVM参数设置:-Xmx8G -Xms8G -server -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled -XX:+CMSScavengeBeforeRemark -XX:+DisableExplicitGC -Djava.awt.headless=true -Xloggc:/apps/service/kafka/bin/../logs/kafkaServer-gc.log -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.port=9999
客户端机器配置:
CPU: 24core/2.6GHZ
Memory: 3G
Network: 1000Mb
OS/kernel: CentOs release 6.3 (Final)
Disk: 240G
5.2 不同场景测试
场景1:测试不同的副本数、min.insync.replicas策略以及request.required.acks策略(以下简称acks策略)对于发送速度(TPS)的影响 。
具体配置:一个producer;发送方式为sync;消息体大小为1kB;partition数为12 。副本数为:1/2/4;min.insync.replicas分别为1/2/4;acks分别为-1(all)/1/0 。
具体测试数据如下表(min.insync.replicas只在acks=-1时有效):

架构师之路-如何建立高可用消息中间件kafka?

文章插图
测试结果分析:
客户端的acks策略对发送的TPS有较大的影响 。TPS:acks_0 > acks_1 > ack_-1;
副本数越高 。TPS越低;副本数一致时 。min.insync.replicas不影响TPS;
acks=0/1时 。TPS与min.insync.replicas参数以及副本数无关 。仅受acks策略的影响 。
下面将partition的个数设置为1 。来进一步确认下不同的acks策略、不同的min.insync.replicas策略以及不同的副本数对于发送速度的影响 。详细请看情景2和情景3 。
场景2:在partition个数固定为1 。测试不同的副本数和min.insync.replicas策略对发送速度的影响 。
具体配置:一个producer;发送方式为sync;消息体大小为1kB;producer端acks=-1(all) 。变换副本数:2/3/4; min.insync.replicas设置为:1/2/4 。
测试结果如下:
架构师之路-如何建立高可用消息中间件kafka?

文章插图
测试结果分析:副本数越高 。TPS越低(这点与场景1的测试结论吻合) 。但是当partition数为1时差距甚微 。min.insync.replicas不影响TPS 。
场景3:在partition个数固定为1 。测试不同的acks策略和副本数对发送速度的影响 。
具体配置:一个producer;发送方式为sync;消息体大小为1kB;min.insync.replicas=1 。topic副本数为:1/2/4;acks: 0/1/-1 。
测试结果如下:
架构师之路-如何建立高可用消息中间件kafka?

推荐阅读