关于物联网:高度可扩展EMQX-50-达成-1-亿-MQTT-连接

5次阅读

共计 4162 个字符,预计需要花费 11 分钟才能阅读完成。

摘要

物联网设施连贯和部署规模的不断扩大,对物联网音讯平台的可扩展性和健壮性提出了更高的要求。为了确认云原生分布式 MQTT 音讯服务器 EMQX 的性能体现能够充沛满足当今物联网连贯规模的需要,咱们在 23 个节点的 EMQX 集群上建设了 1 亿个 MQTT 连贯,对 EMQX 的可扩展性进行了压力测试。

在本测试中,每个 MQTT 客户端订阅了一个惟一的通配符主题,这比间接主题须要更多的 CPU 资源。音讯公布时,咱们抉择了一对一的发布者 - 订阅者拓扑模型,每秒解决音讯可达 100 万条。此外,咱们还比拟了在应用两个不同的数据库后端——RLOG DB 和 Mnesia 时,最大订阅率如何随着集群大小的减少而变动。本文将具体介绍测试状况以及在此过程中面临的一些挑战。

背景介绍

EMQX 是一个高度可扩大的分布式开源 MQTT 音讯服务器,基于 Erlang/OTP 平台开发,可反对数百万并发客户端。因而,EMQX 须要在集群节点之间长久化和复制各种数据,如 MQTT 主题及其订阅者、路由信息、ACL 规定、各种配置等等。为满足此类需要,从公布起,EMQX 就始终采纳 Mnesia 作为数据库后端。

Mnesia 是基于 Erlang/OTP 的嵌入式 ACID 分布式数据库,应用全网状点对点 Erlang 散发来进行事务协调和复制。这一个性使其在程度扩大方面存在艰难:节点越多,复制的数据就越多,写入工作协调的开销就越大,呈现脑裂场景的危险也越大。

在 EMQX 5.0 中,咱们尝试通过一个新的数据库后端类型——RLOG(Replication Log)来缓解此问题,其采纳 Mria 实现。作为 Mnesia 数据库的扩大,Mria 定义了两种类型的节点来帮忙其进行程度扩大:一种是外围节点,其行为与一般的 Mnesia 节点一样,参加写入事务;另一种是复制节点,不参加事务处理,将事务处理委托给外围节点,同时在本地保留数据的只读正本。因为参加其中的节点较少,这使得脑裂危险大大降低,并且缩小了事务处理所需的协调。同时,因为所有节点都能够本地读取数据,能够实现只读数据的快速访问。

为了可能默认应用这个新的数据库后端,咱们须要对其进行压力测试,验证其的确可能很好地进行程度扩大。咱们建设了一个 23 节点的 EMQX 集群,放弃 1 亿个并发连贯,在发布者和订阅者之间平分,并以一对一的形式公布音讯。此外,咱们还将 RLOG DB 后端与传统的 Mnesia 后端进行了比拟,并确认了 RLOG 的达到率确实比 Mnesia 更高。

测试方法

咱们应用了 AWS CDK 来进行集群测试的部署和运行,其能够测试不同类型和数量的实例,还能够尝试应用 EMQX 的不同开发分支。感兴趣的读者能够在这个 Github 仓库中查看咱们的脚本。咱们在负载生成器节点(简称“loadgens”)中应用了咱们的 emqtt-bench 工具生成具备各种选项的连贯 / 公布 / 订阅流量,并应用 EMQX 的 Dashboard 和 Prometheus 来监控测试的进度和实例的健康状况。

咱们用不同实例类型和数量进行了逐个测试。在最初几次测试中,咱们决定对 EMQX 节点和 loadgen 应用 c6g.metal 实例,对集群应用”3+20”拓扑,即 3 个参加写入事务的外围节点,以及 20 个为只读正本并将写入委托给外围节点的复制节点。至于 loadgen,咱们察看到发布者客户端须要的资源要远多于订阅者。如果仅连贯和订阅 1 亿个连贯,只须要 13 个 loadgen 实例;如果还须要进行公布,则须要 17 个。

在这些测试中未应用任何负载均衡器,loadgen 间接连贯到每个节点。为了让外围节点专门用于治理数据库事务,咱们没有建设到这些外围节点的连贯,每个 loadgen 客户端都以均匀分布的形式间接连贯到每个节点,因而所有节点的连接数和资源应用状况大致相同。每个订阅者都订阅了 QoS 为 1 的 bench/%i/# 模式的通配符主题,其中 %i 代表每个订阅者的惟一编号。每个发布者都以 QoS 1 公布了 bench/%i/test 模式的主题,其中 %i 与订阅者的 %i 雷同。这确保了每个发布者都只有一个订阅者。音讯中的无效负载大小始终为 256 字节。

在测试中,咱们首先连贯了所有订阅者客户端,而后才开始连贯发布者。只有在所有发布者都连贯后,它们才开始每 90 秒进行一次音讯公布。在本文报告的 1 亿连贯测试中,订阅者和发布者连贯到 broker 的速率为 16000 连贯 / 秒,不过咱们置信集群能够放弃更高的连贯速率。

测试中遇到的挑战

