Kafka——性能逆天的存在

_飞翔的企鹅_

本文链接:https://blog.csdn.net/gdutliuyun827/article/details/53761108

(by 刘延允,2016-12-17)

0、引言

Kafka是LinkedIn开源出来的一款消息服务器,用scala语言实现;这货的性能是百万级的QPS(估计是挂载了多块磁盘),我随便写个测试程序就是十万级。

1、Kafka基本概念

在Kafka中消息是按照Topic进行分类的;每条发布到Kafka集群的消息都有一个类别,这个类别被称为Topic。(物理上不同Topic的消息分开存储,逻辑上一个Topic的消息虽然保存于一个或多个broker上但用户只需指定消息的Topic即可生产或消费数据而不必关心数据存于何处)。

每个Topic包含一个或多个Parition;Parition是物理存储上的概念,创建Topic时可指定Parition数量。每个Parition对应一个存储文件夹,文件夹下存储该Parition所持有的消息数据和索引文件。Topic进行分区划分的主要目的是出于性能方面的考虑,Kafka尽量的使所有分区均匀的分布到集群所有的节点上而不是集中在某些节点上,另外主从关系也尽量均衡,这样每个节点都会担任一定比例的分区的Leader。每个Parition是一个有序的队列,每条消息在Parition中拥有一个offset。

消息的发布者可将消息发布到指定的Topic中,同时Producer也能决定将此消息发送到哪个Parition(也可以采取随机、哈希、轮训等策略)。

消息的消费者主动从Kafka中拉取消息进行消费(pull模式),在Kafka中一个Parition中的消息可以被无限多个消费者进行消费,每个消费者之间是完全独立,每个Consumer消费后的消息Kafka并不进行删除操作,Kafka中的消息删除是定期进行的,可以指定保留多长时间消息不被删除。通过指定offset就可以消费任意位置的消息,当然前提是指定的offset是存在的。从这点上看Kafka更像是一个只能追加、不能修改、支持随机读取的小文件管理系统。

上面提到每个Consumer是完全独立,如果多个Consume想轮流消费同一个Topic的同一个Parition就做不到;后来Kafka发明了一个Consumer-group的概念,每个Consumer客户端被创建时,会向Zookeeper注册自己的信息;一个group中的多个Consumer可以交错的消费一个Topic的所有Paritions;简而言之,保证此Topic的所有Paritions都能被此group所消费,且消费时为了性能考虑,让Parition相对均衡的分散到每个Consumer上,Consume-group之间是完全独立。主人的相反是挺好的,但是悲剧的是客户端基本都不支持,貌似只有java的客户端支持比较好。

2、消息顺序性与可靠性设计

发布到Kafka的消息在一个Parition中是顺序存储的,发布者可以通过随机、哈希、轮训等方式发布到多个分区中,消费者通过指定offset进行消费;所以Kafka当中消息的顺序性更多的取决于使用方如何使用。

Kafka系统中消息支持容灾备份存储,每个Parition有主分区、备用分区的概念,一个Topic中的多个Parition的主分区可能落在不同的物理机器上面,Kafka也是尽量让其分布在不同的机器上以提高系统性能。消息的读写都是通过主分区直接完成,客户端要直连主分区所在的物理机进行读写操作。备用分区就像一个"Consumer"消费主分区的消息并保存在本地日志中进行备份;主分区负责跟踪所有的备用分区的状态,如果备用分区"落后"太多或者失效,主分区将会把它从同步列表中删除;主备分区的管理是通过zookeeper进行的。

发布时的可靠性取决于两点:发送端的确认机制、以及Kafka系统落地的策略。发送端支持无确认、主分区确认(主分区收到消息后发送确认回执)、以及主备分区确认(备用分区消息同步后主分区才发送确认回执)三种机制;Kafka系统落地的策略有两种刷盘方式:通过配置消息数、以及配置刷盘时间间隔。

消费时的可靠性取决于消费者的读取逻辑,Kafka是不保存消息的任何状态的。At most once、At least once 、Exactly once 三种模式需要自己按照业务实现,最容易实现就是At least once,两外两种在分布式系统中都不可能做到完全的绝对实现,只能无限靠近,降低错误率。

3、消息存储方式

