Kafka设计原理以及在达观产品中的应用

简介:

达观数据作为一家提供大数据服务的公司,经常会遇到客户上报数据的需求。这样的请求不需要马上返回处理结果, 而是需要后台将一系列的上报数据进行统一归档整理挖掘, 然后将结果数据呈现给客户。这样的业务需求需要达观提供数据暂存服务,也就是说我们需要一个系统在生产者(客户上报数据)和消费者(后台数据处理)之间进行沟通,简而言之叫系统间通信消息系统,这种模型就是经典的生产者(producer)、消费者(consumer)模型。

然而有一个消息系统正好是为了应对这种业务场景而生,它就是kafka。那么kafka到底是一个什么样的系统?有什么特点?实际吞吐表现又如何?带着这些问题,我们一起来了解一下。

一, Kafka简介

首先根据官网介绍,知道kafka是一个分布式流处理平台,一个可处理企业级发布/订阅的消息系统,并且具有高容错性和消费及时性等特点,那么它是怎么做到这一点的呢?接着往下看。

1,主题和日志:

主题(topic)和日志(log)设置是kafka一大特色,一个kafka集群可以创建多个topic, 每个topic都相当于一个消息队列,这就意味着可以将不同格式的数据发布到不同的topic中,减小消费这些数据时的逻辑难度。那么每个topic中处理的数据结构是怎样呢?我们先来看一张topic的解剖图:

Kafka

图1:topic原理解析图

从图1中可以看到, 消息传送过来时kafka会通过负载均衡将消息最终写入到磁盘上一个特定分区(partition)。由于在同一个partition上这些消息都是顺序存储的, 所以对一个特定分区每条消息都会有一个基于起始位置的偏移量(offset), 因此我们在后续消费时只需要指明从哪个partition中哪个offset开始消费,就能达到重复消费目的。

1)虽然kafka可以通过增加partition方式来增加负载,但是它的数据最终是被写入到磁盘中。比如机械磁盘写入效率是很低的, 难道我们需要增大一个topic的负载给它设置更多的partition吗?

机械磁盘驱动器吞吐量跟寻道延时是强关联,也就是说,线性读写速度远大于随机读写。例如,在67200rpm SATA RAID-5磁盘阵列中, 随机写速度大约是100k/s, 然而线性写速度可以达到600M/s,后者大约是前者的6000倍。通过图1可知, kafka采用的即是后者, 利用操作系统read-ahead和write-behind技术,极大提升磁盘访问性能;设置partition数量固然可以从磁盘读写角度增大topic负载,但是partition数量过多会导致cpu计算量增大,所以最佳办法是根据不同配置的机器, 不同的业务场景设置不同的partition数量。

2)偏移量offset存储类型是什么, 如果消息足够大,offset的值是否会重新置0, 如果置0,后续消费是否会紊乱?

kafka offset 是一个日志序列号( log sequence number),不必担心offset 长度问题。那么这个日志序列号到底有多大,举个例子:如果一个partition一天接收1T日志, 这个offset至少可以使用1百万年。由于offset足够用,而且不会被置0,所以从这个角度讲消费紊乱情况是不会出现的。

3)写入磁盘的日志会被永久保留吗?如果想删除过期消息, 需要怎么操作?

可以通过配置文件中log.retention参数设置消息过期时间,超过过期时间的消息会被系统删除,删除的消息不可再被重新消费。

2,分布式集群

通过前文介绍我们已经了解到kafka通过partition和顺序读写磁盘的方式达到很高吞吐量,可是单台机器吞吐量再高一旦该机发生故障宕掉就会对业务产生灾难性影响,怎么处理这个问题呢?想必你已经知道了,那就是采用集群的方式,一旦一台机器发生故障客户端可以选择链接其它机器, 保证业务稳定性。每一个partition 都会有一个服务器来作为领导者(leader), 另外一个或者多个服务器(server)来作为跟随者(follower),leader会处理所有的读写请求,而follower则会从leader那里备份数据, 如果一个leader失败了, 其它的follower会自动选举一个成为一个新的leader, 所以对于一个server来说,他可能是某些partition下的leader, 而对于另外一些partition来说则是follower,这样设计可以将负载更好均衡。

1)搭建kafka集群时有没有什么小细节需要值得注意的?

