kafka全面理解
共 2423字,需浏览 5分钟
·
2020-08-25 23:39
什么是消息队列,它的好处是什么?
解藕
将消息写入消息队列,需要消息的系统自己从消息队列中订阅,从而上游系统不需要做任何修改
例如有上游系统a,它有3个下游系统b,c,d,为了使b,c,d能拿到a的数据,a需要在代码中去调用这3个系统。如果有一天,b不再使用a的数据了或b的接口发生了变化,a还需要修改代码。而使用消息队列,就只管往队列里发送数据,需要的下游自己去队列里取数据即可。
异步
不用同步等待下游将数据处理完,将消息发到消息队列中即可返回,不阻碍主流程。
例如上游系统a是主业务,b,c,d是非主要业务,没有必要同步等待3个下游都返回主业务才继续。使用消息队列可以实现异步,提高吞吐量。
削峰
上游数据有突发流量,下游可能扛不住,kafka在中间可以起到一个缓冲的作用,把消息暂存在kafka中,下游服务就可以按照自己的节奏慢慢处理。
kafka概念
broker
broker是kafka实例。
replication
每一个partition有多副本,当主节点发生故障时,会选择一个副本作为主节点。kafka是主写主读的。
topic
topic是消息的分类,一个topic可以供任意多个消费组消费。
partition
topic的分区,每个topic的数据可以被分成多个partition,可以不在一个机器上,由此来实现kafka的伸缩性。各个partition的数据是不重复的,相同partition的数据是按照发送顺序有序的。任何partition只有一个leader,只有leader是对外提供服务的。leader接收到数据后,follower会不停给他发送请求尝试去拉取最新的数据,拉取到自己本地后,写入磁盘中。每个partition都有多个副本,相同partition的各个副本分布在不同的broker上。
consumer group/consumer
一个consumer group是一个topic的订阅者,一个topic可以被多个consumer group订阅,各个consumer group是相互独立的。一个consumer group内部可以有多个consumer,多个consumer不会消费相同的partition的消息。最多有效的consumer数与partition数相同,如果consumer数多于partition数,那么多出来的consumer不会消费到任何消息。
rebalance
消费组内某个消费者挂掉后,其他消费者自动重新分配订阅topic的partition的过程。rebalance是消费者端实现高可用的重要手段。
kafka的特性
高吞吐、低延迟:kakfa 最大的特点就是收发消息非常快,kafka 每秒可以处理几十万条消息,它的最低延迟只有几毫秒。 高伸缩性:每个主题(topic) 包含多个分区(partition),主题中的分区可以分布在不同的主机(broker)中。 持久性、可靠性:Kafka 能够允许数据的持久化存储,消息被持久化到磁盘,并支持数据备份防止数据丢失,Kafka 底层的数据存储是基于 Zookeeper 存储的,Zookeeper 我们知道它的数据能够持久存储。 容错性:允许集群中的节点失败,某个节点宕机,Kafka 集群能够正常工作 高并发:支持数千个客户端同时读写
kafka为何快
页缓存+顺序写入
kafka 写数据的时候,非常关键的一点,它是以磁盘顺序写的方式来写的。仅仅将数据追加到文件的末尾,不是在文件的随机位置来修改数据。
写入磁盘文件的时候,可以直接写入这个 OS Cache 里,也就是仅仅写入内存中,接下来由操作系统自己决定什么时候把 OS Cache 里的数据真的刷入磁盘文件中。
零拷贝
如果Kafka从磁盘中读取数据发送给下游的消费者,大概过程是:
先看看要读的数据在不在os cache中,如果不在的话就从磁盘文件里读取数据后放入os cache 从操作系统的os cache 里拷贝数据到应用程序进程的缓存里 从应用程序进程的缓存里拷贝数据到操作系统层面的Socket缓存里 从Soket缓存里提取数据后发送到网卡,最后发送出去给下游消费者
整个过程有两次没必要的拷贝
从操作系统的cache里拷贝到应用进程的缓存里 从应用程序缓存里拷贝回操作系统的Socket缓存里。
为了进行这两次拷贝,中间还发生了好几次上下文切换,一会儿是应用程序在执行,一会儿上下文切换到操作系统来执行。
所以这种方式来读取数据是比较消耗性能的
零拷贝
让操作系统的cache中的数据发送到网卡 网卡传出给下游的消费者
中间跳过了两次拷贝数据的步骤,Socket缓存中仅仅会拷贝一个描述符过去,不会拷贝数据到Socket缓存
另外:
从磁盘读数据的时候,会先看看os cache内存中是否有,如果有的话,其实读数据都是直接读内存的。
如果kafka集群经过良好的调优,大家会发现大量的数据都是直接写入os cache中,然后读数据的时候也是从os cache中读。
相当于是Kafka完全基于内存提供数据的写和读了,所以这个整体性能会极其的高