一种大规模MongoDB集群监控方案的设计与实现

2019-11-07 12:30:26李云婷张海明黎建辉
数据与计算发展前沿 2019年4期
关键词:实例集群分布式

李云婷,张海明,黎建辉*

1. 中国科学院计算机网络信息中心,北京 100190

2. 中国科学院大学,北京 100049

引言

近年来,数据量的持续高速增长以及大量的并发访问,使得单一结构的数据库在容量和性能上不再满足需求,集群化成为趋势[1]。此外,数据类型也日渐丰富,传统关系型数据库已难以适应诸如 JSON 树状数据、图数据等新兴数据类型,且关系特性一定程度上限制着集群的水平扩展。MongoDB 作为典型的基于文档存储 NoSQL (Not Only SQL)数据库,则获得了广阔的应用空间。其数据结构简单,数据模式灵活,支持大规模分布式集群部署方式,可扩展能力极强,能实现高性能的读写操作[2]。如今,诸多应用趋于使用 MongoDB 集群进行数据存储与管理,为保证集群稳定性和数据可靠性,则需对 MongoDB 集群进行实时性能分析和健康状态报告。集群的各项性能指标与状态数据,对于系统稳定性分析、性能瓶颈优化、快速故障恢复等具有重要意义。

现有的 MongoDB 监控技术主要分为两类:MongoDB 官方提供的监控工具和服务[3],国内外开源项目。MongoDB 提供的工具如mongostat[4]和mongotop[5],适用于单个实例 (instance),监控内容有限,结果在命令行中每秒刷新展示,对于包含众多实例的大规模分布式集群而言并不适用。MongoDB 提供的服务如 free monitoring[6]和 Ops Manager[7],前者的性能分析过于简单,仅展示不超过 24h 的性能变化曲线,且监控数据不在本地存储,无法详尽分析;后者则更适用于集群,对企业版支持较好,社区版无论在本地进行配置还是使用都较为复杂,且自动发现实例时易遗漏 mongos 实例。国内外开源项目中诸如 UMongo[8]、Mongo3[9]、Treesoft[10]等更侧重于数据库的管理和操作,对性能和状态分析简单,一般对集群的支持度较差,大多不再更新。另外,基于开源监控平台如 Zabbix 的 MongoDB 监控解决方案[11]也多支持单点或副本集模式,对于复杂的大规模分布式集群,大多没有涉及或者尚未解决对所有 mongos 实例进行监控和对运行着多个实例的节点进行监控等问题。

由此可看出,现有的监控工具与项目虽对MongoDB 进行了一定程度的支持,但就大规模分布式 MongoDB 集群而言,仍存在不足之处。如何简单、高效、完备地监控 MongoDB 集群成为不容忽视的研究问题。本文认为,监控 MongoDB 集群需满足如下需求:第一,能够实时获取集群的性能和状态数据,且能同时监控众多节点及节点上的若干实例;第二,能够保存长期的监控历史数据;第三,能够提供较好的数据可视化展示。

本文基于上述问题和需求,结合 MongoDB 集群的结构特点,提出适用于 MongoDB 集群的分布式监控方案,在实践中能取得较好的监控效果。

1 MongoDB 集群及监控问题分析

1.1 MongoDB 分布式集群结构

Mongo DB 的分布式集群[12],也称分片集 (Sharded Cluster),主要利用分片技术 (Sharding)使得数据分布式地存储于多台机器上,同时通过副本技术 (Replication)为每台机器上的数据进行备份。一个典型的分片集架构如图1 所示。它包含三个成分:Shard、mongos 和 Config servers。

Shard 即分片,负责存储数据库中的实际数据。分片在生产环境中一般部署为副本集,即一组mongod 实例,以避免单点故障。图1 中的每个分片均部署为包含 3 个 mongod 实例的副本集,其中只有一个 mongod 承担主节点 (primary)角色,其它 mongod 一般作为备份点 (secondary)或仲裁点 (arbiter)。mongos,为客户端访问集群提供接口,本身不存储数据,可部署为多个。客户端连接任一 mongos 均可对集群进行操作,整个集群对外如同单一数据库。Config servers,存储整个集群的元数据和配置信息,也部署为副本集。mongos 收到来自客户端的数据操作请求后,会先从 Config servers 加载元数据,从而将请求正确定位到对应的分片,在相关分片上执行操作后返回结果。

1.2 集群监控问题分析

