导语:疫情期间,为了保障国内学子的正常学习进度,积极响应国家"停工不停学"的号召,紧急上线疫情期间专用的"老师极速版",使广大师生足不出户,即可快速便捷的完成线上开课。面对线上课堂百万量级的互动消息,如何保证消息的实时性和准确性无疑是一个技术挑战。那么如何解决问题呢?接下来,就和小编一起来看看腾讯云中间件CKafka如何为腾讯课堂百万级消息提供技术支撑。(编辑:中间件小Q妹)

背景

两年前,腾讯在线教育部就在探索如何实现架构转型。在梳理过腾讯课堂初始技术架构的痛点后,规划出架构演进的三个重点方向:微服务、中间件、DevOps。尤其在消息中间件的选取上,从自研Hippo消息队列切换到云CKafka。这主要归于以下几点原因:

· 实现技术栈的统一,降低组件适配成本。

· 使用符合开源标准的组件,便于系统切换优秀的开源组件。

· CKafka具备高性能、高可用性和高可靠性的特点:免除复杂的参数配置,提供专业的性能调优;磁盘高可靠,即使服务器坏盘50%也不影响业务;多副本备份,更有多可用区容灾方案可选,零感知服务迁移。

· CKafka提供安全的数据保障:提供鉴权与授权机制、主子账号等功能,为企业数据做好安全防护。

在刚刚过去的2019年,腾讯在线教育部已全面实现了业务上云,不仅提升了团队研发效率,还实现了快速交付。同时,CKafka在消息流处理上的高性能特点得以实践验证。

而现在,疫情当前,面对全国千万师生同时在线的线上课堂,互动消息猛增至百万级别,无疑对在线教育平台的稳定性提出更高要求。为了保证线上课堂广大师生的稳定互动,CKafka作为腾讯课堂的底层消息支撑,在消息的实时性和可靠性上提供了更优化的技术方案。

腾讯课堂在线课程页面

CKafka在腾讯课堂的实践

Ckafka在腾讯课堂系统架构中的应用是非常典型的场景,即消息总线和业务解耦。使用了GB带宽、TB存储规格的实例。我们先来看一下CKafka作为消息总线在腾讯课堂的架构中所处的位置,如下图:

从架构图可知,CKafka处于消息管道的中心位置。同时接收多个消息源数据,等待下游组件的订阅消费。并利用其自身高分布式、高吞吐、高可靠的特性,实现流量削峰和业务解耦。腾讯课堂中的聊天消息、签到、举手、献花、答题卡等功能都使用了该能力。

在线课堂的业务场景不允许出现如消息延迟、数据丢失等情况,否则就会立刻被在线课堂的师生们感知业务的不稳定,造成不良的用户体验。我们来假设一个场景:老师在课堂发布一个问题,学生们举手回答问题,如果老师发出的消息出现延时或丢失的情况,学生们就不能收到消息,无法及时给老师反馈问题答案,线上课堂的互动效果就会很差,严重影响课堂教学质量。

如何避免上述问题呢?我们从CKafka保障消息的实时性和可靠性两方面进行阐述。

消息的实时性

Apache Kafka架构上设计的底层数据读写和存储是以分区为最小单位进行的。首先来看一下Kafka Topic的生产消费模型。

如上图所示,生产者将数据写入到分布在集群内不同节点的不同分区上,一个或多个消费者从多台Borker的分区上消费订阅数据。

从这个模型可知,如果数据的读写都集中在单个分区上,则Topic的的所有压力都会集中在该分区上,从而落到单台Broker上面。假设单台机器能承受的流量是300MB,则此时以腾讯教育的GB/s的流量规模,则会出现消息处理过慢,会导致消息延时。那怎么办呢?此时就应该提升分区的数量,提高数据处理的并行度,从而将整个topic的压力均分到多台机器上。

这时就会有一个疑问,Topic需要多少分区合适呢?是不是越多的分区越好呢?

影响分区数量的因素

从生产者的角度来看,数据向不同的分区写入是完全并行的;从消费者的角度来看,并发数完全取决于分区的数量(如果 consumer 数量大于 分区 数量,则必有 consumer 闲置)。因此选取合适的分区对于发挥 CKafka 实例的性能十分重要。

Topic的分区数量是由多种因素决定的,一般可以根据以下几个因素综合考虑:

· 生产者的峰值带宽

假设单机单partiton的生产消费吞吐各自最高为300,峰值生产带宽是900MB,则单纯生产至少需要3个Partiton。

· 消费者的峰值带宽

有人可能会觉得消费的峰值带宽应该等于生产的峰值带宽。这样是不对的。生产者只会生产一份数据,但是可以有N个消费者消费同一份数据,则此时消费带宽=N*生产带宽。 另外如果是离线计算,可能会在某一时刻,消费历史所有数据,此时消费带宽可能会远远高于生产带宽。 此时如果Topic只设计3个分区就有问题了。假设消费峰值带宽是生产带宽的2倍。则此时至少需要6个分区。

