5

腾讯课堂百万师生同时在线,如何实现消息的稳定互动?

 3 years ago
source link: https://www.infoq.cn/article/FxGp5OLPApuVbaiJDfo8
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

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

引言

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

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

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

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

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

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

而现在,疫情当前,面对全国千万师生同时在线的线上课堂,互动消息猛增至百万级别,无疑对在线教育平台的稳定性提出更高要求。

为了保证线上课堂广大师生的稳定互动,CKafka 作为腾讯课堂的底层消息支撑,在消息的实时性和可靠性上提供了更优化的技术方案。

u6bMvir.jpg!mobile

CKafka 在腾讯课堂的实践

Ckafka 在腾讯课堂系统架构中的应用是非常典型的场景,即消息总线和业务解耦。使用了 GB 带宽、TB 存储规格的实例。

我们先来看一下 CKafka 作为消息总线在腾讯课堂的架构中所处的位置,如下图:

3ErQfub.jpg!mobile

从架构图可知,CKafka 处于消息管道的中心位置。同时接收多个消息源数据,等待下游组件的订阅消费。

并利用其自身高分布式、高吞吐、高可靠的特性,实现流量削峰和业务解耦。腾讯课堂中的聊天消息、签到、举手、献花、答题卡等功能都使用了该能力。

在线课堂的业务场景不允许出现如消息延迟、数据丢失等情况,否则就会立刻被在线课堂的师生们感知业务的不稳定,造成不良的用户体验。

我们来假设一个场景:老师在课堂发布一个问题,学生们举手回答问题,如果老师发出的消息出现延时或丢失的情况,学生们就不能收到消息,无法及时给老师反馈问题答案,线上课堂的互动效果就会很差,严重影响课堂教学质量。

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

消息的实时性

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

6JNZbif.jpg!mobile

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

从这个模型可知,如果数据的读写都集中在单个分区上,则 Topic 的的所有压力都会集中在该分区上,从而落到单台 Broker 上面。

假设单台机器能承受的流量是 300MB,则此时以腾讯教育的 GB/s 的流量规模,则会出现消息处理过慢,会导致消息延时。

那怎么办呢?此时就应该提升分区的数量,提高数据处理的并行度,从而将整个 topic 的压力均分到多台机器上。

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

(1)影响分区数量的因素

从生产者的角度来看,数据向不同的分区写入是完全并行的;从消费者的角度来看,并发数完全取决于分区的数量(如果 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 中,分区数的设计也需要存在一定的冗余,因为很多情况下,性能是无法达到最优的。

所以,分区数量需要综合考虑多个因素,可以适当的多一点分区数量,以提高实例的性能。但也不能太大,太大也会导致一系列的其他问题。

(2)选取合适的分区数量

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

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

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

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

在实际情况中,生产者写入分区的最大吞吐 PT 的影响因素和批处理的规模、压缩算法、确认机制、副本数等有关。

消费者从单个分区消费的最大吞吐 CT 的影响因素和业务逻辑有关,需要在不同场景下实测得出。

通常建议分区的数量一定要大于等于消费者的数量来实现最大并发。如果消费者数量为 5,则分区的数目也应该 ≥ 5 的。

但需要注意的是:过多的分区会导致生产吞吐的降低和选举耗时的增加,因此也不建议过多分区。

提供如下信息供参考:

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

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

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

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

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

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

消息的可靠性

消息的可靠性从不同的角度看是不一样的。

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

从服务提供商来看,我们希望消息的可靠性是站在客户这一边的,即可靠的传输,存储,消费。

CKafka 在做好可靠性存储的基础上,还从配置调优、异常告警等方面尽量做到消息的可靠传输和消费。

(1)关于副本

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

在分布式的场景下,数据损坏和机械故障是被认为常见事件。

数据副本是指在不同节点上持久化同一份数据,当某一个节点上存储的数据丢失时,可以从副本上读取该数据,这是解决分布式系统数据丢失问题最为有效的方法。

那么我们来思考下:有多少个副本的数据才是安全的?

理论上 2 个副本就可以大概率范围的保证数据安全,但是当两个副本都损坏时,数据也会丢失,此时就需要更多的副本,或者需要副本跨可用区、跨地域分布。

当然更多的副本就意味着要存储更多的数据,需要更高的成本投入。所以用户需要在冗余和安全之间权衡出一种平衡。这也是腾讯云上创建 topic 需要用户指定副本数量的原因,如下图:

ZBNbauA.jpg!mobile

(2)服务端的可靠性

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

uIVRBrj.jpg!mobile

如图所示,三个分区和三个副本均匀的分布在三个 Broker 中,每台 Broker 分布了一个分区的 Leader 分区。

从上一节关于副本的描述可知,除非所有的 Broker 在同一时间挂掉,否则即使同时挂掉 2 台 Borker,服务也可以正常运行。

而在我们当前的运营架构中,三台 broker 同时挂掉的概率微乎其微,当然如果真的出现这种情况,那就是整个机房挂掉了。

为了避免整个机房挂掉的情况,腾讯云 Ckafka 也可以配置跨机房容灾和跨可用区容灾,来保证数据的可靠性。关于跨可用区容灾相关的技术点可以点击链接查阅: 《蘑菇街千亿级消息Kafka上云实践》

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

(3)客户端参数调优

生产的可靠传输,主要来看一下如下三个配置: 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 除了作为消息管道帮助业务实现数据解耦、流量削峰外,还可以在其他场景有所作为。

1. 日志分析系统

CKafka 结合大数据套件 EMR,可构建完整的日志分析系统。

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

EFv6FbV.jpg!mobile

2. 流数据处理平台

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

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

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

7rqA3q.png!mobile

结语

腾讯云 CKafka 作为高性能、高吞吐量的消息中间件,为千万师生有序稳定的线上课堂提供了性能支撑,有效的解决了数据的实时性和可靠性问题。

特别是在业务故障时,可实现快速扩缩容,并以其全面的容错机制和故障处理机制为用户提供解决方案。

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

头图:Unsplash

作者:许文强

原文: https://mp.weixin.qq.com/s/wjjA_5o4G9vUTsH5tHxvlA

原文:腾讯课堂百万师生同时在线,如何实现消息的稳定互动?

来源:腾讯云中间件 - 微信公众号 [ID:gh_6ea1bc2dd5fd]

转载:著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK