当前位置: 首页 > news >正文

4.3-中间件之Kafka

一、初识Kafka

什么是Kafka?

Kafka是一种分布式的,基于发布 / 订阅的一个消息系统。在没有Kafka之前,系统架构是一个“蜘蛛网”模型,用户A在网站上发表了一条动态,这条数据需要被送到无数个地方:

  • 写入主数据库
  • 更新搜索索引,让其他人能搜到
  • 更新用户画像,用于推荐系统
  • 发送通知给他的粉丝
  • 生成数据报表,给运营看

这样设计数据库会被系统不停的轮询,压力巨大,此外数据容易不一致且耦合严重,要修改一个接口需要牵一发动全身。

所以Kafka的设计目标就是:

目标一:高吞吐量

  • ​含义​:每秒钟能处理海量的消息(目标是百万级/秒)。

  • ​必要性:这是 Kafka 诞生的首要原因。要作为整个公司数据的“中枢神经系统”,必须能承受所有系统产生的数据洪流。

  • ​如何实现​:

    • ​顺序读写磁盘​:即使使用廉价的机械硬盘,也能获得极高的吞吐。

    • ​批量处理​:生产/消费都采用批量操作,减少网络I/O和系统调用次数。

    • ​零拷贝技术​:优化数据在内核态和用户态之间的传输路径。

目标二:可扩展性

  • ​含义​:系统容量可以通过增加普通的硬件来线性提升。

  • 必要性:业务是增长的,数据量是指数级增加的,系统必须能轻松地水平扩展。

  • ​如何实现​:

    • ​分区模型​:每个 Topic 可以被划分为多个 Partition,这些 Partition 可以分散到不同的服务器上。增加服务器就能增加整体容量。

    • ​无状态 Broker​:Kafka 的 broker(kafka集群中的一台服务器) 本身不记录消费者的状态,使得增删 broker 变得简单。

目标三:持久化与可靠性

  • ​含义​:消息一旦被写入 Kafka,就不能丢失,并且可以被多次、长时间地消费。

  • ​必要性​:Kafka 的定位不仅是消息队列,更是实时的、分布式的提交日志。数据是公司的资产,绝对不能丢。

  • ​如何实现​:

    • ​消息直接持久化到磁盘​:而不是先存内存,再刷盘,避免了断电丢失消息的风险。

    • ​多副本机制​:每个 Partition 的数据都有多个副本,分散在不同机器上,防止单点故障。

目标四:松耦合与实时性

  • ​含义​:让数据生产者无需关心谁用数据、何时用数据,同时保证数据能被实时消费。

  • ​必要性​:这是解耦系统的关键。生产方和消费方独立发展、独立伸缩,互不影响。

  • ​如何实现​

    • ​发布-订阅模型​:生产者发送消息到 Topic,多个消费者组可以独立订阅同一个 Topic。

    • ​消费者拉取模式​:消费者自己控制消费节奏,不会因为消费能力慢而拖垮生产者和 Kafka 服务本身。

    • ​消息保留策略​:数据会持久保存一段时间(可配置),允许新的消费者随时接入并消费历史数据。

二、kafka高吞吐量的实现

kafka的划分很细,即使对 TB 级以上数据也能保证常数时间复杂度的访问性能,依赖于其中的各个部分:有Topic    Partition    Segment索引文件    Segment数据文件    offset值

各部分的理解:

  • Kafka是一个图书馆
  • Topic是一个图书大类(如“少儿图书”类)
  • partition是这个大类下的书架(如 一个作者一个书架)
  • segment是书架的一层(关键),也是kafka文件存储的最小单位
  • 索引文件和数据文件就是书架里面存放的书,一个负责查找,一个负责记录
  • offset即书的页码,也是查找的关键。
| --topic1-0        topic1的0号分区| --00000000000000000000.index    segment  文件| --00000000000000000000.log    后缀分表表示 Segment 索引文件和数据文件。| --00000000000000368769.index| --00000000000000368769.log| --00000000000000737337.index| --00000000000000737337.log| --00000000000001105814.index| --00000000000001105814.log
| --topic2-0
| --topic2-1