· 消费者的处理能力

假设创建了6个分区。此时6个分区最多只会有6个消费者,每个消费者最多每秒可以从Kafka Server拉到300MB的数据。但是每个消费者因为还需处理业务逻辑的关系,只能消费100MB的数据,这样就会容易导致出现消费堆积的情况。 为了增大消费能力,则需要多加入消费者。因为Kafka的consumer group机制里同一个消费组里同一个分区只能被一个消费者消费。所以,就应该增大分区的数量。为满足如上需求,此时至少需要18个分区,18个消费者,才能满足消费需求。

在上面的Case中,分区数的设计也需要存在一定的冗余,因为很多情况下,性能是无法达到最优的。所以,分区数量需要综合考虑多个因素,可以适当的多一点分区数量,以提高实例的性能。但也不能太大,太大也会导致一系列的其他问题。

选取合适的分区数量

考虑到上面提到的实际因素,是否有一个相对简单的判断方法来设计分区数量呢?

在理想情况下,可以通过如下公式来判断分区的数目:

Num = max( T/PT , T/CT ) = T / min( PT , CT )

其中,Num 代表分区数量,T 代表目标吞吐量,PT 代表生产者写入单个 分区 的最大吞吐,CT 代表消费者从单个分区消费的最大吞吐。则分区数量应该等于 T/PT 和 T/CT 中的较大值。

在实际情况中,生产者写入分区的最大吞吐 PT 的影响因素和批处理的规模、压缩算法、确认机制、副本数等有关。消费者从单个分区消费的最大吞吐 CT 的影响因素和业务逻辑有关,需要在不同场景下实测得出。

通常建议分区的数量一定要大于等于消费者的数量来实现最大并发。 如果消费者数量为5,则分区的数目也应该 ≥ 5 的。但需要注意的是:过多的分区会导致生产吞吐的降低和选举耗时的增加,因此也不建议过多分区。

提供如下信息供参考:

1. 单个分区是可以实现消息的顺序写入的。

2. 单个分区只能被同消费者组的单个消费者进程消费。

3. 单个消费者进程可同时消费多个分区,即分区限制了消费端的并发能力。

4. 分区越多,当Leader节点失效后,其他分区重新进行Leader选举的耗时就会越长。

5. 分区的数量是可以动态增加的,只能增加不能减少。但增加会出现消息 rebalance 的情况。

在上述方法的基础上,我们还综合考虑了腾讯课堂的生产消费峰值带宽、消费的行为特征和单个消费者的消费能力等因素,为其设计了合理的分区数量,以满足其对消息实时性的要求。

消息的可靠性

消息的可靠性从不同的角度看是不一样的。从Apache Kafka自身角度看来,消息的可靠性是消息的可靠存储。从业务的角度来看,消息的可靠性是指消息传输、存储、消费的可靠性。

从服务提供商来看,我们希望消息的可靠性是站在客户这一边的,即可靠的传输,存储,消费。CKafka在做好可靠性存储的基础上,还从配置调优、异常告警等方面尽量做到消息的可靠传输和消费。

关于副本

在介绍下面的方案前,我们先聊聊一下副本。为什么要有副本的存在呢?

在分布式的场景下,数据损坏和机械故障是被认为常见事件。数据副本是指在不同节点上持久化同一份数据,当某一个节点上存储的数据丢失时,可以从副本上读取该数据,这是解决分布式系统数据丢失问题最为有效的方法。

那么我们来思考下:有多少个副本的数据才是安全的?理论上2个副本就可以大概率范围的保证数据安全,但是当两个副本都损坏时,数据也会丢失,此时就需要更多的副本,或者需要副本跨可用区、跨地域分布。当然更多的副本就意味着要存储更多的数据,需要更高的成本投入。所以用户需要在冗余和安全之间权衡出一种平衡。这也是腾讯云上创建topic需要用户指定副本数量的原因,如下图:

服务端的可靠性

假设TopicA有3个分区,每个分区有三个副本。来看一下如下的Topic分区分布示意图。

如图所示,三个分区和三个副本均匀的分布在三个Broker中,每台Broker分布了一个分区的Leader分区。从上一节关于副本的描述可知,除非所有的Broker在同一时间挂掉,否则即使同时挂掉2台Borker,服务也可以正常运行。而在我们当前的运营架构中,三台broker同时挂掉的概率微乎其微,当然如果真的出现这种情况,那就是整个机房挂掉了。

为了避免整个机房挂掉的情况,腾讯云Ckafka也可以配置跨机房容灾和跨可用区容灾,来保证数据的可靠性。关于跨可用区容灾相关的技术点可以查阅:。

