高性能Kafka

一.概述

消息队列模式:

  • 点对点: 1:1。就是一个队列只能由一个消费者进行消费,这个消费者消费完毕就把消息进行删除,不会再给别的消费者。只能消费者拉消息。
  • 发布/订阅: 1:多
  • 消息队列主动推送消息。
    • 缺点:推送速率难以适应消费速率,不知道消费者的处理效率,造成浪费。
  • 消费方主动从消息队列拉取消息。
    • 缺点:消息延迟(比如每隔2秒进行拉取,就会造成2秒的延迟),每一个消费方都处于忙循环,一直检测有没有消息。(kafka)
    • kafka改进:使用长轮询:消费者去 Broker 拉消息,定义了一个超时时间,也就是说消费者去请求消息,如果有的话马上返回消息,如果没有的话消费者等着直到超时,然后再次发起拉消息请求。不会频繁的进行拉取。

什么是Kafka?

  • 是一个分布式的基于发布订阅模式的消息队列,主要应用于大数据实时处理领域,天然分布式。

二.Kafka基础架构

高性能Kafka
  • Producer :消息生产者,就是向 kafka broker 发消息的客户端;
  • Consumer :消息消费者,向 kafka broker 取消息的客户端;
  • Consumer Group (CG):消费者组,由多个 consumer 组成。一个消费者组消费一个topic,消费者组的每一个消费者消费一个或多个Partition。
  • Broker :一台 kafka 服务器就是一个 broker。一个集群由多个 broker 组成。一个 broker 可以容纳多个 topic。
  • Topic :可以理解为一个队列,生产者和消费者面向的都是一个 topic;
  • Partition:为了实现扩展性,一个非常大的 topic 可以分布到多个 broker(即服务器)上, 一个 topic 可以分为多个 partition(每个partition分布在不同的Broker上),每个 partition 是一个有序的队列;
  • Replica:副本,为保证集群中的某个节点发生故障时,该节点上的 partition 数据不丢失,且 kafka 仍然能够继续工作,kafka 提供了副本机制,一个 topic 的每个分区都有若干个副本, 一个 leader 和若干个 follower。
  • leader:每个分区多个副本的主,生产者发送数据的对象,以及消费者消费数据的对象都是 leader。(leader和follower都是Partition,放在不同的Broker中)
  • follower:每个分区多个副本中的从,实时从 leader 中同步数据,保持和 leader 数据的同步。leader 发生故障时,某个 follower 会成为新的 follower。

总结:

topic就相当于Rabbit MQ 的queue,现在把queue进行分区,分为多个Partition。并且一个节点只有一个主Partition。相当于可以把一个消息可以分在不同的机器上的不同主Partition上,最后交给一个消费者组。(也可以理解为把一个topic分为不同的主partition”纵向”放在不同的机器上)。一个topic对应多个消费组,一个消费组可以接受多个的topic。消费者组内每个消费者负责消费不同分区的数据,一个分区只能由一个组内消费者消费。

三.如何保证消息的可靠性

要保证消息不丢失,需要三方面都进行保证:生产者(ISR,ack),消费者(offset),Kafka(持久化,集群(副本同步策略))

生产者:topic 的每个 partition 收到 producer 发送的数据后,都需要向 producer 发送 ack(acknowledgement 确认收到),如果 producer 收到 ack,就会进行下一轮的发送,否则重新发送数据。

要想每一个partition发送ack,就需要每一个partition的follower进行同步才能发送ack。

  • 副本数据同步策略
  • 半数以上完成同步,就发送 ack。

    • 优点:延迟低;缺点:选举新的 leader 时,容忍 n 台 节点的故障,需要2n+1 个副本
    • 全部完成同步,才发送 ack。(kafka采用)

    • 优点:选举新的 leader 时,容忍 n 台 节点的故障,需要n+1 个副本;缺点:延迟高。

    • AR,ISR,OSR:AR=ISR+OSR
    • ISR:In-Sync Replicas 副本同步队列,存放可以被同步的副本,有些follower同步时超过阈值都会被剔除出ISR(万一有的follower宕机了,不能一直等它吧),存入OSR(Outof-Sync Replicas)列表,新加入的follower也会先存放在OSR中。
    • AR:所有副本
    • ack应答机制:
    • 0:不需要等待ack返回,容易丢失数据。
    • 1:只要Leader收到数据,就进行ack。不需要等待follower都同步完成。当leader没有同步完数据前宕机,丢失数据。
    • -1:等待所有的follower都同步完,再进行ack。会造成数据重复。这时候才认为一条数据被commit了(放心了)。

消费者:由于 consumer 在消费过程中可能会出现断电宕机等故障,consumer 恢复后,需要从故障前的位置的继续消费,所以 consumer 需要实时记录自己消费到了哪个
offset

,以便故障恢复后继续消费。Kafka就是用 offset

来表示消费者的消费进度到哪了,
每个消费者会都有自己的 offset

。说白了 offset