查找流程:假设要查找页码(offset)为368772 的内容(消息)

  • 在根据查找消息的key确定他的“书架分区”partition
  • 到指定书架前,每一层的编号,用的是这一层存放的起始页码,比如第一层存放(1-10000)第二层(10001-20000)...
  • 利用二分查找定位368772 所在的层号
  • 取出对应层里面的目录(索引文件),这个目录是稀疏的,只稀疏记录了页码(offset)1从第0个字符开始读,页码(offset)3从第497个字符开始读....(而这条消息的全局页码(offset)是 368769 + 3 = 368772
  • 直接从这一层的数据文件的497字符开始读取

总结:找索引文件利用二分查找,找文件中对应的消息,利用偏移量和索引文件中的稀疏索引。

 Kafka 高性能很重要的原因:

  1. 顺序磁盘 IO 存储设计,写在log数据文件里面的消息都是顺序的(kafka将生产者发送的消息攒成一批,顺序追加到数据文件末尾),这种顺序磁盘IO快于随机读写内存。
  2. PageCache,进程准备读写磁盘前,OS会先查看内容是否读取到PageCache上,如果命中,则可以避免磁盘IO
  3. 零拷贝,​从磁盘读取消息,然后原封不动地通过网络发送给消费者。这样可以减少一半的拷贝操作,避免了内核缓冲区读到用户缓冲区,然后用户缓冲区再写回到内核缓冲区   的两次拷贝操作。只需要从磁盘读出到内核缓冲区,然后直接从内核缓冲区发送到网卡。(DMA负责)

三、kafka可扩展性的实现

Kafka一个很重要的特性就是,只需写入一次消息,可以支持任意多的应用读取这个消息。一个应用如果看作一个消费组,然后消费组里对应多个消费者,每一个消费者可以与一个Topic里面的分区对应。如果该应用消费能力不足,那么可以考虑在这个消费组里增加消费者。如果应用需要读取全量消息,那么就为该应用设置一个消费组。

消费者可以1:n个分区,但是如果消费者数量>分区数量,多余的消费者会空闲,因为一个分区不支持同一个消费组里的多个消费者消费,所以对应的Topic里面的分区应该多一些。

zookeeper的作用:注册服务发现,标识各broker的ip。

    四、kafka可靠性保证

    1.保证消息不丢失:生产者确认 + 服务端多副本冗余 + 消费者手动提交

    • 生产者设置 acks 参数:acks=all​:需分区的 leader 以及 follower的确认。
      acks=0,则不等broker返回,提供了最低延迟,但是最不安全。
      acks=1,等待分区的leader落盘成功后返回ACK
    • broker采用多副本机制,消费者什么时候能读取消息?LEO和HW

            HW标识了消费者可以读取的消息的位置,也就是主副分区中,更新消息最慢的分区的位置

            LEO标记的是主分区的最新消息的位置

    • 消费者在消费完毕后,再提交偏移量offset
      如果是自动提交offset,比如1s一次,可能会导致丢失数据,因为可能1s还没有处理完数据
      如果是手动提交offset,丢数据情况对于消费者一般不存在,但是无法避免重复消费(拉取)的情况,即消费者消费完但是没有提交offset就宕机了,需要重复消费。最大限度避免重复消费的办法就是  同步提交消息,这样最多重复消费一条消息。

    五、kafka的策略

    生产者消息的分区分配策略:

    • 如果消息有指明分区号,之前归入对应分区。
    • 如果没有指明分区号,但是消息带有对应的key值,Hash(key) % 分区数后,放入对应分区
    • 没有指明分区也没有key,顺序轮询各个分区均匀放入。

    消费者的分区分配策略:(消费组数量<分区)

    • 整除分配,分区数/消费者数为消费者分配到的分区数,但是当无法整除的时候,不能实现均匀分配
    • 轮询分配,把分区号按字典排序后,顺序轮询消费者分配。但是当各个消费者订阅的Topic不同的时候,无法实现均匀分配
    • 粘性分配,首先按轮询分配对分区进行分配,但有一个关键改进:​它严格遵循消费者的订阅信息。而且在出现有消费者C1脱离了消费组的情况下,进行分区重定向的时候,按照轮询只把C1的分区分给其余消费者,遵循尽量少的移动。

    kafka的rebalance策略

    当消费组的成员发生变更,有消费者加入或者有消费者宕机,或者消费者无法在规定时间内完成消费,会触发rebalance机制。

    session.timeout.ms表示消费者向broker发生心跳的超时时间,一般大于3*发送心跳的时间间隔

    max.poll.interval.ms表示每两次消费的时间间隔,也就是一次消费时长,如果超过这个时间,会认为消费者死了,会进行rebalance

    http://www.dtcms.com/a/469667.html

    相关文章:

  • 方寸之间见天地:新兴高端印章的当代破局与价值重构
  • 如何改善基于深度学习的场重构
  • Maven 进行项目构建settings.xml 配置教程
  • 磁力搜索网站怎么做的网站和app设计区别
  • 西安网站建设公司都有哪些网站设计开发文档模板下载
  • C++设计模式_结构型模式_桥接模式Bridge
  • 关于flutter插件的存储位置问题
  • 把“Mixed Content”吃干抹净——一次 https→http 踩坑实录
  • 中山大学联合项目 论文解读 | iManip:面向机器人操作的技能增量学习
  • Unity:Json笔记——Json文件格式、JsonUtlity序列化和反序列化
  • 第八章 惊喜15 小萍收获初会
  • RabbitMQ基础知识与Spring Boot 3.x集成案例
  • 租房网站建设多少钱网站域名怎么改
  • Redis CPU高负载案例分析
  • ARMv9 CCA机密计算架构演进技术解析:重塑云原生时代的数据安全基石
  • 湖州网站设计浙北数据最新发布的手机有哪些
  • AD加域账号权限设置
  • 解决idea报错:Error running TrustApexCrmApplication. Command line is too long
  • 网站开发淄博进口商品代理平台
  • systme V共享内存(version1)
  • 万网网站制作wordpress投稿管理系统
  • python(47) : 快速截图[Windows工具(2)]
  • VSCODE GDB调试
  • 江西企业网站定制wordpress网页效果
  • CCF-GESP 等级考试 2024年6月认证C++三级真题解析
  • 前端学习1(学习时间:30分钟简单)
  • vlan范围
  • 北京顺义做网站编程正规学校有哪几所
  • 跨平台向量库:Linux Windows 上一条龙部署 PostgreSQL 向量扩展
  • 基于YOLO与DeepSort的高效行人跟踪算法研究