文档章节

高性能消息队列 CKafka 核心原理介绍(上)

腾讯云加社区
 腾讯云加社区
发布于 2017/09/11 15:45
字数 2907
阅读 20
收藏 0
点赞 0
评论 0

欢迎大家关注腾讯云技术社区,我们将为大家推荐技术精品文章哦~

作者:闫燕飞

1.背景

Ckafka是基础架构部开发的高性能、高可用消息中间件,其主要用于消息传输、网站活动追踪、运营监控、日志聚合、流式处理、事件追踪、提交日志等等需要高性能的场景,,目前已经上线腾讯云。Ckafka完全兼容现有的Kafka协议,使现有Kafka用户可以零成本迁入Ckafka。Ckafka基于现有的Kafka进行了扩展开发和优化,为了方便用户理解Ckafka本文也将对Kafka的实现原理进行较为详细的介绍。

2.Kafka原理

2.1 Kafka诞生背景

Kafka是一种高吞吐量的采用发布订阅模式的分布式消息系统,最初由LinkedIn采用Scala语言开发,用作LinkedIn的活动流追踪和运营系统数据处理管道的基础。现已成为Apache开源项目,其主要的设计目标如下:

  1. 以时间复杂度为O(1)的方式提供消息持久化能力,即使对TB级以上的数据也能保证常数时间复杂度的访问性能。注:其实对于写Kafka的确保证了O(1)的常数时间性能。但对于读,是segment分片级别对数O(logn)时间复杂度。
  2. 高吞吐率。Kafka力争即使在非常廉价的商用机上也能做到单机支持100Kqps的消息传输能力。
  3. 支持Kafka Server间的消息分区(partition),及分布式消费,同时保证每个partition内的消息顺序传输。注:其实Kafka本身实现逻辑并不做该保证,主要的算法是集中在消费者端,由消费者的分配算法保证,详情下面会介绍。
  4. 同时支持离线数据处理和实时数据处理。
  5. 支持在线水平扩展,Kafka的水平扩展主要来源于其分区(partition)的设计理念。

2.2 主流消息队列对比

  RabbitMQ RocketMQ CMQ Kafka
模式 发布订阅 发布订阅 传统queue/发布订阅 发布订阅
同步算法 GM 同步双写 Raft ISR(Replica)
分布式扩展 支持 支持 支持
堆积能力 磁盘容量 磁盘容量 磁盘(水平扩展) 磁盘(水平扩展)
性能 很高
可靠性 一般 一般 极高 一般
持久化 内存/硬盘 磁盘 磁盘 磁盘

2.3 架构

2.3.1 整体架构图

2.3.2 相关概念介绍

2.3.2.1 zookeeper集群

Kafka系统强依赖的组件。其存储了Kafka核心原数据 (如topic信息配置、broker信息、 消费分组等等,相当于DB充当了Kafka的配置管理中心) 。 Kafka的leader选举(如coordinator选举、controller选举、partition leader选举等等),同样也会借助于zookeeper。

2.3.2.2 coordinator

coordinator协调器模块,主要用来管理消费分组和消费offset,充当中介管理消费者并从消费分组中选举出一个消费者作为leader,然后将消费分组中所有消费者信息发往该leader由该leader负责分配partition。该模块为Kafka 0.9版本新加入的新的模块,Kafka集群中可以存在多个协调器分别管不同的消费分组,提高整个系统的扩展能力,主要用于解决之前消费者(high level消费者api)都需要通过与zookeeper连接进行相关的选举,导致zookeeper压力大、惊群及脑裂问题。

2.3.2.3 controller

controller模块,主要负责partition leader选举、监听创建及删除Topic事件然后下发到指定broker进行处理等功能,整个Kafka集群中只能有一个controller,Kafka利用zookeeper的临时节点特性来进行controller选举。

2.3.2.4 Broker

消息缓存代理,Kafka集群包含一个或多个服务器,这些服务器被称为Broker,负责消息的存储于转发,作为代理对外提供生产和消费服务。

2.3.2.5 Topic

消息主题(类别),逻辑上的概念,特指Kafka处理的消息源的不同分类,用户可以根据自己的业务形态将不同业务类别的消息分别存储到不同Topic。用户生产和消费时只需指定所关注的topic即可,不用关注该topic的数据存放的具体位置。

