从0开始回顾Kafka---系列三

简介: 消费者只能拉取到这个 offset 之前的消息。

主题与分区

1、Kafka 分区数可以增加或减少吗?为什么?

目前Kafka只支持增加分区数而不支持减少分区数。

为什么不支持减少分区?

  1. 按照Kafka现有的代码逻辑而言,此功能完全可以实现,不过也会使得代码的复杂度急剧增大
  2. 实现此功能需要考虑的因素很多,比如删除掉的分区中的消息该作何处理?如果随着分区一起消失则消息的可靠性得不到保障;如果需要保留则又需要考虑如何保留。直接存储到现有分区的尾部,消息的时间戳就不会递增。如果分散插入到现有的分区中,那么在消息量很大的时候,内部的数据复制会占用很大的资源,而且在复制期间,此主题的可用性又如何得到保障?
  3. 虽然分区数不可以减少,但是分区对应的副本数是可以减少的

2、 kafka中每个分区的消息是有序的吗?每个主题呢?  

每个消息在被追加到分区日志文件的时候都会分配一个特定的偏移量(offset)。

offset 是消息在分区中的唯一标识,Kafka 通过它来保证消息在分区内的顺序性,不过 offset 并不跨越分区,也就是说,Kafka 保证的是分区有序而不是主题有序


其他

1、Kafka如何实现高性能IO?

1、使用批量处理的方式来提升系统吞吐能力。

  • Kafka 的客户端 SDK( 软件开发工具包  ) 在实现消息发送逻辑的时候,采用了异步批量发送的机制。
  • 无论是同步发送还是异步发送,Kafka 都不会立即就把这条消息发送出去。它会先把这条消息,存放在内存中缓存起来,然后选择合适的时机把缓存中的所有消息组成一批,一次性发给 Broker。
  • Broker 整个处理流程中,无论是写入磁盘、从磁盘读出来、还是复制到其他副本这些流程中,批消息都不会被解开,一直是作为一条“批消息”来进行处理的
  • 在消费时,消息同样是以批为单位进行传递的,Consumer 从 Broker 拉到一批消息后,在客户端把批消息解开,再一条一条交给用户代码处理。  

2、基于磁盘文件高性能顺序读写的特性来设计的存储结构。

  • 对于磁盘来说,它有一个特性,就是顺序读写的性能要远远好于随机读写。  因为顺序读写相比随机读写省去了大部分的寻址时间,它只要寻址一次,就可以连续地读写下去,所以说,性能要比随机读写要好很多。  
  •  Kafka  存储设计非常简单,对于每个分区,它把从 Producer 收到的消息,顺序地写入对应的 log 文件中,一个文件写满了,就开启一个新的文件这样顺序写下去。消费的时候,也是从某个全局的位置开始,也就是某一个 log 文件中的某个位置开始,顺序地把消息读出来。
  • Kafka充分利用了顺序读写这个特性,极大提升了 Kafka 在使用磁盘时的 IO 性能。

3、利用操作系统的 PageCache 来缓存数据,减少 IO 并提升读性能。

  • PageCache 是现代操作系统都具有的一项基本特性,相当于操作系统在内存中给磁盘上的文件建立的缓存。
  • Kafka 在读写消息文件的时候,充分利用了 PageCache 的特性。一般来说,消息刚刚写入到服务端就会被消费,按照 LRU 的“优先清除最近最少使用的页”这种策略,读取的时候,对于这种刚刚写入的 PageCache,命中的几率会非常高。
  • 大部分情况下,消费读消息都会命中 PageCache,带来的好处有两个:一个是读取的速度会非常快,另外一个是,给写入消息让出磁盘的 IO 资源,间接也提升了写入的性能。

4、使用零拷贝技术加速消费流程。

ZeroCopy:零拷贝技术:

我们知道,在服务端,处理消费的大致逻辑是这样的:

  • 首先,从文件中找到消息数据,读到内存中;
  • 然后,把消息通过网络发给客户端。

这个过程中,数据实际上做了 2 次或者 3 次复制:

  1. 从文件复制数据到 PageCache 中,如果命中 PageCache,这一步可以省掉;
  2. 从 PageCache 复制到应用程序的内存空间中,也就是我们可以操作的对象所在的内存;
  3. 从应用程序的内存空间复制到 Socket 的缓冲区,这个过程就是我们调用网络应用框架的 API 发送数据的过程。