我们可以通过参数配置来尽可能的保证可靠性传输和消费,用告警来做兜底策略,让研发感知介入处理。下面来看一下生产和消费端的参数调优。

客户端参数调优

生产的可靠传输,主要来看一下如下三个配置: ack、retries。

· ack

Kafka producer 的 ack 有 3 种机制,分别说明如下:

-1:Broker 在 leader 收到数据并同步给所有 ISR 中的 follower 后,才应答给 Producer 继续发送下一条(批)消息。 这种配置提供了最高的数据可靠性,只要有一个已同步的副本存活就不会有消息丢失。

0:生产者不等待来自 broker 同步完成的确认,继续发送下一条(批)消息。这种配置生产性能最高,但数据可靠性最低(当服务器故障时可能会有数据丢失) 。

1:生产者在 leader 已成功收到的数据并得到确认后再发送下一条(批)消息。这种配置是在生产吞吐和数据可靠性之间的权衡(如果leader已死但是尚未复制,则消息可能丢失)

用户不显式配置时,默认值为1。如果是需要可靠性要求高的,建议设置为-1。设置为-1会影响吞吐的性能。

· retries

请求发生错误时重试次数,建议将该值设置为大于0,失败重试最大程度保证消息不丢失。

消费的稳定,看一下以下配置,主要避免重复消费和频繁的消费组Rebalance:

· auto.offset.reset

表示当Broker端没有offset(如第一次消费或 offset超过7天过期)时如何初始化 offset。earliest:表示自动重置到 分区 的最小 offset

latest:默认为 latest,表示自动重置到分区的最大 offset

none:不自动进行 offset 重置,抛出 OffsetOutOfRangeException 异常

默认值为latest。当设置为earliest的时候,需要注意的是:当offset失效后,就会从现存的最早的数据开始消费的情况,可能会出现数据重复消费的情况。

· session.timeout.ms

使用 Kafka 消费分组机制时,消费者超时的时间。当 Broker 在该时间内没有收到消费者的心跳时,就会认为该消费者发生故障,Broker 发起重新 Rebalance 过程。目前该值的在 Broker 的配置必须在group.min.session.timeout.ms=6000和group.max.session.timeout.ms=300000 之间。

· heartbeat.interval.ms

使用 Kafka 消费分组机制时,消费者发送心跳的间隔。这个值必须小于 session.timeout.ms,一般小于它的三分之一。

· max.poll.interval.ms

使用 Kafka 消费分组机制时,再次调用 poll 允许的最大间隔。如果在该时间内没有再次调用 poll,则认为该消费者已经失败,Broker 会重新发起 Rebalance 把分配给它的分区 分配给其他消费者。

参数调优只能最大程度保证服务的可用,并不能保证服务的百分百可用。客户端需要具有捕获生产,消费等行为异常的行为。当出现异常时,能够告警,以便人工处理。这样才能最大的保证业务的高可用。

CKafka的其他优势

CKafka除了作为消息管道帮助业务实现数据解耦、流量削峰外,还可以在其他场景有所作为。

日志分析系统

CKafka 结合大数据套件 EMR,可构建完整的日志分析系统。首先通过部署在客户端的 agent 进行日志采集,并将数据聚合到消息队列 CKafka,之后通过后端的大数据套件如 Spark 等进行数据的多次计算消费,并且对原始日志进行清理,落盘存储或进行图形化展示。

流数据处理平台

CKafka 结合流计算 SCS , 可用于实时/离线数据处理及异常检测,满足不同场景需要:

1. 对实时数据进行分析和展示,并做异常检测,快速定位系统问题。

2. 消费历史数据进行落盘存储和离线分析,对数据进行二次加工,生成趋势报表等。

结语

腾讯云CKafka作为高性能、高吞吐量的消息中间件,为千万师生有序稳定的线上课堂提供了性能支撑,有效的解决了数据的实时性和可靠性问题。特别是在业务故障时,可实现快速扩缩容,并以其全面的容错机制和故障处理机制为用户提供解决方案。

在2020年突如其来的疫情期间,CKafka将与腾讯课堂一起努力,为莘莘学子们百万级的课堂互动消息做好技术支撑,为构建良好的线上课堂体验贡献一份力量。

作者简介

许文强, 腾讯云中间件消息队列资深研发工程师。腾讯云Ckafka核心研发,拥有多年分布式系统研发经验。主要负责腾讯云CKafka定制化开发及优化工作。专注于Kafka在公有云多租户和大规模集群场景下的性能分析和优化。