2.3.2.6 Partition

Topic物理上的分组,在创建Topic时可以指定分区的数量,每个partition是一个有序的队列,按生产顺序存储着每条消息,而且每条消息都会分配一个64bit的自增长的有序offset(相当于消息id)。Partition是整个Kafka可以平行扩展的关键因素。

2.3.2.7 Replication

副本,topic级别的配置,可以理解为topic消息的副本数。Kafka 0.8版本加入的概念,主要目的就是提高系统的可用性。防止broker意外崩溃导致部分partition不可以服务。

2.3.2.8 ISR

In-Sync Replicas ,Kafka用来维护跟上leader数据的broker列表,当leader崩溃后,优先从该列中选举leader

2.3.2.9 Producer

Producer 生产者,采用Push方式进行消息发布生产。Producer可以通过与zookeeper连接获取broker信息, topic信息等等元数据,然后再与broker交互进行消息发布。在此过程中zookeeper相当于一个配置管理中心(类似于Name Server提供相关的路由信息)。采用直接向Producer暴露zookeeper信息存在以下两个非常大的弊端:

  1. zookeeper属于整个Kafka系统的核心结构,其性能直接影响了整个集群的规模,故当暴露给生产者过多的生产者会导致zookeeper性能下降最终影响整个Kafka集群的规模和稳定性。
  2. zookeeper存储着Kafka的核心数据,若公开暴露出去则容易受到恶意用户的攻击,最终导致Kafka集群不可服务,故非常不建议Kafka服务提供方向使用者暴露zookeeper信息。

正因为存在上面的问题,Kafka也提供了Metadata RPC,通过该RPC生产者可以获取到broker信息、topic信息以及topic下partition的leader信息,然后生产者在访问指定的broker进行消息生产,从而对生产者隐藏了zookeeper信息使的整个系统更加安全、稳定、高效。

2.3.2.10 Consumer

消费者,采用Pull方式,从Broker端拉取消息并进行处理。当采用订阅方式(一般通过使用consumer high level api或new consumer来进行订阅)订阅感兴趣的Topic时,Consumer必须属于一个消费分组,而且Kafka保证同一个Topic的一条消息只能被同一个消费分组中的一个Consumer消费,但多个消费分组可以同时消费这一条消息。

其实Kafka本身不对这个(同一个topic的一条消息只能被同一个消费分组中一个消费者消费)做任何保证,尤其是在0.9版本之前Kafka Broker根本都没有消费分组的概念也没有消费offset概念,Kafka只是提供FetchMessage RPC供使用者去拉取消息,至于是谁来取,取多少次其根本不关心,该保证是由消费者api内部的算法自己完成。

在0.9版本之前消费分组只是消费者端的概念,同一个消费分组的所有消费者都通过与zookeeper连接注册,然后自主选择一个leader(一个消费分组一个leader),再通过该leader进行partition分配(分配算法默认是range,也可以配置成round robin甚至自己实现一个算法非常的灵活)。所有消费者都按照约定访问分配给自己的partition,并且可以选择将消费offset保持在zookeeper或自己存。该方式会暴露zookeeper从而导致存在和暴露zookeeper给Producer一样的问题,并且因为任何一个消费者退出都会触发zookeeper事件,然后重新进行rebalance,从而导致zookeeper压力非常大、而且还存在惊群及无法解决的脑裂问题,针对这个问题0.9版本(含)之后,Kafka Broker添加了coordinator协调器模块。

但coordinator模块也未进行任何分配算法相关的处理,只是替换了zookeeper的一些功能,充当了中介将之前消费者都要通过zookeeper自己选择leader, 变成统一和coordinator通信,然后由coordinator选择leader,然后将同一个消费分组中的消费者都发送给leader(消费者api),由leader负责分配。另一个方面就是coordinator当前多了管理offset的功能,消费者可以选择将offset提交给coordinator,然后由coordinator进行保存,当前默认情况下coordinator会将offset信息保存在一个特殊的topic(默认名称_consumer_offsets)中,从而减少zookeeper的压力。消费分组中partition的分配具体可以看下一个小结中消费分组的相关说明。

2.3.2.11 Consumer Group