总体而言,MongoDB 的分布式集群中通常只包含 mongos 和 mongod 两种实例。mongos 处理来自应用层的请求,不存储数据;而 mongod 则处理数据请求,一般存储数据。对分布式集群进行监控,不仅是对集群中的所有节点进行监控,更是对集群中所有的 mongos 和 mongod 实例进行监控。因此监控 MongoDB 分布式集群需考虑的问题如下:

第一,如何获取完整的集群结构。MongoDB 分片集往往规模庞大、结构复杂,因而监控的前提是要知晓集群的结构,如集群中的节点信息、各节点上运行的实例信息。目前无法通过 MongoDB 官方提供的相关命令获取完整的集群结构。主要原因在于集群中各个 mongos 实例相互独立,即无法通过登录到一个mongos 而获取到另一个 mongos 的基本信息和状态。此外,集群结构还需设计简单明了的数据格式来进行表达。

第二,如何选取监控的基本单元。MongoDB 分布式集群结构复杂的主要原因在于集群的节点和实例并不局限为一对一关系,在实际部署环境中往往表现为一对多关系。即在一个节点上同时运行多个实例,以充分利用节点资源,例如某个节点上可部署一个 mongos 和多个 mongod 实例,它们占用不同的端口,在集群中承担不同的角色,每个 mongod 实例在不同位置分别存放数据。一般而言,集群的监控通常以节点作为基本单元,便于数据分析和呈现,但 MongoDB 集群需要对每个实例进行单独的监控分析。

第三,如何处理集群结构的变动。MongoDB 集群的可扩展性极强,集群结构容易发生变动。当集群增加分片时,集群结构随之改变,新的节点和实例需要能够及时加入监控。即在不改变原有节点监控的前提下,花费较小的开销将新增节点和实例纳入监控范围。

图1 MongoDB 分布式集群架构Fig.1 MongoDB sharded cluster architecture

2 分布式监控方案设计

针对上述监控基本需求和问题,结合大规模分布式 MongoDB 集群的结构特点,提出分布式监控方案。其中分布式监控架构以集群实例作为基本监控单元,定时采集数据,进行处理、存储和分析,同时进行性能实时展示,能用于包含大量节点与实例的MongoDB 集群。另外,设计 MongoDB 集群结构描述方法,将集群成分、节点、实例等详细信息通过简洁清晰的JSON格式进行表达。

2.1 分布式监控方案架构

MongoDB 集群节点和实例数量众多、结构易变动,尤其是一个节点上往往运行多个实例,承担多重功能。因此,传统的单一数据采集和接收模式在效果和效率上均难以满足监控需求,以节点为监控单位的数据采集方式更是无法满足监控架构的扩展需求,故设计分布式监控架构如图2 所示,以适应大规模易扩展的 MongoDB 集群。

在实际生产环境中,MongoDB 集群的节点往往同时运行和维护着多个 mongos 和 mongod 实例,这些实例在功能上多互有关联,但在性能和运行状态上则相对独立。因而在分布式监控架构中,采用实例作为基本监控单元,对每个实例单独进行性能分析。首先,使用多个采集器分散采集实时运行数据,每个采集器负责一定数量实例的数据采集。数据采集过程则突破了集群节点的局限,将整个集群视作实例的集合,不同节点、不同类型的实例可通过同一采集器进行数据采集。采集器定时从连接的实例上采集实时数据,从数据中筛选出监控所需的指标数据。数据发送器将指标数据发送至相应的代理接收处。代理接收处主要用于数据中转,汇聚一定范围的数据后再进行发送,能够有效地减缓数据接收的负担,在监控大规模 MongoDB 集群时效果显著。最后接收数据,对数据进行一定处理和分类,将监控数据统一存储至数据库。读取数据库中的数据,一方面可进行实时性能的可视化展示,在集群发生异常状态时告警,另一方面,可通过历史数据进行系统瓶颈分析和集群稳定性分析。

另外,为适应 MongoDB 集群的可扩展性,上述监控架构也具有一定的可扩展性。当集群中增加了新节点和实例,由于监控架构将实例而非节点作为监控单元,因此只需简单地将新增实例加入到已有采集器的数据采集范围,即可高效地将扩展的新节点纳入监控范围。当扩展的节点数过多时,可适当再增加新的采集器,还可相应地增加代理接收以减轻数据接收压力。

图2 分布式监控架构Fig.2 Distributed monitoring architecture

2.2 集群结构描述方法

在分布式监控架构中,监控数据以实例为单位进行分散采集,接收时可按照节点进行分类整理并存储,便于数据可视化展示。即展示每个节点上所有实例的实时性能和状态,同时表现出每个实例在集群中充当的成分和角色信息。因此,对于 MongoDB 集群,构建其分布式监控系统的关键依据是集群的结构信息。