就是表示消费者的
消费进度 。

  • 在以前版本的Kafka,这个offset是由Zookeeper来管理的,后来Kafka开发者认为Zookeeper不合适大量的删改操作,于是把offset在broker以内部topic(__consumer_offsets)的方式来保存起来。
  • 关闭自动提交位移,在消息被完整处理之后再手动提交位移。enable.auto.commit=false
  • LEO:指的是每个副本最大的 offset;如下图,leader最大的LEO到19,其他的follower还没有同步完,leader挂了,有的follower只同步到12,有的同步到15,就会出现消费数据错乱,所以让消费者只能从HW的位置进行消费。这样保证消费数据不会出现错乱。
  • HW:指的是消费者能见到的最大的 offset,ISR 队列中最小的 LEO。

Kafka:Kafka是以
日志文件

进行存储。

高性能Kafka
  • 采用分片机制和索引机制。
  • topic是逻辑上的概念,Partition是物理上的概念。每一个Partition又分为好几个Segment,每一个Segment存放2个文件。.log和.index文件。
  • .index文件存储索引,log文件存储真正的消息,新的消息放在文件尾部。

四.Kafka为什么那么快?Kafka是以日志文件保存在磁盘上,但是效率还是很高,为什么呢?我们来分析它对于读写的优化。

  • 写数据:
  • 顺序写入:Kafka把数据一直追加到文件末端,省去了大量磁头寻址的时间。
  • Memory Mapped Files:mmf 直接利用操作系统的Page来实现文件到物理内存的映射,完成之后对物理内存的操作会直接同步到硬盘。
  • 读数据:
  • 零拷贝:操作系统的文章有讲。
  • 批量发送:Kafka允许进行批量发送消息,producter发送消息的时候,可以将消息缓存在本地,等到了固定条件发送到 Kafka 。
  • 数据压缩:可以通过GZIP或Snappy格式对消息集合进行压缩。压缩的好处就是减少传输的数据量,减轻对网络传输的压力。

五.其他小问题

生产者分区策略:

高性能Kafka
  • 指明Partition的情况下,直接存到指明的Partition值。
  • 没有指明Partition但是有key,将key的hash值与topic的partition数进行取余得到Partition值
  • 轮询:既没有Partition又没有key,第一次调用时随机生成一个整数(后面每次调用在这个整数上自增),将这个值与topic可用的Partititon总数取余得到Partititon值。

消费者分区策略:

  • 分配策略触发条件:当消费者组中消费者个数发生变化(新增消费者/某一个消费者宕机)的时候就会触发分配策略。
  • 轮询:

高性能Kafka
  • Range(默认):按照消费者组进行划分,先算topic组/消费者的个数,按照上面消费数量大的原则进行分配。

高性能Kafka

kafka中的 zookeeper 起到什么作用,可以不用zookeeper么?

  • 早期版本的kafka用zk做元数据信息存储,consumer的消费状态,group的管理以及 offset的值等。考虑到和zk打交道网络的问题,效率不高,就在新版本弱化了zk的依赖。
  • broker依然依赖于ZK,zookeeper 在kafka中还用来选举controller和检测broker是否存活等等。

如果leader crash时,ISR为空怎么办?用如下参数进行调节

  • unclean.leader.election,这个参数有两个值:
  • true(默认):允许不同步副本成为leader,由于不同步副本的消息较为滞后,此时成为leader,可能会出现消息不一致的情况。
  • false:不允许不同步副本成为leader,此时如果发生ISR列表为空,会一直等待旧leader恢复,降低了可用性。

为什么Kafka不支持读写分离?

  • 在Kafka中,生产者写入消息、消费者读取消息的操作都是与 leader 副本进行交互的,从 而实现的是一种主写主读的生产消费模型。
  • Kafka 并不支持主写从读,因为主写从读有 2 个很明显的缺点:
  • 数据一致性问题。数据从主节点转到从节点必然会有一个延时的时间窗口,这个时间 窗口会导致主从节点之间的数据不一致。某一时刻,在主节点和从节点中 A 数据的值都为 X, 之后将主节点中 A 的值修改为 Y,那么在这个变更通知到从节点之前,应用读取从节点中的 A 数据的值并不为最新的 Y,由此便产生了数据不一致的问题。
  • 延时问题。类似 Redis 这种组件,数据从写入主节点到同步至从节点中的过程需要经 历网络→主节点内存→网络→从节点内存这几个阶段,整个过程会耗费一定的时间。而在 Kafka 中,主从同步会比 Redis 更加耗时,它需要经历网络→主节点内存→主节点磁盘→网络→从节 点内存→从节点磁盘这几个阶段。对延时敏感的应用而言,主写从读的功能并不太适用。

Kafka中是怎么体现消息顺序性的?

  • kafka每个partition中的消息在写入时都是有序的,消费时,每个partition只能被每一个group中的一个消费者消费,保证了消费时也是有序的。
  • 整个topic不保证有序。如果为了保证topic整个有序,那么将partition调整为1.