消费分组,消费者标签,用于将消费者分类。可以简单的理解为队列,当一个消费分组订阅了一个topic则相当于为这个topic创建了一个队列,当多个消费分组订阅同一个topic则相当于创建多个队列,也变相的达到了广播的目的,而且该广播只用存储一份数据。 为了方便理解,通过下面的图片对消费分组相关概念进行讲解。

  1. 一个消费分组可以订阅多个topic,同理一个topic可以被多个消费分组订阅
  2. topic中的partition只会分配给同一个消费分组中的一个消费者,基于这种分配策略,若在生产消息时采用按照消息key进行hash将同一个用户的消息分配到同一partition则可以保证消息的先进先出。Kafka正是基于这种分配策略实现了消息的先进先出。
  3. 同一个消费分组中,不同的消费者订阅的topic可能不一样,但Kafka的partition分配策略保证在同一个消费分组的topic只会分配给订阅了该topic的消费者,即消费分组中会按照topic再划分一个维度。以上图为例Consumer group1中C1和C2同时订阅了Topic 1所以将Topic1下面的P0 ~ P3四个partition均分给C1和C2。同样Consumer group1中只有C1订阅了Topic0故Topic0中的两个partition只分配给了C1未分配给C2。

2.3.2.12 Message

消息,是通信和存储的最小单位。其包含一个变长头部,一个变长key,和一个变长value。其中key和value是用户自己指定,对用户来说是不透明的。Message的详细格式下面会有介绍,这里先不展开说明。

下一篇:《高性能消息队列 CKafka 核心原理介绍(下)》

相关阅读

Raft 算法原理及其在 CMQ 中的应用(上)

Raft 算法原理及其在 CMQ 中的应用(下)

消息队列 CMQ 七大功能实践案例

此文已由作者授权腾讯云技术社区发布,转载请注明文章出处
原文链接:https://www.qcloud.com/community/article/549934
获取更多腾讯海量技术实践干货,欢迎大家前往腾讯云技术社区

© 著作权归作者所有

共有 人打赏支持
腾讯云加社区
粉丝 79
博文 99
码字总数 244836
作品 0
深圳
闫燕飞:Kafka的高性能揭秘及优化

欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文首发在云+社区,未经许可,不得转载。 大家下午好,我是来自腾讯云基础架构部ckafka团队的高级工程师闫燕飞。今天在这里首先...

腾讯云加社区 ⋅ 05/03 ⋅ 0

干货满满,腾讯云+社区技术沙龙 Kafka Meetup 深圳站圆满结束

云加社区技术沙龙 发表于腾讯云技术沙龙订阅 56 干货满满,腾讯云+社区技术沙龙 Kafka Meetup 深圳站圆满结束 云+导语:4月22日,由腾讯云和 Kafka 社区主办、开源中国协办的腾讯云+社区技术...

腾讯云加社区 ⋅ 04/25 ⋅ 0

互联网技术栈 『Contents Catalog』

image.png 编程语言 Java书单——由入门到上天 UML-类间关系 Java解读-ThreadLocal详解与应用 并发编程-Concurrent用户指南 Java并发编程-原子性变量 Java 并发工具包-常用线程池 基于事件驱...

高广超 ⋅ 2017/11/03 ⋅ 0

腾讯云Kafka海量服务自动化运营实践

腾讯云CKafka是基于Apache Kafka 的分布式、高可扩展以及高吞吐的云端Kafka服务。腾讯云CKafka针对开源Kafka进行了多种优化,其中包括无锁队列优化、异步刷盘优化、多版本支持以及GC优化等优...

腾讯架构师 ⋅ 05/02 ⋅ 0

架构师必备词汇和知识点

01 高可用 负载均衡(负载均衡算法) 反向代理 服务隔离 服务限流 服务降级(自动优雅降级) 失效转移 超时重试(代理超时、容器超时、前端超时、中间件超时、数据库超时、NoSql超时) 回滚机...

t4i2b10X4c22nF6A ⋅ 2017/11/24 ⋅ 0

看过的书籍

