# 嵌入式数据库

EMQX 使用一个嵌入式数据库 Mria (opens new window) 来存储以下信息。

  • 路由表
  • 会话
  • 配置
  • 警报
  • 等等

Mria 的表会被复制到所有 EMQX 节点上。 这也有助于容错:只要集群中至少有一个节点是活的,数据就是安全的。

如果EMQX集群的规模低于 5 个节点,通常不需要对数据库的弹性伸缩能力进行调优。

然而,为了实现横向扩展,建议将集群中的节点分成两个角色。

  • 核心(Core)节点
  • 复制(Replicant)节点

# 节点角色

核心节点作为数据库的真数据源:它们以全网状连接,每一个节点都包含一个最新的数据副本。 核心节点一般是静态和持久的,也就是说,不建议对核心集群进行自动伸缩。

另一方面,复制节点,将所有表的写操作转到核心节点上处理。 它们各自连接到核心节点的其中一个,并被动地复制核心节点的事务。 这意味着复制节点不允许自己执行任何写操作。 相反,它们要求核心节点代表它们更新数据。 同时,它们有一个完整的本地数据副本,所以读取访问的速度也同样快。

这种方法解决了两个问题。

  • 横向可扩展性(我们已经测试了有 23 个节点的 EMQX 集群)
  • 它可以实现复制节点集群的自动伸缩

由于复制节点不参与数据写入,当更多的复制者加入集群时,表的更新效率不会受到影响,进而允许创建更大的 EMQX 集群。

另外,复制节点被设计成可以按需增删,添加或删除它们不会改变数据冗余,所以它们可以被放在一个自动伸缩组中,从而实现更好的 DevOps 实践。 请注意,根据总数据量的大小,从核心节点初始复制数据是一个相对繁重的操作,所以自动伸缩策略不能过于激进。

# 配置

在 EMQX 5.0 中,所以如果不做任何调整的话所有节点都默认为 Core 节点,默认行为和 4.x 版本是一致的。

可以通过设置 emqx.conf 中的 node.db_role 参数或 EMQX_NODE__DB_ROLE 环境变量,把节点上设置为 Replicant 节点。

请注意,集群中至少要有一个核心节点,我们建议以 3 个 Core + N 个 Replicant 的设置作为初始规格。

根据业务需求,Core 节点可以接受 MQTT 的业务流量,也可以纯粹作为集群的数据库来使用。我们建议:

  • 在小集群中(3 个节点或更少),没有必要使用 Core + Replicant 复制模式,可以让 Core 节点承担所有的流量,避免增加上手和使用的难度。
  • 在超大的集群中(10 个节点或更多),建议把 MQTT 流量从 Core 节点移走,这样更加稳定性和水平扩展性更好。
  • 在中型集群中,取决于许多因素,需要根据用户实际的场景测试才能知道哪个更优。

# 网络与硬件配置

# 网络

Core 节点之间的网络延迟建议 10ms 以下,实测高于 100ms 将不可用,请将 Core 节点部署在同一个私有网络下;Replicant 与 Core 节点之间同样建议部署在同一个私有网络下,但网络质量要求可以比 Core 节点间略低。

# CPU 与内存

Core 节点需要较大的内存,在不承接连接的情况下,CPU 消耗较低;Replicant 节点硬件配置与 4.x 一致,可按连接和吞吐配置估算其内存要求。

# 异常处理

Core 节点对于 Replicant 节点是无感的,当某一 Core 节点宕机时,Replicant 节点会自动连接到其他 Core 节点,此过程中客户端不会掉线,但可能导致路由更新延迟;当 Replicant 节点宕机时,所有连接到该节点的客户端会被断开,但由于 Replicant 是无状态的,所以不会影响到其他节点的稳定性,此时客户端需要设置重连机制,连接至另一个 Replicant 节点。

# 监控和故障排查

对 Mria 性能的监控可以通过 Prometheus 指标或使用 Erlang 控制台来完成。

# Prometheus 系统指标

# 核心节点

  • emqx_mria_last_intercepted_trans:自节点启动以来,分片区收到的事务数量。注意,这个值在不同的核心节点上可能不同。
  • emqx_mria_weight:一个用于负载平衡的值。它的变化取决于核心节点的瞬间负载。
  • emqx_mria_replicants:连接到核心节点的复制节点数量。
  • emqx_mria_server_mql:未处理的事务数量,等待发送至复制者节点。越少越好。如果这个指标有增长的趋势,则可能需要为当前的核心节点增加算力资源,或添加更多的核心节点。

# 复制节点

  • emqx_mria_lag:复制者节点滞后,表示复制者节点滞后上游核心节点的程度。越少越好。
  • emqx_mria_bootstrap_time:复制者节点启动过程中花费的时间。这个值在复制者节点的正常运行过程中不会改变。
  • emqx_mria_bootstrap_num_keys:在初始复制过程中从核心节点复制的数据库记录的数量。这个值在复制者节点的正常运行中不会改变。
  • emqx_mria_message_queue_len:复制进程的消息队列长度。应该一直保持在0左右。
  • emqx_mria_replayq_len:复制者节点的内部重放队列的长度。越少越好。

# 控制台命令

执行 emqx_ctl eval 'mria_rlog:status().' 命令可以获得关于嵌入式数据库状态的更多信息。