Kafka 使用零拷贝技术可以把这个复制次数减少一次,上面的 2、3 步骤两次复制合并成一次复制。直接从 PageCache 中把数据复制到 Socket 缓冲区中,这样不仅减少一次数据复制,更重要的是,由于不用把数据复制到用户内存空间,DMA 控制器可以直接完成数据复制,不需要 CPU 参与,速度更快。

2、Kafka如何保证一致性?

一致性指的是什么?

不论是旧的 Leader 还是新选举的 Leader,Consumer 都能读到一样的数据。  

如何解决?

Kafka引入了High Watermark 机制,当我们将隔离级别isolation.level设置为:read_committed时,Kafka会保证所有消费者所消费的消息都是在High Water Mark之下。

所谓High Watermark ,俗称高水位,它标识了一个特定的消息偏移量(offset),消费者只能拉取到这个 offset 之前的消息。


相关文章
|
11月前
|
SQL 关系型数据库 MySQL
MySQL 锁
MySQL里常见的几种锁
170 3
|
消息中间件 存储 数据库
深入学习RocketMQ的底层存储设计原理
文章深入探讨了RocketMQ的底层存储设计原理,分析了其如何通过将数据和索引映射到内存、异步刷新磁盘以及消息内容的混合存储来实现高性能的读写操作,从而保证了RocketMQ作为一款低延迟消息队列的读写性能。
|
10月前
|
存储 数据采集 监控
如何解决取模算法中数据倾斜的问题?
【10月更文挑战第25天】在实际应用中,需要根据具体的数据特点、系统架构和业务需求,选择合适的方法或方法组合来优化取模算法的数据分片效果。
|
存储 Java C++
人人都会的synchronized锁升级,你真正从源码层面理解过吗?
本文结合Jvm源码层面分析synchronized锁升级原理,可以帮助读者从本质上理解锁升级过程,从锁如何存储,存储在哪的疑问出发,一步一步彻底剖析偏向锁,轻量级锁,自旋锁,重量级锁的原理和机制。
人人都会的synchronized锁升级,你真正从源码层面理解过吗?
|
NoSQL 安全 Java
Redis6入门到实战------ 三、常用五大数据类型(字符串 String)
这篇文章深入探讨了Redis中的String数据类型,包括键操作的命令、String类型的命令使用,以及String在Redis中的内部数据结构实现。
Redis6入门到实战------ 三、常用五大数据类型(字符串 String)
|
11月前
|
消息中间件 存储 监控
说说如何解决RocketMq消息积压?为什么Kafka性能比RocketMq高?它们区别是什么?
【10月更文挑战第8天】在分布式系统中,消息队列扮演着至关重要的角色,它不仅能够解耦系统组件,还能提供异步处理、流量削峰和消息持久化等功能。在众多的消息队列产品中,RocketMQ和Kafka无疑是其中的佼佼者。本文将围绕如何解决RocketMQ消息积压、为什么Kafka性能比RocketMQ高以及它们之间的区别进行深入探讨。
369 1
|
监控 关系型数据库 MySQL
在Linux中,mysql的innodb如何定位锁问题?
在Linux中,mysql的innodb如何定位锁问题?
|
缓存 运维 监控
成为工程师 - 如何提升系统稳定性(1)
成为工程师 - 如何提升系统稳定性(1)
|
存储 SQL 关系型数据库
MySQL意向锁是什么?
意向锁用于协调InnoDB存储引擎中的行锁与表锁,避免全表扫描判断行锁的存在,提升性能。主要包括意向共享锁(IS)与意向排他锁(IX),分别在请求行级共享(S)锁与排他(X)锁前加于表级。意向锁自动管理,无需用户干预。例如,事务A锁定一行时先加IS锁,B事务可加IX锁但不能直接加表级X锁。意向锁与行级S/X锁兼容,仅与表级S/X锁冲突。这确保了锁机制高效且减少冲突。
420 0
|
安全 Java 编译器
synchronized同步锁 : 原理到锁升级及历史演进的解析
synchronized同步锁 : 原理到锁升级及历史演进的解析