但由于节点和实例的一对多关系,以及实例间的相对独立性,集群的结构信息往往难以完整获取。上文提及的 Ops Manager 和一些基于 Zabbix 的监控解决方案,在监控 MongoDB 分布式集群时都存在会遗漏 mongos 实例的问题,而原因也正是因为无法获取集群的完整结构信息。因此,本文认为,完整的集群结构信息不应通过外部连接命令获取,而是应由集群的管理员直接提供并维护。同时,结构信息作为监控系统的输入,还需进行简明规范的表达和描述。

通常情况下,结构信息应包含节点信息、实例信息、成分信息三部分。本文提出集群结构描述方法,将三种信息用通用规范的 JSON 格式进行统一表达。按照集群成分来划分并组织集群结构,对每个实例进行详细描述,在实例信息中融入节点信息。对于 mongos 实例,需给出所在节点的 IP 地址和占用端口;对于 mongod 实例,除 IP 和端口信息外,还需给出实例的角色信息,即是否为仲裁点。若为仲裁点 (arbiter),则该实例不存储数据,监控时只需判断实例是否正常运行;若不是仲裁点 (not arbiter),则监控时需获取详细的性能指标数据。

表1 集群结构信息示例Table1 Example of a cluster structure

例如某 MongoDB 集群共包含 5 个节点、15 个实例。其中 mongos 实例共 3 个,Config servers 包含的mongod 实例共 3 个,3 个分片中每个分片包含 mongod 实例各 3 个,其各节点的详细信息如表1 所示。

集群结构可通过 MongoDB 的三种成分 mongos、config、shard 进行划分,分别描述各成分中所有实例的详细信息,表1 中的集群结构可表达为如下的 JSON 格式:

3 监控系统实现

上述监控方案主要依据 MongoDB 的集群结构来构建分布式监控系统,分散地采集各实例的实时数据,经代理中转后,统一接收存储,并提供可视化展示和数据分析支持。对比当前主流的开源监控平台后,本文选用 Zabbix 对上述分布式监控系统进行实现。

3.1 开源监控平台 Zabbix 介绍

Zabbix[13]是一个企业级的开源通用监控平台,能对包括操作系统、数据库系统、硬件、网络等在内的多种系统资源和设备进行监控;提供灵活的告警与事件处理机制;同时通过 Web 界面提供可视化展示和配置管理;支持分布式的监控部署方式。目前,众多企业、高校的数据中心均使用Zabbix作为监控解决方案[14-17]。

Zabbix 架构简洁,通常包含 5 个主要的组件:Server、Database、Web、Proxy、Agent。其中,Server 是 Zabbix 的核心组件,用于捕获、接收和处理监控数据,将监控数据存储至 Database,并通过 Web页面进行展示。Database 用于存储 Zabbix 的所有数据信息,包括监控数据和配置信息。Web 提供 Zabbix 的访问接口,一方面提供监控数据的可视化展示,另一方面提供监控主机、监控项、用户权限等配置和管理。Database 和 Web 均可视作 Server 的一部分。Proxy 为可选组件,用于实现分布式监控,减轻 Server 端的负担。Agent 一般部署于被监控的主机上,通过 zabbix_agentd 进程采集并发送数据。除 zabbix_agentd 外,也可使用 zabbix_sender 进程来发送数据,但它无法直接采集数据。

3.2 监控系统的 Zabbix 实现

Zabbix 作为当前主流的开源监控方案,具有较强的通用性和易用性,因此本文选用 Zabbix 4.0 实现对 MongoDB 集群的分布式监控系统。其实现架构如图3 所示,主要使用了 Zabbix 的 sender 进程、Proxy 和 Server 组件。

与图2 的分布式监控架构相对应,数据采集模块通过定时执行 Python 脚本实现,而数据发送模块则通过 zabbix_sender 进程实现。使用 Python 脚本配合 zabbix_sender 来进行采集和发送,而非使用传统的 zabbix_agentd 进程,原因在于:其一,agentd 一般需部署运行于监控的节点上,而 sender 可部署在集群外的其它节点上,能连接集群即可。虽然 agentd 对于所在节点的影响甚微,但出于数据安全和操作权限等考虑,将集群节点与监控点隔离则更佳;其二,agentd 只能监控其所在节点的实例,当 MongoDB 集群进行扩展,则需在新节点上重新部署 agentd,而 sender 则可跨节点监控实例,更为灵活便捷;其三,sender 更适于批量数据的收集和发送。监控架构中的代理接收模块则通过图3 中的 zabbix_proxy 实现,proxy 可汇聚来自 sender 的数据,再将数据定期发送至 Zabbix Server。Zabbix Server 包含 Database 和 Web,因此能够实现分布式监控架构中的接收处理、统一存储、实时展示模块。 而图2 架构中的数据分析模块则需通过其它更为专业的统计分析模型或工具来完成。

