看完就入门系列!吞吐量消息持久化负载均衡和持久化伸缩性…… 你真的了解 Kafka 了吗?
Posted CSDN云计算
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了看完就入门系列!吞吐量消息持久化负载均衡和持久化伸缩性…… 你真的了解 Kafka 了吗?相关的知识,希望对你有一定的参考价值。
作者| liuhehe123
来源| CSDN博客 责编| Carol
出品| CSDN云计算(ID:CSDNcloud)
封图| CSDN下载于视觉中国
无论是已经接触过 Kafka 还是刚入坑的小伙伴,都应该时不时回头了解一下 Kafka ,有时候会有不少新收获。今天这份 Kafka 的介绍,建议再认真阅读一遍哦~
Kafka在设计之初就考虑的问题:
吞吐量/延时
消息持久化
负载均衡和持久化
伸缩性
kafka是如何做到高吞吐量和低延时的呢?
kafka的写入操作是很快的,这主要得益于它对磁盘的使用方法不同。虽然kafka会持久化所有数据到磁盘,但本质上每次写入操作其实都只是把数据写入到操作系统的页缓存中,然后由操作系统自行决定什么时候把页缓存中的数据写回磁盘。
先说kafka是咋实现的,kafka依靠下列4点达到了高吞吐量、低延时的设计目标:
大量使用操作系统叶缓存,内存操作速度快且命中率高。
kafka不直接参与物理I/O操作,而是交给最擅长此事的操作系统来完成。
采用追加写入的方式,摒弃了缓慢的磁盘随机读写操作。
使用以sendfile为代表的的零拷贝技术加强网络间的数据传输效率。
前三个都是使用页缓存的好处,页缓存是在内存中分配的,所以写入消息很快。使得kafka不必直接与底层文件系统打交道。另外采用追加的方式写入,避免了磁盘随机写操作。
零拷贝:
简而言之,就是避免让CPU做大量的数据拷贝技术,采用不使用CPU时间的技术进行系统内核缓冲区之间的数据拷贝。
从上图中可以看出,共产生了四次数据拷贝,即使使用了DMA来处理了与硬件的通讯,CPU仍然需要处理两次数据拷贝,与此同时,在用户态与内核态也发生了多次上下文切换,无疑也加重了CPU负担。
1、让数据传输不需要经过user space
我们减少拷贝次数的一种方法是调用mmap()来代替read调用:
buf = mmap(diskfd, len);
write(sockfd, buf, len);
应用程序调用mmap(),磁盘上的数据会通过DMA被拷贝的内核缓冲区,接着操作系统会把这段内核缓冲区与应用程序共享,这样就不需要把内核缓冲区的内容往用户空间拷贝。应用程序再调用write(),操作系统直接将内核缓冲区的内容拷贝到socket缓冲区中,这一切都发生在内核态,最后,socket缓冲区再把数据发到网卡去。
2、sendfile
使用sendfile不仅减少了数据拷贝的次数,还减少了上下文切换,数据传送始终只发生在kernel space。下图为使用DMA的sendfile零拷贝技术图。
消息持久化
kafka是要持久化消息的,而且要将消息持久化到磁盘上的。
先说这样做的好处(为什么要持久化):
解耦消息发送与消息消费:通过将消息持久化使得生产者不再需要直接和消费者方耦合,它只是简单地把消息生产出来并交由kafka服务器保存起来即可。
实现灵活的消息处理(便于消息重演):很多kafka下游子系统(消费方)都会有这样的需求——对于已经处理过的消息可能在未来的某个时间点重新处理一次,即所谓的消息重演(message replay)。
那么kafka持久化是咋做的呢?
对比一下:
普通的系统实现持久化时可能先尽量使用内存,当内存资源耗尽时,再一次性地把数据 “刷盘”;kafka则反其道行之,所有数据都会立即被写入到文件系统的持久化日志中,之后kafka服务器才会返回结果给客户端,通知客户端消息写入成功。这样做即实时保存了数据,又减少了kafka程序对于内存的消耗,从而将节省出的内存留给页缓存使用,进一步提升整体性能。
这里解释下:kafka在吞吐量中说使用页缓存,持久化又说尽量减少对内存的消耗,这是咋回事?
总的来说,Kafka不会保持尽可能多的内容在内存空间,而是尽可能把内容直接写入到磁盘。所有的数据都及时的以追加的方式写入到文件系统的持久化日志中,而不必要把内存中的内容刷新到磁盘中。
负载均衡和故障转移
kafka作为一个完备的分布式系统,肯定也是要满足负载均衡和故障转移处理操作的。
负载均衡:kafka的负载均衡是通过智能化的分区领导者选举来实现的。可以在集群中的所有机器上以均等的机会分散各个partition的leader,从而整体上实现了负载均衡。【后面进行补充】
故障转移(使用zookeeper):即当服务器意外中止时,整个集群能够快速检测到他失效了,并立即将该服务器上的应用或服务转移到其他机器上。kafka使用的是会话机制来解决的。每台kafka服务器启动后会以会话的形式把自己注册到zookeeper服务器上,一旦该服务器运转出现问题,与zookeeper的会话便不能维持从而超时失效,此时kafka会选举出一台新的服务器赖万全代替这台服务器继续提供服务。
伸缩性
伸缩性指的是:向分布式系统系统中增加额外的计算资源时提升吞吐量的能力。
如果服务器是无状态的,状态的保存和管理交给专门的协调服务来做,比如 zookeeper ,那么整个集群的服务器之间就不需要再进行繁重的状态共享,这极大地降低了维护复杂度。
Kafka 正式采用了这一思想——每台kafka的服务器上的状态统一交由Zookeeper保管。而扩展kafka集群就很容易:启动一台新的kafka服务器即可。
需要说明的一点是,kafka服务器并不是所有状态都不保存,他只是保存了很轻量级的内部状态,所以整个集群间维护状态一致性的代价很低。
来看看kafka的基本概念和术语
目前kafka最新的版本是 2.4。
1、broker、topic、partition、offset、replica、leader和follower
下面是Kafka的大致架构图:
Kafka服务器官方称呼为:broker。
先来说说Kafka的消息格式是啥样的?
消息由三部分组成:消息头部、key 和 value。
消息头:包括CRC码、消息版本、属性、时间戳、键长度和消息体长度等信息。
Key: 消息键, 对消息做partition时使用,即决定消息被保存在某个topic下的那个partition。
Value:消息体,保存实际的消息数据。
Timestamp: 消息发送时间戳。
2、kafka的Topic和Partition 到底是个什么东西?
Topic(主题): topic代表了一类消息,也可以认为消息被发送到的地方。比如业务A使用一个topic, 业务B使用另外一个topic。相当于 柴鸡蛋和茶叶蛋这样简单分下。
Partition(分区) 以上是关于看完就入门系列!吞吐量消息持久化负载均衡和持久化伸缩性…… 你真的了解 Kafka 了吗?的主要内容,如果未能解决你的问题,请参考以下文章 activeMQ能不能配置多个实例的负载均衡,并只连接一个MySQL,将消息持久化存入到一个数据库中?