Parition是以文件的形式存储在文件系统中,比如创建了一个名为tipocTest的Topic,其有4个Parition,在Kafka的数据目录下面会有四个文件夹,按照Topic-partnum命名。

每个文件夹的内容

Parition中的每条Message由offset来表示它在这个Parition中的偏移量,这个offset不是该Message在Parition数据文件中的实际存储位置,而是逻辑上一个值,它唯一确定了Parition中的一条Message。因此,可以认为offset是Parition中Message的id。Parition中的每条Message包含了三个属性: Offset 、DataSize 、Data;Parition的数据文件则包含了若干条上述格式的Message,按offset由小到大排列在一起;Kafka收到新的消息后追加到文件末尾即可,所以消息的发布效率是很高的。

下面我们来思考另一个问题,如果一个Parition只有一个数据文件会怎么样? 新消息是添加在文件末尾,不论文件数据文件有多大,这个操作永远都是O(1)。但是在读取的时候根据offset查找Message是顺序查找的,因此,如果数据文件很大的话,查找的效率就低。那么Kafka是如何解决查找效率的的问题呢?1) 分段、2) 索引。

4、数据文件的分段与索引

Kafka解决查询效率的手段之一是将数据文件分段,可以配置每个数据文件的最大值,每段放在一个单独的数据文件里面,数据文件以该段中最小的offset命名。这样在查找指定offset的Message的时候,用二分查找就可以定位到该Message在哪个段中。

数据文件分段使得可以在一个较小的数据文件中查找对应offset的Message了,但是这依然需要顺序扫描才能找到对应offset的Message。为了进一步提高查找的效率,Kafka为每个分段后的数据文件建立了索引文件,文件名与数据文件的名字是一样的,只是文件扩展名为.index。索引文件中包含若干个索引条目,每个条目表示数据文件中一条Message的索引——Offset与position(Message在数据文件中的绝对位置)的对应关系;index文件中并没有为数据文件中的每条Message建立索引,而是采用了稀疏存储的方式,每隔一定字节的数据建立一条索引。这样避免了索引文件占用过多的空间,从而可以将索引文件保留在内存中。但缺点是没有建立索引的Message也不能一次定位到其在数据文件的位置,从而需要做一次顺序扫描,但是这次顺序扫描的范围就很小了。

每个分段还有一个.timeindex索引文件,这个文件的格式与.index文件格式一样,所记录的东西是消息发布时间与offset的稀疏索引,用于消息定期删除使用。

下图是一个分段索引的例子

这套机制是建立在offset是有序的;索引文件被映射到内存中,所以查找的速度还是很快的。一句话,Kafka的Message存储采用了分区(Parition)、分段(segment)和稀疏索引这几个手段来达到高效发布和随机读取。

5、消费端设计

出于性能、容灾方面的考虑,实际需求是有多Consumer消费一个Topic的情况;由于多个Consumer之间是相互独立的,可以采用竞争Parition上岗的方式进行消费,同一个时刻只有一个Consumer在消费一个Parition,多个Consumer之间定期同步offset状态;如果是需要多通道消费,可以竞争不同的Parition对应资源上岗消费。

由于Kafka是按照offset进行读取的,一般的client都封装成:给定一个起始offset后续不停的get就可以顺序读取了,没有消费确认的概念,Kafka也不会维护每个消息、每个Consumer的状态。其实实现一套消费确认机制也不难,这需要我们实现一个proxy层,在proxy层保留一个循环缓冲区,业务端消费确认后方可从缓冲区里面移除,如果一段时间没有确认,下次来取的时候重复下发下去,类似于tcp滑动窗口的概念。