图3 Zabbix 监控实现架构Fig.3 Implementation of Zabbix monitoring architecture

总体而言,Zabbix 实现 MongoDB 集群监控的流程可划分为两个阶段:配置主机和持续监控。两个阶段都需要读取并解析 MongoDB 集群的 JSON 结构信息。

配置主机阶段,即在 Zabbix Server 端依据 MongoDB 集群结构进行相应的主机配置,其具体流程如下:

配置主机阶段主要在 Web 前端完成可视化相关配置,以集群节点为单位进行组织,构建一个主机组,为每个节点创建主机,并根据节点上运行的具体实例为该主机链接相应的模板。模板是 Zabbix 中监控项、触发器、自定义图形等的集合。本文将模板与实例进行对应,充当相同集群成分和角色的实例可使用同一模板。Zabbix 4.0 尚未提供适用于 MongoDB 的官方模板,考虑到大规模集群监控的复杂性,本文对 MongoDB 相关指标进行设计和筛选,提出了适用于 MongoDB 集群的基础模板 Template MongoDB Not Arbiter 和 Template MongoDB Arbiter。前者适用于 mongos 实例以及非仲裁点的 mongod 实例,包含 11 个监控项,能对 MongoDB 主要性能指标和状态进行实时监控;后者则适用于充当仲裁点的 mongod 实例,包含 1 个监控项,仅监控运行状态,不对性能指标作监控。两种模板的监控项、触发器、自定义图形等具体内容分别如表2 和表3 所示。

表2 Template MongoDB Not Arbiter 模板内容Table2 Template MongoDB Not Arbiter

表3 Template MongoDB Arbiter 模板内容Table3 Template MongoDB Arbiter

结合集群的结构信息,可通过关键词替换等方法将基础模板简单地转化生成集群的定制模板,再根据每个节点上实际运行的实例情况为其链接相应的模板。以表1 集群中的 IP102 节点为例,其上运行 3 个实例,分别为 mongos 实例,shard1 的 mongod 实例和 config 的 mongod 实例,且两个 mongod 实例均为非仲裁点。因此,IP102 对应的主机需要链接 3 个模板,分别是 Template MongoDB Not Arbiter mongos,Template MongoDB Not Arbiter shard1,Template MongoDB Not Arbiter config。

持续监控阶段需定时采集数据、处理数据并展示。主要依据 JSON 结构信息中的 IP 地址和端口连接每一个实例,通过执行 serverStatus 命令,从返回文档中筛选出与模板监控项对应的指标数据。监控数据由 sender 发送,经过 proxy,最后到达 Server 端,进行简单预处理后,将数据分派到对应的主机并统一存储,Web 页面实时以图形化方式显示各主机的性能数据并刷新。每个 sender 负责一定数量的实例的数据采集。若集群进行扩展,首先需在集群结构的 JSON 描述中添加新增的实例和节点信息,而后更新 Server 端的主机配置,最后再将新增实例纳入数据采集范围。若加入新实例后,监控系统中各组件负荷过大,还可根据实际情况相应地增加 sender 与 proxy 数量。

3.3 实现效果

与其它同样使用 Zabbix 的 MongoDB 监控解决方案相比,本文的分布式监控方案针对集群设计,尤其是大规模复杂集群,而非单点模式。方案将整个集群当作实例的集合进行监控,在性能展示时又以节点为单位进行组织,重点解决复杂集群多节点、多实例、节点与实例呈一对多关系的监控难题。以表1 中集群的 IP101 节点为例,通过 Zabbix 的 Web 页面,既能查看该节点上 shard1 mongod 实例的监控项如 Mongo current connections (数据库当前连接数)的实时变化曲线,也能查看其 config mongod 实例的网络带宽和数据库基本操作数的实时变化,如图4 所示。

与 MongoDB 官方提供的 mongostat、mongotop 命令和 free monitoring 服务相比,本文的分布式监控方案能同时监控一个复杂集群的所有实例,而非单个实例,且监控指标丰富多样,能全面对实例进行状态评估,还能对任一实例的任一数值型监控项提供如图4 的可视化展示。