疯狂java讲义(讲得比较细,对全面了解jdk有很大帮助) 疯狂android讲义(当时要做android,买了这本书) oracle从入门到精通(系统讲oracle使用) 精通div+css网页样式与布局(程序员在样式方...

rock912 ⋅ 2016/01/21 ⋅ 0

架构设计思路

前言 我们一般在做架构设计的时候,会经历过三个阶段:需求分析、概要设计和详细设计。 需求分析阶段: 主要梳理所有用例(Use case)和场景,并抽象出面向系统的用户与角色,梳理出需求提供哪...

6776jkjk ⋅ 2017/11/19 ⋅ 0

分布式异步编程框架--Koper

Koper Koper是一个基于消息和事件驱动的分布式异步编程框架, Koper的设计目标是为大型场景提供高性能高吞吐的简单编程方案。 Koper为分布式环境提供了简化的消息监听和数据事件监听模型,它...

raymondkk ⋅ 2016/11/18 ⋅ 1

FastDev/OF.Notify

#OF.Notify 一、项目描述 本项目是希望提供一个高可用、分布式、大容量、高性能、支持动态扩容的消息队列,目前很多的消息队列很多要么是单节点的,要么 是基于数据分片实现的比如kafka,无法...

FastDev ⋅ 2016/05/30 ⋅ 0

Android Handler异步通信:深入详解Handler机制源码

前言 在开发的多线程应用场景中,机制十分常用 今天,我将手把手带你深入分析 机制的源码,希望你们会喜欢 目录 1. Handler 机制简介 在多线程的应用场景中,将工作线程中需更新的操作信息 ...

carson_ho ⋅ 05/21 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

那些证书相关的玩意儿(SSL,X.509,PEM,DER,CRT,CER,KEY,CSR,P12等)

之前没接触过证书加密的话,对证书相关的这些概念真是感觉挺棘手的,因为一下子来了一大堆新名词,看起来像是另一个领域的东西,而不是我们所熟悉的编程领域的那些东西,起码我个人感觉如此,且很长...

颖辉小居 ⋅ 19分钟前 ⋅ 0

利用有限制通配符提升API灵活性(28)

1、参数化类型是不可变的 List<String> 不是List<Object>的子类,但是二者是有联系的 利用有限制的通配符类型处理类似情况 List<? extends Object>(生产者) Collection<? super E>(消费者......

职业搬砖20年 ⋅ 25分钟前 ⋅ 0

ssm框架 +bootstrap分页

这里有两种方式 方式一:自己写分页 方式二:使用插件PageHelper 1.自己写分页 1.1 效果 1.2 实现过程 1.2.1 创建分页公共类 //---------------------------1.属性-------------------------...

Lucky_Me ⋅ 32分钟前 ⋅ 0

Istio

helm template install/kubernetes/helm/istio --name istio --namespace istio-system > $HOME/istio.yaml after $ kubectl create namespace istio-system$ kubectl create -f $HOME/ist......

openthings ⋅ 33分钟前 ⋅ 0

内核线程、轻量级进程、用户线程

线程与进程概念 在现代操作系统中,进程支持多线程。 进程是资源管理的最小单元; 线程是程序执行的最小单元。 即线程作为调度和分配的基本单位,进程作为资源分配的基本单位 一个进程的组成...

117 ⋅ 38分钟前 ⋅ 0

elasticsearch2.4.6升级为elasticsearch-5.5.0的经历

将elasticsearch-5.5.0 中的配置 path.data 指向原来的数据路径 即 path.data: /usr/local/src/elasticsearch-2.4.6/data 注意: elasticsearch-5.5.0 需要将jdk版本升级到1.8...

晨猫 ⋅ 38分钟前 ⋅ 1

lvm讲解 磁盘故障小案例

1

oschina130111 ⋅ 42分钟前 ⋅ 0

那些提升开发人员工作效率的在线工具

本文转载自公众号 Hollis 作为一个Java开发人员,经常要和各种各样的工具打交道,除了我们常用的IDE工具以外,其实还有很多工具是我们在日常开发及学习过程中要经常使用到的。 Hollis偏爱使用...

时刻在奔跑 ⋅ 55分钟前 ⋅ 0

restful风格 实现DELETE PUT请求 的web.xml的配置

import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframe......

泉天下 ⋅ 今天 ⋅ 0

Shell数组

Shell数组 Shell在编程方面比Windows批处理强大很多,无论是在循环、运算。 bash支持一维数组(不支持多维数组),并且没有限定数组的大小。类似与C语言,数组元素的下标由0开始编号。获取数...

蜗牛奔跑 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部