kafka官网已经有详细的搭建过程,在此不赘述。建议正式项目中不要采用伪集群(多个broker运行在同一台物理机上)的搭建方式,而且zookeeper集群和kafka集群最好不要出现在同一台实体机上,这样会影响kafka顺序读写效率。

2)在kafka集群中如果一个server失败, 怎样保证数据完整性?

在kafka配置文件中有一个复制因子控制参数,如果将该参数设置为N,则表示一份数据会被保存N次,而这些数据被备份到不同server中,所以当设置复制因子为N时即使有N-1台server失败,也会保证数据完整性。

3,生产者消费者和消息的顺序性:

上面讲了那么多,无非是要实现一个队列的数据结构。对于队列这种数据结构我们一点也不陌生,由此可以想到对于kafka的一个topic 队列来说,生产消费逻辑应该是这样:有很多生产者向topic中写入数据,另外一端则有许多消费者消费数据。(见图2)

Kafka

图2:生产者消费者原理解析图

然而实际上kafka生产者消费者模式有它的特殊性,那么kafka这个队列是怎样实现入队和出队的?接下来我们一起来看看kafka生产者消费者模式。

生产者:生产者(producer)顾名思义,就是向kafka队列中发布消息的,即入队操作者。生产者功能是在topic中选择一个partion 然后向这个partition中发送数据。选择partition的过程就是一个负载均衡的方式, 比如可以采用轮询或者自己设定partition选择函数来实现负载均衡。当然如果使用封装的api比如(https://github.com/dpkp/kafka-python)就大可不必关心负载均衡问题。会有默认的负载均衡函数来实现这一功能。

消费者: 消费者(consumer)功能是从队列中读取数据并进行相应逻辑处理,但是kafka消费者有特殊之处。kafka增加了一个组(group)的概念,一个topic可以有多个group, 当多个consumer从属于一个组时,一条消息将被发往所有组,但是在组内,这条消息只会被一个consumer消费。由此说来一个group才是一个真正“逻辑消费者(logic consumer)”。相关逻辑如图3所示。

消息顺序性:通过图3我们知道消息的消费情况,那么一个消息流消费情况会是怎样的?其实在高等级api中由于指定了负载均衡规则,同一个生产者发布两条不同消息数据时会根据相应规则发送到一个特定partition中,在消费时会按照同样规则从partition中取出数据,这样就能保证两条数据消费的先后顺序,从而保证了消息顺序性。

1)对于一个具有多个consumer的topic,我要实现一条消息被多个consumer消费和一条消息只被一个consumer消费,那我需要怎么设置group?

将多个consumer设置为同一个组可以实现一条消息只被多个consumer消费, 将所有的consumer都设置为不同组,一条消息将会被所有consumer消费。

2)如果有一批数据消费时必须严格按照入队先后顺序来消费,需要怎样设置生产者和消费者。

如果数据量小,可以将topic设置为一个partition;如果数据量较大,可以将一个生产者写死负载均衡函数,将数据发送到一个特定partition上,消费数据时指定消费者消费的partition,和offset来顺序消费数据。

Kafka

图3:多个消费者组时消息流向原理图

二, Kafka性能测试:

kafka是跨语言消息队列系统,github上提供了Java, Python等多种语言客户端,为了简单起见,我们这里采用kafka-python(https://github.com/dpkp/kafka-python)作为客户端来链接kafka集群做测试。

测试环境:

1, broker 数量:3
2, 备份因子数:2
3, 磁盘信息:200G普通机械硬盘
4, cpu参数:8核8线程
5, 语言: Python2.7
6, 客户端: kafka-python
7, partition 数量: 5

单进程producer 发送10条消息测试(如图4):

Kafka

图4:一个生产者发送消息延时结果图

统计上图数据可知平均延时:0.004488707,也就是说qps可以达到2000,这样的成绩无疑是惊人的。那么在多进程情况下kafka表现还会好吗?我们设置10个进程,看看kafka在10个进程下的延时会有较大的变化吗?如图5(打印消息过多,截取部分结果图):

Kafka

图5:多个生产者发送消息延时结果图(部分)

由图5可知10 个进程每个进程发送10条消息,平均延时为0.00050380466秒, qps接近200000,由于kafka支持数千个客户端同时读写,所以kafka吞吐能力是惊人的,更多测试欢迎大家去完成。

三,kafka在达观数据的应用介绍

1,在垂直搜索中的应用:

我们知道搜索引擎需要定时对文档进行更新, 如果我们把需要更新内容暂存到 kafka,这样索引更新时,只需要从对应 partition 中从上一次取过的 offset 处继续取数据,就能达到增量更新目的,而过期数据会被自动清理, 减少了操作冗余性和复杂性。

2,在用户画像以及相关推荐中的应用:

和用户画像之前上报的用户点击行为数据不同,相关推荐之前的海量 item 数据上报对数据准确性要求更高,试想如果一条 item 数据因为处理失败而没有正确入库,那么相关推荐时就永远不会出现这条 item, 所以这就对“可回滚”提出了更加严格要求。然而在 kafka 中,也只需要将消费的 offset 重新置为消费失败时的 offset,修复入库问题重新消费即可。

当然 kafka 还有更加广泛的应用,这里就不一一讨论,根据官网的介绍,kafka 在网站行为追踪(Website Activity Tracking)、数据监控, 流处理等众多方面有特长,如果你对 kafka 原理有研究或者有实际应用方面有心得,欢迎来讨论,谢谢!


本文作者:蹇智华

来源:51CTO

相关文章
|
1月前
|
消息中间件 缓存 关系型数据库
Flink CDC产品常见问题之upsert-kafka增加参数报错如何解决
Flink CDC(Change Data Capture)是一个基于Apache Flink的实时数据变更捕获库,用于实现数据库的实时同步和变更流的处理;在本汇总中,我们组织了关于Flink CDC产品在实践中用户经常提出的问题及其解答,目的是辅助用户更好地理解和应用这一技术,优化实时数据处理流程。
|
3月前
|
消息中间件 缓存 Kafka
探究Kafka原理-5.Kafka设计原理和生产者原理解析(下)
探究Kafka原理-5.Kafka设计原理和生产者原理解析
39 0
|
3月前
|
消息中间件 存储 负载均衡
探究Kafka原理-5.Kafka设计原理和生产者原理解析(上)
探究Kafka原理-5.Kafka设计原理和生产者原理解析
63 0
|
3月前
|
消息中间件 存储 负载均衡
kafka核心原理,藏在这 16 张图里
kafka核心原理,藏在这 16 张图里
25 0
|
3月前
|
消息中间件 存储 设计模式
Kafka原理篇:图解kakfa架构原理
Kafka原理篇:图解kakfa架构原理
76 1
|
20天前
|
消息中间件 监控 Kafka
【Kafka】Kafka 数据一致性原理
【4月更文挑战第7天】【Kafka】Kafka 数据一致性原理
|
30天前
|
消息中间件 存储 Kafka
【深入浅出 RocketMQ原理及实战】「底层源码挖掘系列」透彻剖析贯穿一下RocketMQ和Kafka索引设计原理和方案
【深入浅出 RocketMQ原理及实战】「底层源码挖掘系列」透彻剖析贯穿一下RocketMQ和Kafka索引设计原理和方案
48 1
|
1月前
|
消息中间件 关系型数据库 MySQL
Flink CDC产品常见问题之用upsert的方式写入kafka失败如何解决
Flink CDC(Change Data Capture)是一个基于Apache Flink的实时数据变更捕获库,用于实现数据库的实时同步和变更流的处理;在本汇总中,我们组织了关于Flink CDC产品在实践中用户经常提出的问题及其解答,目的是辅助用户更好地理解和应用这一技术,优化实时数据处理流程。
|
1月前
|
消息中间件 关系型数据库 Kafka
Flink CDC产品常见问题之Flink CDC里从kafka消费的时候顺序混乱如何解决
Flink CDC(Change Data Capture)是一个基于Apache Flink的实时数据变更捕获库,用于实现数据库的实时同步和变更流的处理;在本汇总中,我们组织了关于Flink CDC产品在实践中用户经常提出的问题及其解答,目的是辅助用户更好地理解和应用这一技术,优化实时数据处理流程。
|
1月前
|
消息中间件 Java Kafka
【Spring底层原理高级进阶】Spring Kafka:实时数据流处理,让业务风起云涌!️
【Spring底层原理高级进阶】Spring Kafka:实时数据流处理,让业务风起云涌!️

热门文章

最新文章