可消费消息数量_战疫情!CKafka助力腾讯课堂百万消息实现稳定互动相关推荐

  1. kafka消费并导出_如何使用Docker内的Kafka服务?消息服务测试实践篇

    背景及系统简介: Kafka是一种高吞吐量的分布式架构的发布订阅消息系统,它可以处理消费者在网站中的所有动作流数据.通常由于高吞吐量的要求而选择通过处理日志数据和日志聚合来解决. 本文涉及的分布式系统 ...

  2. 微信服务通知消息找回_如何通过微信第三方平台群发服务号消息通知?

    在公众号后台可以群发功能实现,第三方平台可以用微号帮功能服务号每月400次群发实现,服务号每个月可以群发400次消息,但每个粉丝每月只能收到4次消息,不可突破微信规则.本功能主要为微信服务号实现千人千 ...

  3. python windows 消息通讯_如何使用python與windows中的事件/消息掛鈎

    in short: i want to intercept suspend/standby messages on my laptop, but my program doesn't receives ...

  4. 完了!生产事故!几百万消息在消息队列里积压了几个小时!

    分享一个大神的人工智能教程.零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到人工智能的队伍中来!点击浏览教程 一.面试题 如何解决消息队列的延时以及过期失效问题?消息队列满了以后该怎么处理?有几 ...

  5. kafka消息消费有延迟_消息中间件选型分析---从Kafka与RabbitMQ的对比来看全局

    有很多网友留言:公司要做消息中间件选型,该如何选?你觉得哪个比较好?消息选型的确是一个大论题,实则说来话长的事情又如何长话短说.对此笔者专门撰稿一篇内功心法:如何看待消息中间件的选型,不过这篇只表其意 ...

  6. 可消费消息数量_17 个方面,综合对比 主流消息队列

    一.资料文档 二.开发语言 三.支持的协议 四.消息存储 五.消息事务 六.负载均衡 七.集群方式 八.管理界面 九.可用性 十.消息重复 十一.吞吐量TPS 十二.订阅形式和消息分发 十三.顺序消息 ...

  7. rabbitmq 不同的消费者消费同一个队列_消息队列王者--rabbitMQ深入理解--工作过程、消费模式、持久化等...

    概述 之前已经对rabbitMQ的一些基本概念做了介绍和不同MQ之间的比较,今天主要对rabbitMQ的一些方面做扩展. 01 消息队列 Broker:简单来说就是消息队列服务器实体. Exchang ...

  8. kafka消息消费有延迟_注意了!Kafka与RabbitMQ千万不要乱用…

    作为一个有丰富经验的微服务系统架构师,经常有人问我,应该选择 RabbitMQ 还是 Kafka? 图片来自 Pexels 基于某些原因, 许多开发者会把这两种技术当做等价的来看待.的确,在一些案例场 ...

  9. 多线程顺序消费MySQL数据_关于MQ的几件小事(五)如何保证消息按顺序执行

    1.为什么要保证顺序 消息队列中的若干消息如果是对同一个数据进行操作,这些操作具有前后的关系,必须要按前后的顺序执行,否则就会造成数据异常.举例: 比如通过mysql binlog进行两个数据库的数据 ...

最新文章

  1. 简单linux蠕虫,清除Linux系统上的蠕虫程序Ramen
  2. spring在WEB中的应用。
  3. 怎么使用继承的一个实例
  4. Cannot call sendError() after the response has been committed
  5. (一)低功耗设计目的与功耗的类型
  6. 【Java】接口(interface)VS抽象类
  7. JavaScript中用var和不用var的区别
  8. C语言正函数nosign,Function declarations(函数声明)
  9. pku 2387 Til the Cows Come Home
  10. java native方法_深入理解Java虚拟机
  11. Java语言分为三大平台:JavaSE、JavaEE、JavaME
  12. 嵌入式培训学哪些?嵌入式软件开发入门教程
  13. 使用HttpURLConnection 越过ssl证书访问htts协议接口
  14. 金融行业市场占有率超五成,ZDNS筑牢金融科技网络根基
  15. Abnormal Activity Detection Using Pyroelectric Infrared Sensors
  16. 省赛选拔-A 警察抓小偷
  17. 我炸了!前有4个月造抖音,现有3天造百度!!!
  18. 九月份研究生开学之前计划
  19. app/config 中的配置说明
  20. TanGo 免费版 安装方法

热门文章

  1. C++开发即时通讯软件,需要注意什么?
  2. 虽然有失落的即时通讯
  3. 通过怒气系统的hongjin2
  4. 年轻人不通人情世故的C++短处中
  5. 网络游戏中网络模块浅析
  6. 一种被忽视的构造和整数溢出重现
  7. 分分钟甩Word几条街,Python编辑公式竟可以如此简单,你都知道吗?
  8. 聊聊 Python 调用 JS 的几种方式,你都知道吗?
  9. java类的实现程序_java – 如何在另一个类中实现处理程序?
  10. c++矩阵连乘的动态规划算法并输出_算法交流: 7215 简单的整数划分问题 【2.7基本算法之算法效率】...