Kafka——性能逆天的存在相关推荐

  1. Kafka性能强于RabbitMQ的原因

    目录 一.Kafka VS RabbitMQ 1.衡量指标 2.结论 二.Kafak的高吞吐和低延迟是怎么实现的? 1.页缓存技术+磁盘顺序写 2.零拷贝技术 三.关于页缓存.磁盘顺序写.Socket ...

  2. Kafka 性能调优实战:同等资源配置性能提升 20 几倍的秘诀

    作者 | 丁威       责编 | 欧阳姝黎 抛出问题 笔者最近在折腾数据异构体系,在实现MySQL增量数据同步到MQ(Kafka.RocketMQ),本文的故事就从这里开始. 众所周知,为了提高写 ...

  3. kafka性能优化入门

    当我们谈论 Kafka 性能调优时,需要考虑很少的配置参数.因此,为了提高性能,最重要的配置是控制磁盘刷新速率的配置. 此外,我们可以根据组件划分这些配置.因此,让我们先谈谈Producer.因此,在 ...

  4. Kafka性能篇:为何Kafka这么快?

    『码哥』的 Redis 系列文章有一篇讲透了 Redis 的性能优化 --<Redis 核心篇:唯快不破的秘密>.深入地从 IO.线程.数据结构.编码等方面剖析了 Redis " ...

  5. 行业:DP2.0接口性能逆天,但想要普及还很难

    行业:DP2.0接口性能逆天,但想要普及还很难 桑殆充谈论科技 关注作者 获得积分 关注 2021-02-26 09:32 迈拓维矩MT-801UK-L kvm切换器8口usb高清VGA显示器鼠标键盘 ...

  6. 为什么kafka性能非常高

    使用到零拷贝技术 属于linux操作系统内核自带: 顺序读写 分区模型架构 生产者投递消息 批量投递模型 消息压缩 详细谈到解读: 生产者 生产者先将消息投递给缓冲区 (Map集合 key=topic ...

  7. kafka性能高的影响因素

    1.使用操作系统的页缓存 kafka的性能非常依赖于操作系统的页缓存,页缓存提供了比kafka进程内存更好的缓存方式. 2.零拷贝(linux的sendfile函数,对应FileChannel.tra ...

  8. Kafka性能压测完整版

    1.压测方案 1.1 压测目的 本次性能测试在正式环境下单台服务器上Kafka处理MQ消息能力进行压力测试.测试包括对Kafka写入MQ消息和消费MQ消息进行压力测试,根据不同量级的消息处理结果,评估 ...

  9. Kafka性能基准测试、Kafak生产者吞吐量测试、Kafka消费者吞吐量测试、BenchMark 10

    前言_BenchMark BenchMark是一个系统性能的测量工具,也可以看做是一种评价方式 主要测试负载的执行时间.传输速度.吞吐量.资源占用率等 对系统进行性能基准测试后,将得到基准数据作为性能 ...

最新文章

  1. (四)Asp.net web api中的坑-【api的返回值】
  2. python使用spark_apache spark - 在python中导入pyspark
  3. Codeforces 1375H Set Merging (分块)
  4. 经典C语言程序100例之六
  5. MPEG2、H.263、H.264协议效率对比
  6. linux 命令行 浏览器_3个用于Linux命令行的Web浏览器
  7. linux工具-journalctl查询日志
  8. 《南溪的目标检测学习笔记》——性能优化的学习笔记
  9. PRML笔记 第一章 Introduction
  10. 基于 LoadRunner 实现企业级服务器端性能测试的实践
  11. 全网首发:安卓GLSurfaceView绘制显示YUV(NV21)
  12. 常规英文字体 电商_最强电商美工逆袭系列1——最全的电商字体应用详解
  13. 大数据处理与分析---课程总结
  14. 模拟CMOS集成电路设计 学习笔记(三)
  15. [ERROR] [MY-012576] [InnoDB] Unable to create temporary file; errno: 30
  16. 干货 | 京东云部署Wordpress最佳实践
  17. 异常检测中的浅层模型与深度学习模型综述(A Unifying Review of Deep and Shallow Anomaly Detection)
  18. 绘声绘影2023简体中文版新功能介绍
  19. Win10怎么默认用Windows照片查看程序打开图片
  20. Linux git环境搭建和常用指令--推送至Github为例

热门文章

  1. python有关迭代器和生成器的面试题_python面试题之生成器迭代器
  2. python 两个列表相互映射_零基础同学,一看就会的Python字典操作指南
  3. python size和count_groupby 的妙用(注意size和count)
  4. 如何使用MySQL进行备份?
  5. 解决H5的a标签的download属性下载service上的文件/图片出现跨域问题
  6. PCL之点云配准--ICP
  7. Qt窗口部件——对话框QDialog
  8. Web程序员如何入门以太坊开发
  9. 完整仿写鸿洋WanAndroid网站客户端
  10. iOS - OC 与 Swift 互相操作