Kafka中最少一次/最多一次/精准一次?

  • at lest once(最少一次):消息不丢,但可能重复。先处理消息,再保存offset。当处理消息的时候宕机,没有存offset,重新消费的时候,再次处理刚才没有处理的消息。但是当存offset的时候宕机,再次消费的时候,重新消费到刚才的消息,造成重复。
  • at most once(最多一次):消息会丢,但不会重复。先保存offset,再处理消息。当处理消息的时候宕机,由于已经保存了offset,重新消费的时候,就不会处理刚才没有处理的消息。但是当保存offset的时候宕机,还没有消费消息,再次消费的时候不会重复。
  • Exactly Once(精准一次):消息不丢,也不重复。
  • 解决方案一:最少一次+幂等性
  • 解决方案二:最多一次+事务

寄语:要偷偷的努力,希望自己也能成为别人的梦想。

Original: https://www.cnblogs.com/monkey-xuan/p/15870875.html
Author: 小猴子_X
Title: 高性能Kafka

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/579548/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • Smartbi绘制表格

    Smartbi操作—绘制报表 实现需求 在需要向数据库中查询一些字段并绘制成一个Excel表格时,可以不需要经过后台写代码,直接通过在Smartbi中写SQL语句查询数…

    Java 2023年6月16日
    091
  • Could not resolve placeholder ‘usp.server.port’ in value “${usp.server.port}”

    我是接触的新项目遇到的这个问题,代码肯定没啥问题(才拷过来的),网上找了很多才发现我这个是个微服务的项目,这个${usp.server.port}表示就去配置中心微服务得到值,搞了…

    Java 2023年6月6日
    051
  • redis基础

    一、介绍 Redis诞生于2009年全称是Remote Dictionary Server,远程词典服务器,是一个基于内存 的键值型NoSQL数据库。 特征: ●键值(key-va…

    Java 2023年6月8日
    078
  • Java Date 和 Calendar

    Java 语言的Date(日期),Calendar(日历),DateFormat(日期格式)组成了Java标准的一个基本但是非常重要的部分。日期是商业逻辑计算一个关键的部分,所有的…

    Java 2023年5月29日
    061
  • Linux中CentOS 7的安装及Linux常用命令

    前言 什么是Linux Linux是一套免费使用和自由传播的操作系统。说到操作系统,大家比较熟知的应该就是Windows和MacOS操作系统,我们今天所学习的Linux也是一款操作…

    Java 2023年6月15日
    095
  • SpringBoot-Web应用安全策略实现

    近期项目上线,甲方要求通过安全检测才能进行验收,故针对扫描结果对系统进行了一系列的安全加固,本文对一些常见的安全问题及防护策略进行介绍,提供对应的解决方案 XSS常发生于论坛评论等…

    Java 2023年6月15日
    083
  • 公众号文章汇总

    JDK源码分析实战系列-ThreadLocal自旋锁-JUC系列Doug Lea文章阅读记录-JUC系列AQS源码一窥-JUC系列AQS源码二探-JUC系列AQS源码三视-JUC系…

    Java 2023年6月14日
    086
  • 消息的种类与消息队列的处理方式

    消息的种类 1.1 按照发送的特点分 同步消息 异步消息 单向消息 举例: 同步消息 我去小吃店要了一套煎饼果子,在门口等了十分钟,煎饼果子好了老板告诉我让我取餐。 异步消息 我去…

    Java 2023年6月14日
    093
  • Jetpack架构组件学习(4)——APP Startup库的使用

    最近在研究APP的启动优化,也是发现了Jetpack中的 App Startup库,可以进行SDK的初始化操作,于是便是学习了,特此记录 原文:Jetpack架构组件学习(4)——…

    Java 2023年6月13日
    0105
  • 解决 Docker Push Skipped foreign layer 的错误

    引言当Docker推送基于Windows镜像到私有仓库的时候会遇到 Skipped foreign layer的问题。 docker push 192.168.2.30:5000/…

    Java 2023年6月15日
    068
  • 注释和良好的编程风格

    注释、良好的编程风格 注释 分类: 单行注&am…

    Java 2023年6月7日
    081
  • 部署-docker安装gitlab

    gitlab简单介绍 gitlab是一个私有的源代码管理系统,提供了web界面给用户进行访问和操作。gitlab存储的仓库是服务端的,需要跟本地的仓库进行配合使用,而本地的仓库管理…

    Java 2023年6月7日
    084
  • 关于非对称加密的一点解说

    非对称加密定义: 非对称加密算法又称 现代加密算&#x6CD5…

    Java 2023年6月16日
    0111
  • Spring Security 源码学习(二): Spring Security自动配置(初始化流程)

    【深度好文】: 「和耳朵」SpringSecurity是如何代理过滤器链的? 1. 自动配置security的bean信息 SpringBoot自动配置实现原理 下面是 Sprin…

    Java 2023年5月30日
    094
  • IDEA05 mybatis插件之MyBatisCodeHelper-Pro

    前提准备: 》IDEA专业版本 1 安装MyBatisCodeHelper-Pro IDEA提供了插件安装功能,可以根据开发需要安装适合的插件 》help -> find a…

    Java 2023年5月30日
    0168
  • HTML&CSS

    Web概念概述、HTML、CSS web概念概述 1.1 JavaWeb 使用Java语言开发基于互联网的项目 1.2 软件架构 C/S: Client/Server 客户端/服务…

    Java 2023年6月6日
    079
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球