kafka篇-设计思路

本文转自 lecury 的博客:https://blog.lecury.cn

1. 设计背景

许多互联网公司,每天都会产生大量的日志数据,包括用户行为记录、运营指标、系统运行状况的监控数据等。为了分析用户的行为或者监控系统的状态,需要对这些数据进行周期性的分析和统计。传统的日志分析系统提供了一种离线处理日志信息的可扩展方案(类似于从生产环境的服务器上抓取日志文件,然后聚合到数据仓库进行离线分析),但如果要进行实时地处理,通常会有较大延迟。kafka构建了一种新颖的消息系统,提供了类似于消息传递系统的API,允许应用程序实时的订阅日志事件,做到实时或近实时分析。

2. 持久化设计

与传统消息系统不同的是,kafka会把消息持久化到磁盘上,以实现消息的回溯功能。磁盘总是给人们留下“慢速”的印象,事实上,磁盘的速度要比人们预想中的快得多,这取决于使用磁盘的姿势。常见的SATA磁盘随机读写性能,仅为100K/s,而顺序读写可达600MB/s,不同的使用姿势,性能差距可达到6000倍。kafka为了实现高吞吐的消息服务,充分借助了磁盘顺序读写的优势。

2.1 磁盘顺序读写

磁盘的顺序读写是有规律的,并且操作系统进行了大量优化,包括 read-aheadwrite-behind技术,其中 read-ahead是以大的data block为单位预先读取数据,而 write-behind则是将多个小型的逻辑写操作,合并成一次大型的物理磁盘写入。除此之外,操作系统还对读写磁盘的内容进行cache,主动将系统空闲内存用作 page cache,所有的磁盘读写操作都会通过这个 page cache。kafka没有使用 in-process cache来缓存磁盘数据,而是使用了 page cache,因为即使进程维护了 in-process cache,在读写磁盘时,该数据也会被复制到操作系统的 page cache中。直接使用 page cache一方面可以使得缓存容量大大增加,另一方面kafka服务重启的情况下,缓存依旧可用。为了充分利用磁盘顺序读写能力、实现消息存储时的高吞吐,kafka只是对消息进行 简单的读取和追加,并没有使用类似于BTree的数据结构来索引数据和随机读写数据。消息系统一般都是顺序消费、依次推送消息,这种根据需求特定场景进行的简单读取和追加,既可以满足实际需求,又能大幅提升吞吐。

2.2 消息过期机制

在 Kafka 中,可以让消息保留相对较长的一段时间(比如一周),而不是试图在被消费后立即删除,也可以让消息保留到一定规模后,比如消息大小超出2G,再清除旧数据。

3. 高吞吐设计

kafka的吞吐表现是极为优秀的,在kafka篇-基本介绍中也给出了吞吐性能的测试数据,这里简单谈一谈kafka高吞吐的设计要点。

3.1 本地IO的优化

kafka强依赖操作系统提供的page cache功能,采用简单读取、顺序追加的方式,保证读写操作均属于Sequence I/O,从而充分利用了磁盘顺序读写的性能。

3.2 网络IO的优化

kafka是一个分布式的消息系统,在消息的生产和消费过程中,不仅涉及到本地的IO,还涉及大量的网络IO,对于网络层IO的优化,主要涉及两个方面:
  • 避免大量小型的IO操作

  • 避免过多的字节拷贝

小型的IO操作发生在客户端与服务器之间,以及服务端自身的持久化操作中。 为了避免大量小型的IO操作,kafka对消息进行分组,使得多个消息打包成一组,而不是每次发送一条消息,这样可以减少小型网络IO的操作,批处理从而带来更大的吞吐。为了避免过多的字节拷贝,kafka对日志块的网络传输也进行了优化, 通过sendfile系统调用将数据从page cache直接转移到socket网络连接中。数据从文件到套接字,常见的数据传输路径如下:
  • 操作系统从磁盘读取数据 -> 内核空间的page cache

  • 应用程序读取内核空间数据 -> 用户空间的缓冲区

  • 应用程序将数据(用户空间的缓冲区) -> 内核空间到套接字缓冲区(内核空间)

  • 操作系统将数据从套接字缓冲区(内核空间) -> 网络发送的 NIC 缓冲区

中间涉及4次copy操作和两次系统调用,而通过sendfile的话,可以允许操作系统将数据从page cache直接发送到网络,即只需最后一步操作,可将数据复制到NIC缓冲区。

3.3 压缩

kafka提供了端到端的数据压缩功能,将消息以压缩格式写入,并在日志中保持压缩,只在consumer消费时解压缩。

4. 稳定性设计

稳定性对每一个系统来说,都是尤为重要的,kafka为了保障稳定性,不仅为每个数据分区实现了副本的概念,而且为日志备份提供了一整套的保障机制。

4.1 分区和副本

kafka将主题划分为多个分区,通过分区规则将消息存储到相应的分区,只要分区规则设置的合理,那么所有消息将会被均匀的分布到不同的分区中,从而实现负载均衡和水平扩展。kafka每个分区拥有若干副本,当集群部分节点出现问题时,可以进行故障转移,以保证数据的可用性。

4.2 日志备份 ISR

kafka稳定性的核心是备份日志文件,正常情况下每个分区都有一个leader和零或多个followers,读写操作均由leader处理,followers节点同步leader节点的日志,保持消息和偏移量同leader一致。日志的读写操作均由leader完成,其他follower节点从leader同步日志。如果leader因意外而退出,kafka会通过ISR集合选出新的leader节点。ISR(a set of in-sync replicas)是kafka维护的同步状态集合,只有这个集合的成员才有资格被选为leader,并且一条消息需要被这个集合的所有节点读取并追加到日志,这条消息才可以被视为提交,ISR集合的变化会持久化到ZooKeeper中。

5. 参考

kafka官方文档 http://kafka.apache.org


往期推荐

1、HBase最佳实践 | 聊聊HBase核心配置参数
2、Apache Hudi:剑指数据湖的增量处理框架
3、Hadoop社区比 Ozone 更重要的事情
4、MapReduce Shuffle 和 Spark Shuffle 结业篇

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
kafka是一个分布式的流处理平台,它可以处理和存储大规模的实时数据流。kafka-run-class是kafka提供的一个脚本工具,用于在命令行中执行指定的类。kafka.tools.GetOffsetShell是用于获取指定topic在指定时间点的偏移量信息的工具。 具体来说,kafka.tools.GetOffsetShell通过指定topic、时间点和broker列表来获取该topic在指定时间点的偏移量。它的用法类似于以下命令: ``` bin/kafka-run-class.sh kafka.tools.GetOffsetShell --topic <topic> --time <timestamp> --broker-list <broker-list> --partitions <partitions> ``` 其中,<topic>是要查询的topic名称,<timestamp>是要查询的时间点,<broker-list>是broker的地址列表,<partitions>是要查询的分区编号。该命令会返回指定topic在指定时间点的偏移量信息。 另外,kafka.tools.ConsumerOffsetChecker是kafka提供的另一个工具,用于检查消费者的偏移量信息。它可以通过指定zookeeper连接、消费者组和topic来获取消费者的偏移量信息。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [kafka监控命令kafka-run-class.sh查看消费了多少条数据](https://blog.csdn.net/m0_37739193/article/details/73849523)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [kafka_2.9.2-0.8.2.1.tgz](https://download.csdn.net/download/shy_snow/9372309)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值