在对如此量级的连贯和吞吐量进行试验的过程中,咱们遇到了一些挑战并据此进行了相干考察,使性能瓶颈失去了改善。system_monitor 为咱们跟踪 Erlang 过程中的内存和 CPU 应用状况提供了很大帮忙,它能够称得上是“BEAM 过程的 htop”,让咱们可能找到具备长音讯队列、高内存和 / 或 CPU 使用率的过程。在集群测试期间察看到状况之后,咱们利用它在 Mria 中进行了一些性能调优[1] [2] [3]。

在应用 Mria 进行的初始测试中,简略地说,复制机制基本上是要将所有事务记录到由复制节点订阅的一个暗藏的表中。这实际上在外围节点之间产生了一些网络开销,因为每个事务实质上都是“复制的”。在咱们 fork 的 Erlang/OTP 代码中,咱们增加了一个新的 Mnesia 模块,使咱们可能更轻松地捕捉所有提交的事务日志,不须要“复制”写入,大大减少了网络应用,让集群放弃更高的连贯和事务处理速率。在进行了这些优化后,咱们进一步对集群进行了压力测试,并发现了新的瓶颈,须要进一步的性能调优[4] [5] [6]。

即便是咱们的招牌测试工具也须要进行一些调整能力解决如此大量的连贯和连贯速率。为此咱们进行了一些品质改良 [7] [8] [9] [10] 和性能优化[11] [12]。在咱们的公布 - 订阅测试中,甚至专门建设了一个分支(不在以后的骨干分支中),以便进一步升高内存的应用。

测试后果

下面的动画展现了一对一公布 - 订阅测试的最终后果。咱们建设了 1 亿个连贯,其中 5000 万是订阅者,另外 5000 万是发布者。通过每 90 秒公布一次音讯,咱们能够看到均匀入站和出站速率达到了每秒 100 万条以上。在公布高峰期,20 个复制节点(这些节点是连贯的节点)中的每一个节点在公布过程中均匀用到 90% 的内存(约 113GiB)和约 97% 的 CPU(64 个 arm64 内核)。处理事务的 3 个外围节点应用 CPU 较少(使用率不到 1%),并且只应用了 28% 的内存(约 36GiB)。256 字节无效负载的公布过程中须要的网络流量在 240MB/s 到 290 MB/s 之间。在公布高峰期,loadgen 须要简直全副内存(约 120GiB)和整个 CPU。

留神:在这个测试中,所有配对的发布者和订阅者碰巧都在同一个 broker 中,这并不是一个非常靠近事实用例的现实场景。目前 EMQX 团队正在进行更多的测试,并将继续更新停顿。

为了将 RLOG 集群与等效的 Mnesia 集群进行比拟,咱们应用了另一种总连接数较少的拓扑:RLOG 应用 3 个外围节点 +7 个复制节点,Mnesia 集群应用 10 个节点,其中 7 个节点进入连贯。咱们以不同速率进行连贯和订阅,不进行公布。

下图展现了咱们的测试后果。对于 Mnesia,连贯和订阅节点的速度越快,察看到的“扁平化”行为就越多,即集群无奈达到目标最大连接数,在这些测试中,指标最大连接数为 5000 万。而对于 RLOG,咱们能够看到它可能达到更高的连贯速率,而集群不会体现出这种扁平化行为。由此咱们能够得出结论,应用 RLOG 的 Mria 在连贯速率较高的状况下比咱们过来采纳的 Mnesia 后端性能体现更好。

结语

通过一系列测试并取得这些令人满意的后果之后,咱们认为 Mria 提供的 RLOG 数据库后端可在 EMQX 5.0 中投入使用。它曾经成为以后主分支中的默认数据库后端。

References

[1] – fix(performance): Move message queues to off_heap by k32 · Pull Request #43 · emqx/mria

[2] – perf(replicant): Improve performance of the agent and the replicant by k32 · Pull Request #44 · emqx/mria

[3] – fix(mria_status): Remove mria_status process by k32 · Pull Request #48 · emqx/mria

[4] – Store transactions in replayq in normal mode by k32 · Pull Request #65 · emqx/mria

[5] – feat: Remove redundand data from the mnesia ops by k32 · Pull Request #67 · emqx/mria

[6] – feat: Batch transaction imports by k32 · Pull Request #70 · emqx/mria

[7] – feat: add new waiting options for publishing by thalesmg · Pull Request #160 · emqx/emqtt-bench

[8] – feat: add option to retry connections by thalesmg · Pull Request #161 · emqx/emqtt-bench

[9] – Add support for rate control for 1000+ conns/s by qzhuyan · Pull Request #167 · emqx/emqtt-bench

[10] – support multi target hosts by qzhuyan · Pull Request #168 · emqx/emqtt-bench

[11] – feat: bump max procs to 16M by qzhuyan · Pull Request #138 · emqx/emqtt-bench

[12] – feat: tune gc for publishing by thalesmg · Pull Request #164 · emqx/emqtt-bench

版权申明:本文为 EMQ 原创,转载请注明出处。

原文链接:https://www.emqx.com/zh/blog/reaching-100m-mqtt-connections-with-emqx-5-0

正文完
 0