与 MongoDB 官方提供的 Ops Manager 相比,本文的分布式监控方案配置较为简单,能提供并表达出完整的集群结构,在监控时不会遗漏任何一个 mongos 实例。同时,在监控指标上进行了筛选,重点关注实例运行状态、网络带宽和数据库操作信息,专注于集群性能监控。若集群进行扩展,该方案能够通过结构信息简单方便快速地更新监控范围。另外,由于方案中对监控历史数据进行了集中存储,因此能支持接入专业的模型和工具以进行深入的性能数据分析。

图4 监控效果图Fig.4 Example of monitoring results

在实践过程中,对上述分布式监控系统中监控数据发送所需的网络流量以及监控数据存储所需的空间容量进行简单测试。对于 mongos 实例或非仲裁点的 mongod 实例,使用表2 模板,每次需采集并打包发送11项监控指标,平均每次发送使用网络流量为 1104 B;对于充当仲裁点的 mongod 实例,使用表3 模板,每次只需采集并打包发送1项监控指标,平均每次发送使用网络流量为 310 B。对表1 中的集群进行测试,集群包含 5 个节点,15 个实例,其中 13 个实例为 mongos 或非仲裁点的 mongod 实例,2 个实例为仲裁点实例,共有 145 个监控项,将数据采集发送频率设置为 30 s 一次,则监控 1 天后,监控数据发送使用的网络总流量为 37.8 MB,Zabbix 的 Database 中增加的存储量为 59.7 MB。对包含 20 个节点、39 个实例的集群进行测试,共有 349 个监控项,将数据采集发送频率设置为 30 s 一次,则监控 1 天后,监控数据发送使用的网络总流量为 92.3 MB,Database 中增加的存储量为 143.8 MB。由于监控中将集群实例作为数据采集的基本单位,因此系统中监控数据的网络流量和存储总量均应与集群实例数量呈正比关系。由此可推断,当集群中实例数达到 100 时,频率 30 s、监控 1 天,数据发送使用的网络流量应为约 200 MB,数据存储量将增加约 350 MB。并且,由于 Zabbix 的 Database 中存储的历史和趋势数据可配置存储保留时长,超过时长的数据将被清理,因此 Database 的数据容量不会持续大量增长。

上述分布式监控系统理论上能通过增加 sender 和 proxy 的数量、配置多级 proxy 等方式适应超大规模的 MongoDB 集群。由于 sender 需将数据打包发送,每个 sender 负责的实例数量建议设置为 15-20 个,这样能保证每个 sender 的发送负荷不会过大且 sender 的数量可控。每个proxy建议连接 3-10 个 sender。当集群达到超大规模,可考虑设置二级 proxy 以进一步减轻 Server 处的接收负担。

实践证明,本文提出的分布式监控方案能适用于大规模分布式 MongoDB 集群,能通过较小的网络流量和存储空间获得完备的长期和实时监控数据。Zabbix 的 Server 和 proxy 部署和使用对基本内存和硬盘要求较低、sender 对部署节点的影响较小,监控数据采集所使用的 serverStatus 命令对 MongoDB 集群本身影响甚微,不影响集群的整体性能。因此当集群节点数较多时,仍能维持高效的监控方式。此外,Zabbix 还可与可视化工具 Grafana 相结合[18]以提供更专业的数据可视化展示。

4 结语

MongoDB 集群作为典型的 NoSQL 数据库系统,在数据量级持续增加的背景下,获得了广泛的应用和发展。针对 MongoDB 集群规模庞大、节点和实例数量多、结构易变动等特点,本文提出分布式监控方案,设计集群结构的描述方法,将集群实例作为基本监控单元,分散采集数据,再进行统一存储和分析。通过使用开源平台 Zabbix,实现了对大规模分布式 MongoDB 集群的性能状态监控,得到较好的可视化效果。在下一步工作中,将把集群节点的系统资源使用情况纳入监控范围,同时加强对监控数据的统计和分析,进一步完善监控方案。

猜你喜欢
实例集群分布式
海上小型无人机集群的反制装备需求与应对之策研究
一种无人机集群发射回收装置的控制系统设计
电子制作(2018年11期)2018-08-04 03:25:40
分布式光伏热钱汹涌
能源(2017年10期)2017-12-20 05:54:07
分布式光伏:爆发还是徘徊
能源(2017年5期)2017-07-06 09:25:54
Python与Spark集群在收费数据分析中的应用
勤快又呆萌的集群机器人
基于DDS的分布式三维协同仿真研究
雷达与对抗(2015年3期)2015-12-09 02:38:50
完形填空Ⅱ
完形填空Ⅰ
西门子 分布式I/O Simatic ET 200AL