01-正文
本章节下载 (1.25 MB)
MongoDB是一个介于关系数据库和非关系数据库之间,非关系数据库当中功能最丰富,最像关系数据库的产品。它支持的数据结构非常松散,是类似json的bson格式,因此可以存储比较复杂的数据类型。MongoDB最大的特点是它支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。
图1-1 MongoDB副本集整体架构
集群拥有一个主节点和多个从节点,如图1-1所示。主节点提供所有的增、删、查、改服务;从节点不提供任何服务,但是可以通过设置使从节点提供查询服务,减少主节点的压力。
· 当集群中主节点发生故障时,副本集可以自动投票,选举出新的主节点,并引导其余的从节点连接新的主节点,而且这个过程对应用是透明的。
· MongoDB副本集使用的是N个mongoDB 节点构建的具备自动容错功能、自动恢复功能的高可用方案。在副本集中,任何节点都可作为主节点,但为了维持数据一致性,只能有一个主节点。
· 主节点负责数据的写入和更新,并在更新数据的同时,将操作信息写入名为oplog的日志文件当中。从节点会定时轮询读取oplog日志,根据日志内容同步更新自身的数据,保持与主节点一致。
· 在一些场景中,用户还可以使用副本集来扩展读性能,客户端有能力发送读写操作给不同的服务器,也可以在不同的数据中心获取不同的副本来扩展分布式应用的能力。
· 在副本集中还有一个额外的仲裁节点(不需要使用专用的硬件设备),负责在主节点发生故障时,参与选举新节点作为主节点。
· 副本集中的各节点会通过心跳信息来检测各自的健康状况,当主节点出现故障时,多个从节点会触发一次新的选举操作,并选举其中一个作为新的主节点。为了保证选举能够出现多数派,副本集的节点数需要保持为奇数。
图1-2 MongoDB分片架构图
MongoDB分片是横跨多台主机存储数据记录的过程,它是MongoDB针对日益增长的数据需求而采用的解决方案。随着数据的快速增长,单台服务器已经无法满足读写高吞吐量的需求。MongoDB分片通过水平扩展的方式解决了这个问题。通过分片可以添加更多的机器到集群中来应对快速增长的数据存储并且满足高吞吐量的读写操作。MongoDB使用分片技术来支持大数据集和高吞吐量操作。
MongoDB通过配置分片集群来支持分片,分片集群架构如图1-2所示。一个分片集群包括以下几
个组件:MongoDB Shard,Mongos,ConfigServer。
· Mongos:数据路由,负责提供客户端应用访问每个分片的路径。
· ConfigServer:配置服务器,存储集群的元数据,这些数据包含了集群数据集到各分片的映射关系。查询路由就是通过这些元数据到特定的分片上执行指定的数据操作。
· MongoDB Shard:数据分片,用来存储数据,为了提供系统可用性和数据一致性,通常每个分片是一个副本集。
Mongos本身并不持久化数据,分片集群所有的元数据都会存储到ConfigServer,而用户的数据会分散存储到各个MongoDB Shard。Mongos启动后,会从配置服务器加载元数据,开始提供服务,将用户的请求正确地路由到对应的分片。
MongoDB的数据模型是一种灵活模式。关系型数据库要求租户在插入数据之前必须先定义好一个表的数据结构,而MongoDB的集合则并不限制document结构。这种灵活性让对象和数据库文档直接的映射变得很容易。即使数据记录之间有很大的变化,每个文档也可以很好的映射到各条不同的记录。当然在实际使用中,同一个集合中的文档往往都有一个比较类似的结构。
设计基于MongoDB的应用程序数据模型时的关键就是选择合适的文档结构以及确定应用程序如何描述数据之间的关系。有两种方式可以用来描述这些关系:引用及内嵌。
· References-引用:引用方式通过存储链接或者引用信息来实现两个不同文档直接的关联,如图1-3所示。应用程序可以通过解析这些数据库引用来访问相关数据。
· Embedded Data-内嵌:内嵌方式指的是相关关联的数据保存在同一个文档结构之内,如图1-4所示。MongoDB的文档结构允许一个字段或者一个数组内的值为一个嵌套的文档。这种冗余的数据模型可以让应用程序在一个数据库操作内完成对相关数据的读取或修改。
MongoDB的主要目标是在键/值存储方式(提供了高性能和高度伸缩性)以及传统的RDBMS系统(丰富的功能)两者中间架起一座桥梁,集两者的优势于一身。MongoDB适用于以下场景:
(1) 网站数据
MongoDB非常适合实时的插入,更新与查询,并具备网站实时数据存储所需的复制及高度伸缩性。
(2) 缓存
由于性能很高,MongoDB也适合作为信息基础设施的缓存层。在系统重启之后,由MongoDB搭建的持久化缓存可以避免下层的数据源过载。
(3) 用于对象及JSON数据的存储
MongoDB的BSON数据格式非常适合文档格式化的存储及查询。
· 本章节主要介绍在MongoDB云数据库中,安装MongoDB时的节点规划策略。关于MongoDB部署流程以及部署过程中相关的参数说明等,详情请参见产品在线联机帮助。
· 在实际生产环境中,MongoDB集群规模应随业务需求及数据量增加进行动态调整。
部署MongoDB副本集时,部署策略如表2-1所示。
表2-1 MongoDB副本集部署策略
节点类型 |
是否必选 |
选型说明 |
描述 |
MongoDB Node |
必选 |
MongoDB运行进程 |
MongoDB Node个数至少配置1个,其中: · 当MongoDB Node个数小于3时,将会部署MongoDB单机模式,此时不支持开启高可用 · 当MongoDB Node个数大于等于3时,将会部署MongoDB集群模式,此时开启高可用 |
部署MongoDB分片集群时,部署策略如表2-2所示。
表2-2 MongoDB分片集群部署策略
节点类型 |
是否必选 |
选型说明 |
描述 |
MongoDB Node |
必选 |
MongoDB运行进程 |
分片集群分片MongoDB Shard个数支持2-16个,每个分片为3节点MongoDB Node副本集 |
Mongos Node |
必选 |
Mongos运行进程 |
Mongos Node个数至少配置1个,最大支持16个 |
ConfigServer Node |
必选 |
ConfigServer运行进程 |
ConfigServer Node个数固定为3个 |
用户身份认证:当用户访问已启用访问控制的MongoDB集群时,会强制执行用户身份验证,用户只能执行由其角色确定的操作。
· 用户是指在集群详情页的[集群详情/用户]页签下看到的用户,包括集群数据库用户;也可以使用集群创建使用的mongouser数据库超级用户。
· 客户端所在主机需要配置MongoDB集群主机域名解析。客户端所在主机的/etc/hosts文件需要配置MongoDB集群主机域名相关信息,配置后用户才可以正常访问MongoDB集群。
通过mongo shell命令来连接数据库:
副本集:mongo mongodb://{ip}:{port}/admin?replicaSet=shard0 -umongouser –p password
· ip:集群主机ip
· port:MongoDB服务端口
分片集群:mongo mongodb://{ip}:{port}/admin -umongouser –p password
· ip:Mongos进程主机ip
· port:Mongos服务端口
删除数据库将清空数据库中的数据。
在MongoDB中,数据库指一组集合的逻辑分组,类似于RDBMS中的DataBase。数据库的用法举例如下:
(1) 使用数据库:(MongoDB中数据库不用创建,可直接使用)
shard0:PRIMARY> use db1
(2) 显示所有数据库(数据库中如果没有数据,则不显示):
shard0:PRIMARY> show dbs
(3) 在数据库中创建集合:
shard0:PRIMARY> db.createCollection('coll')
(4) 显示数据库下的所有集合:
shard0:PRIMARY> show tables
(5) 删除数据库:
shard0:PRIMARY> db.dropDatabase()
MongoDB Shell客户端使用createCollection关键字来创建集合。MongoDB插入数据时如果没有集合,会自动创建,因此createCollection主要用于使用特定选项创建集合。用法举例如下:
· 指定集合名来创建集合:
shard0:PRIMARY> db.createCollection('coll')
· 限制集合空间大小和文档个数创建集合,size:字节大小,max:文档个数:
shard0:PRIMARY> db.createCollection("coll",{ capped:true,size:100,max:100})
· 使用文档校验创建集合,支持json格式校验,如下方式:
shard0:PRIMARY> db.createCollection( "contacts", {
validator: { $jsonSchema: {
bsonType: "object",
required: [ "phone" ],
properties: {
phone: {
bsonType: "string",
description: "must be a string and is required"
},
email: {
bsonType : "string",
pattern : "@mongodb\.com$",
description: "must be a string and match the regular expression pattern"
},
status: {
enum: [ "Unknown", "Incomplete" ],
description: "can only be one of the enum values"
}
}
} }
} )
当执行以下插入语句时,校验格式不符合,提示插入失败信息。
shard0:PRIMARY> db.contacts.insert( { name: "Amanda", status: "Updated" } )
用法举例如下:
shard0:PRIMARY> db.contacts.insert( { name: "Amanda", phone: "Updated" } )
查询数据,用法举例如下:
shard0:PRIMARY> db.contacts.find()
shard0:PRIMARY> db.contacts.find( { status: "Updated" } )
本章重点介绍数据库集群的基本操作与高级特性。
· 基本操作包括:集群详情概览、数据库集群的扩缩容以及用户和数据库的管理等。
· 高级特性包括:数据库备份、白名单管理、集群监控告警以及其他高级用法。
进入集群详情页面,如图3-1所示,集群详情页面主要展示该集群的基本信息、概览、部署拓扑、配置等相关信息,同时可进行集群的高级管理,包含告警、备份恢复和白名单等。
· 基本信息:展示集群的健康状态、基本配置和硬件配置等信息,以便于快速了解集群。
· 概览:展示了该集群中组件统计、性能指标趋势图、以及CPU/磁盘/内存使用率等信息。
· 部署拓扑:在[部署拓扑]页签下,可查看集群的节点信息和安装的组件,并对组件进行启动、停止、重启等操作。
· 配置:在[配置]页签下,可查看集群中组件的配置、配置修改历史信息,并且可以执行配置修改等操作。
· 用户:在[用户]页签下,可查看集群中所有的用户信息。
· 数据库:在[数据库]页签下,可查看集群中的所有数据库信息。
· 监控:在[监控]页签下,可查看集群中的监控列表,展示节点当前状态、节点IP、磁盘/CPU/内存使用率等信息。
· 告警:在[告警]页签下,可查看集群中的集群告警统计信息、告警列表,同时可以进行告警配置。
· 备份恢复:在[备份恢复]页签下,可以自定义创建备份策略,同时页面展示集群中已有的备份策略、备份任务等相关信息。
· 计费:在[计费]页签下,可根据在[系统/系统配置/运营配置/计费策略]页面配置的对应计费策略,按照使用集群的时长计算使用费用。
· 白名单:在[白名单]页签下,用户可以通过操作白名单状态限制用户对集群的访问权限。
用户在使用云数据库MongoDB服务的过程中,可根据实际需求对集群进行扩缩容的操作。
MongoDB集群扩容是指集群新添加节点并在该节点上新增MongoDB服务。
随着业务量增长,数据库集群提供的计算和存储能力无法满足业务需求时,可首先考虑提升数据库单节点的配置(CPU、内存、磁盘),当单节点配置提升仍无法达到业务的性能要求时,可考虑增加数据库集群节点,分担业务对于数据库单节点的请求压力。
· 扩容前需保证当前集群运行状态正常,若集群处于异常状态,请先处理相关异常情况,再进行扩容操作。
· 执行节点扩容前,要求在云平台中已完成云资源的准备。云资源包括裸金属和虚拟机两种,根据实际使用需求任选其一即可。
· 副本集集群扩容时,扩容节点规格和当前规格一致,节点个数最多扩容至7个,且需保持扩容后为奇数个。
· 分片集集群ConfigServer实例不支持扩容。
· 只有集群的创建者才能对集群进行节点扩容操作。
· 扩容操作不影响当前数据库集群的可用性,MongoDB集群自动完成数据同步。
· 节点扩容操作不可中止或暂停,操作不可进行回退,需谨慎操作。
副本集集群扩容操作步骤如下:
(1) 在集群管理页面,单击集群名称可跳转至集群详情页面。
(2) 选中集群详情页面右上角的[集群操作]下拉框中<节点扩容>进入节点扩容页面。
(3) 在下拉框中选择扩容节点数,单击<确定>按钮,即完成MongoDB副本集集群扩容。
图3-2 MongoDB副本集扩容
分片集群扩容操作步骤如下:
(1) 在集群管理页面,单击集群名称可跳转至集群详情页面。
(2) 选中在集群详情页面右上角的[集群操作]下拉框中<节点扩容>进入节点扩容页面,
(3) 选择扩容类型,填写节点规格。
¡ 添加分片:添加MongoDB Shard节点,选择该类型则系统自动生成集群节点类型、数量、规格等数据,不支持修改。
¡ 添加mongos:添加Mongos节点,扩容节点数可选择1-15个,节点规格请根据用户实际需求选择。
(4) 单击<确定>按钮,即完成MongoDB分片集群扩容。
图3-3 MongoDB分片集群扩容
扩容操作下发且完成后,可查看集群运行状态,部署拓扑和监控等信息查看扩容情况。
更改规格是指在原有规格上进行规格扩充。更改规格包含普通更改和在线更改。
· 普通更改指修改原节点的CPU、内存和磁盘大小,更改后会重启云主机。
· 在线更改指在原有规格上进行规格扩充,在线更改操作不会造成云主机重启。
当业务的运行需要提升计算性能和磁盘存储空间时,可对节点的CPU、内存和磁盘进行扩容操作,以获取更高性能。
· 虚拟化类型为CAS且为Linux操作系统的云主机在线扩容需满足初始内存大于等于4GB。
· 若云主机存在包含数据盘的整机快照,请先删除相应整机快照后再使用普通更改方式更改规格,否则会导致更改规格失败。
普通更改会重启云主机。
MongoDB更改规格操作步骤如下:
(1) 在集群管理页面,单击集群名称可跳转至集群详情页面。
(2) 在集群详情页面,选择[监控]页签,单击<更改规格>按钮,在弹出的菜单中选择对应需要更改的节点规格并进行确认后,即可完成操作。
图3-4 更改规格
MongoDB集群缩容是指将某节点上安装的MongoDB服务停止运行,退出集群,并删除节点。
因数据库单节点配置(CPU、内存、磁盘)不可回退,当有业务量缩减或“降本增效”优化资源分配时,可考虑集群缩容操作直接回收主机资源。
· 只有集群的创建者才能对集群进行删除主机的操作。
· 在副本集集群模式下,Master节点所在主机<删除>按钮置灰,不支持删除。
· 在分片集群模式下,MongoDB分片、ConfigServer不支持删除,Mongos主机支持删除,至少需要保留一个节点。
· 开启反亲和性后,不允许进行缩容操作。
· 删除节点为高危操作,不可中止或暂停,请谨慎使用。
· 在生产环境中,删除节点会同时删除节点中的数据,用户执行该操作前务必确认是否执行删除主机操作。
(1) 在集群管理页面,单击集群名称可跳转至集群详情页面。
(2) 在集群详情页面,选择[监控]页签,单击监控列表某节点对应的<删除>按钮或者选中集群操作下拉框中的<删除节点>按钮,弹出删除节点弹框。
(3) 在弹出的删除节点弹框中选中要删除的节点,单击<确认删除节点>按钮,即删除该节点。
图3-5 MongoDB缩容操作
· 用户为MongoDB数据库用户,通过数据库权限配置可以控制用户对数据库的读写权限。
· 用户需要关联需要操作的数据库。
· 在同一个数据库,用户名称具有唯一性,在同一数据库中创建多个用户时名称不能重复。
MongoDB提供了通过web界面管理用户和数据库的功能。
在新建MongoDB数据库集群时,会默认为MongoDB集群创建mongouser用户,密码为在创建集群时用户输入的数据库密码,在实际使用中建议根据不同的业务需求创建不同的数据库用户,当前数据库用户权限是粗粒度的,对应权限如表3-1所示。
表3-1 MongoDB角色说明
组件 |
角色类型 |
对应的组件权限 |
MongoDB |
管理员 |
拥有该数据库所有权限 |
读写 |
数据读取、写入等相关操作 |
|
只读 |
数据读取等相关操作 |
租户在使用过程中,根据实际需要,可执行新建用户的操作。
(1) 在集群管理页面,单击集群名称可进入集群详情页面。
(2) 选择[用户]页签,单击<新建用户>按钮,进入新建用户页面。
(3) 根据提示配置对应参数项的值,如下:
¡ 用户名称:可以操作数据库的用户名称。
¡ 角色:新增用户的角色,角色有三种管理员、读写、只读。
¡ 密码:自定义输入符合规则的用户密码。
¡ 确认密码:重复输入用户密码,进行确认。
¡ 数据库授权:用户可以操作的数据库名称。
(4) 相关信息配置完成后,单击<确定>按钮,即可完成新建用户。
图3-6 创建用户
集群在使用过程中,根据实际需要,可执行新建数据库的操作。
(1) 在集群管理页面,选择[集群列表]页签,单击集群名称可进入集群详情页面。
(2) 在集群详情页面选择[数据库]页签,单击<新建数据库>按钮,进入新建数据库页面。
(3) 根据提示配置对应参数项的值,如下:
¡ 数据库名称:自定义输入符合命名规则的用户名。
¡ 数据库描述:输入数据库描述信息。
(4) 相关信息配置完成后,单击<确定>按钮,即可完成新建数据库。
图3-7 创建数据库
数据库的备份恢复能防止因自然灾害、数据误删、系统漏洞、硬件故障等带来的数据丢失隐患。云数据库MongoDB提供完善的数据备份功能,支持全量备份方式。下面将详细阐述备份操作的相关概念及步骤。
备份数据的前提是完成备份服务器和备份策略的创建。
数据库备份的操作流程主要为:
(1) 首先需完成备份服务器的部署,详情可参见3.4.2 备份服务器 。
(2) 其次需创建备份策略,详情可参见3.4.3 备份策略。
(3) 在手动或被动触发备份策略后会生成对应的备份任务,整体流程图如图3-8所示。
备份服务器在备份恢复功能中主要起存储备份数据作用,在执行备份任务时备份数据将远程拷贝到备份服务器上。备份服务器需在创建备份前完成部署,备份的数据才能正常存储在备份服务器上。
· 部署备份服务器时,建议备份服务器所在主机的时间和云平台时间保持一致。
· 备份文件存储目录在备份策略执行用于存放数据,建议提前规划,选择较大的数据目录作为备份服务器的备份目录。
(1) 在[备份管理/备份服务器]页面,单击<部署>按钮,根据提示配置对应参数项的值,具体参数说明可参考联机帮助文档。
(2) 将主机IP地址、ssh端口、root用户密码输入完成后,单击<连接主机>按钮,主机测试连接通过后,选择备份目录(默认只展示大于20G的目录),即可完成部署。
图3-9 部署备份服务器
当部署备份服务器的请求提交后,可在[备份管理/备份服务器]页签下查看该备份服务器的状态。
· 当状态从“部署中”改为“运行中”,则表示备份服务器部署成功。
· 若备份服务器的状态为“失败”,可单击备份服务器的IP地址进入备份器详情,查看部署日志,查找备份服务器部署失败的原因。
备份服务器完成创建后,为防止备份数据将备份目录占满,用户可对该备份目录设置配额。
在执行数据库备份任务时会校验当前目录下的备份文件是否超过了用户分配的配额,若超过配额则将中止本次备份任务并将备份任务置为失败。
(1) 在备份管理页面,选择[备份服务器]页签,单击IP地址可进入备份服务器详情页面。
(2) 在备份服务器详情页面,单击备份数据存储目录列表的<修改>按钮,即可在弹框中设置合适的配额大小,如图3-10所示。
【说明】在新增备份目录时默认配额为当前目录的最大磁盘容量。
完成备份服务器的创建,用户即可以根据实际的业务需求创建数据库备份策略。
备份策略将以定时调度的方式进行数据库数据备份(类似Linux中的crontab定时任务),备份策略为全量的逻辑备份。
创建备份策略的步骤如下:
(1) 在[备份管理/定时备份策略]页签下,单击<创建策略>按钮,弹出创建备份策略弹框。
(2) 在弹框中完成策略名称、数据库集群、备份类型、备份时间、存储方式、存储时长等配置,如图3-11所示,关于各参数项配置详情请参见产品在线联机帮助。
(3) 各个参数配置完成后,单击<确定>按钮,备份策略创建成功。
建议在集群创建完成后,尽快进行备份策略的创建并手动执行1次备份策略,以提高集群的容灾能力。
云数据库MongoDB支持手动或自动触发备份策略。
备份策略被触发执行后会生成对应的备份任务,通过备份任务列表详情可以看到本次备份任务的执行的状态,如备份任务执行失败,可通过备份任务查看备份失败的具体原因。
图3-12 备份任务
· 新建集群后,用户可以通过操作白名单状态限制用户对集群的访问权限。
· 白名单状态默认是关闭,即所有用户IP均有权限访问集群数据库。
· 当用户需要限制某些用户访问时,可以开启白名单,在白名单管理页面手动添加有访问权限的IP,即只有在白名单中的IP才可以访问集群数据库。
· 为了保证数据的安全性,建议在集群创建完成后立即将白名单开启。
集群创建后,白名单状态默认为关闭,即所有用户IP都有权限访问集群数据库;当用户需要限制某些用户访问时,可以开启白名单,在白名单管理页面手动添加有访问权限的IP,即只有在白名单中的IP才可以访问集群数据库。
(1) 在集群管理页面,单击集群名称可跳转至集群详情页面。
(2) 选择[白名单]页签,单击<开启白名单>/<关闭白名单>按钮,在弹出开启/关闭白名单窗口中进行确认后,即可完成开启/关闭白名单操作。
图3-13 开启/关闭白名单
开启白名单后才可执行添加白名单操作。
(1) 在集群管理页面,单击集群名称可跳转至集群详情页面。
(2) 在集群详情页面选择[白名单]页签,单击<添加>按钮,弹出添加白名单窗口。
(3) 根据实际需求选择添加IP类型后,单击<确定>按钮,完成添加白名单操作。
¡ IP:一个或多个单独的IP地址添加进白名单中。
¡ 子网:在该子网掩码下的IP添加进白名单中。
¡ IP段:这个区间内的IP都添加到白名单中。
图3-14 添加白名单
若不允许某IP地址继续访问数据库,则可执行移除白名单操作。
(1) 在集群管理页面,单击集群名称可跳转至集群详情页面。
(2) 选择[白名单]页签,在白名单IP列表中选择想要移除的IP地址,可以执行移除单个IP或多个IP的操作。
¡ 移除IP:单击IP列表对应<移除>按钮,弹出移除IP弹框,确认要移除的IP,单击<确定>按钮,完成操作。
¡ 批量移除IP:选中多个IP列表前面的选框,单击列表上方<移除>按钮,弹出移除IP弹框,确认要移除的IP信息,单击<确定>按钮,完成操作。
数据安全服务是云数据库MongoDB的重要特性之一,云数据库MongoDB提供了丰富的性能监控项和秒级监控频率,方便您掌握集群的运行状态并通过细粒度的监控数据快速定位运维问题,并且能够提供告警组管理以及个性化的告警管理与配置。
CPU、内存、磁盘的硬性限制会对数据库性能产生很大影响,云数据库MongoDB控制台提供了丰富的性能监控项和秒级监控频率,方便您掌握集群的运行状态并通过细粒度的监控数据快速定位运维问题。
当业务感知数据库性能存在问题时,首先应查看数据库的宿主机状态。在集群信息详情的[概览]页签,3段式展示了主机上的性能监控图表,包括组件统计、性能趋势、内存/磁盘/CPU使用率,详细地展示了数据库宿主机当前的主机性能,如图3-15所示。
不同的业务对于数据库性能的要求不同,因此个性化的用户监控告警配置必不可少,云数据库MongoDB提供了实时的数据库状态监控,并可以让用户自定义监控告警级别和告警方式。
在告警管理界面,可查看告警信息、告警联系组和告警联系人等相关详情信息,同时可对告警联系组和联系人等执行相关管理操作。
在集群管理界面,单击集群名称进入集群详情页面,选择[告警]页签,可查看告警列表详细信息。单击页面的<告警配置>按钮,可自定义配置告警规则,系统告警配置指标项摘要如_Ref89251404所示。
表3-2 告警项及说明
告警项 |
告警描述 |
游标开启数量 |
游标开启数量大于10000为一般级别,大于30000为严重级别,可自定义修改阈值 |
数据库可用性 |
数据库可用性等于0为严重级别 |
数据库连接使用率 |
数据库连接数大于60%为一般级别,大于80%为严重级别,可自定义修改阈值 |
节点可用性 |
数据库可用性等于0为严重级别 |
主从复制延时 |
主从复制延时大于60s为一般级别,大于600s为严重级别,可自定义修改阈值 |
内存使用率 |
内存使用率大于60%为一般级别,大于80%为严重级别,可自定义修改阈值 |
CPU使用率 |
CPU使用率大于60%为一般级别,大于80%为严重级别,可自定义修改阈值 |
磁盘使用率 |
磁盘使用率大于60%为一般级别,大于80%为严重级别,大于95%为致命级别,可自定义修改阈值 |
当某一指标超过设定的阈值后则会自动发出告警邮件或短信。产生告警后,会在告警管理页面的告警信息列表展示详细告警信息。
日志管理是云数据库MongoDB的重要特性之一,云数据库MongoDB提供了全生命周期内的日志记录、导出功能,导出的日志可以帮助我们快速定位云数据库MongoDB服务从创建、使用直至销毁阶段内的问题。
用户若在创建云数据库MongoDB服务过程中出现创建失败的情况;或在云数据库MongoDB服务的使用过程中出现下发任务命令发生异常的情况,则可进行相关运行日志收集。
(1) 在[日志管理/运行日志收集]页面,提供了运行日志的收集筛选条件,如图3-16所示。
(2) 输入连接信息,测试远程连接成功后,选择所需收集日志的时间范围。部分配置参数说明如下:
¡ 远程连接信息
- SSH端口:云平台远程SSH连接端口。
- root密码:root用户的远程登录密码。
¡ 日志收集类型
- 基础日志:base服务中的相关日志,默认选中不可修改。
- 服务日志:数据库服务运行的日志,默认选中不可修改。
¡ 日志收集时间:自定义选择日志产生的时间范围,默认选择前一天和当天的时间,最大范围30天。
(3) 以上信息配置完成后,单击<确定>按钮,即可开始运行日志收集并下载日志压缩文件。
· 运行日志以天为单位进行收集和下载,当某天没有产生日志信息时,下载成功后解压没有该天的日志文件信息。
· 下载的日志信息压缩包最大为1GB,若超过该值则某些日志信息可能会丢失,此时建议分批下载。
云数据库MongoDB提供了集群日志下载功能,用户可以根据实际需要下载不同的节点日志,用于快速定位集群在使用过程中的问题。
用户在使用MongoDB集群过程中,如MongoDB集群发生异常情况,可下载集群节点的日志信息以便定位异常。
仅支持下载集群节点为“在线”状态的集群日志信息。
(1) 在[日志管理/集群日志收集]页面,提供了集群日志的收集筛选条件,如图3-17所示。
(2) 选择需要下载日志信息的集群名称,会查询当前集群下的节点信息并展示在下方列表中。选择集群及节点后,单击操作列的<下载>按钮可进行日志下载。
· 开发所使用jar包
compile(group: 'org.mongodb', name: 'mongo-java-driver', version: '3.2.0')
· OpenJDK版本
OpenJDK版本为1.8。
· 注意事项:
¡ 保证开发环境与连接集群时间同步,避免出现连接不上、连接超时等问题。
¡ 需将连接集群/etc/hosts文件内容拷贝到开发环境的hosts中。
¡ 切记调用结束时注意关闭MongoClient等连接。
MongoDB调用结束时注意关闭MongoClient等连接。
· MongoDB单机模式
//请根据实际环境修改配置
private static final String ADDR = "10.121.65.37";//服务器IP地址
private static final int PORT = 27018;//端口
private static final String AUTH = "CloudOS5#DE3@Redis";//密码
private static final String DB = "admin";//数据库
private static final String USER = "mongouser";//用户名
private static final List<ServerAddress> addrs = new ArrayList<>();
addrs.add(new ServerAddress(ADDR));
· MongoDB集群模式
private static final String ADDR1 = "10.121.65.37";//服务器IP地址
private static final String ADDR2 = "10.121.65.38";//服务器IP地址
private static final String ADDR3 = "10.121.65.39";//服务器IP地址
private static final int PORT = 27018;//端口
private static final String AUTH = "CloudOS5#DE3@Redis";//密码
private static final String DB = "admin";//数据库
private static final String USER = "mongouser";//用户名
private static final List<ServerAddress> addrs = new ArrayList<>();
addrs.add(new ServerAddress(ADDR1));
addrs.add(new ServerAddress(ADDR2));
addrs.add(new ServerAddress(ADDR3));
以上示例中的参数(ADDR、PORT、AUTH、DB、USER)需要根据实际环境修改。
· MongoDB单机模式、集群模式示例如下:
static {
try {
//创建连接池,新建连接
MongoCredential credential = MongoCredential.createScramSha1Credential(USER, DB, AUTH.toCharArray());
List<MongoCredential> credentials = new ArrayList<>();
credentials.add(credential);
//通过连接认证获取MongoDB连接
MongoClient client = new MongoClient(addrs,credentials);
} catch (Exception e) {
e.printStackTrace();
}
}
//释放资源
public static void releaseResource(final MongoClient client) {
if(client!= null) {
client.close();
}
}
以下数据操作不区分MongoDB单机模式或集群模式。
public static void insertDoc(final MongoClient mongoClient) {
//插入文档
MongoDatabase database = mongoClient.getDatabase("mydb");
MongoCollection<Document> collection = database.getCollection("test");
Document doc = new Document("name", "MongoDB")
.append("type", "database")
.append("count", 1)
.append("versions", Arrays.asList("v3.2", "v3.0", "v2.6"))
.append("info", new Document("x", 203).append("y", 102));
collection.insertOne(doc);
}
public static void findCollection(MongoCollection<Document> collection){
//遍历集合文档
MongoCursor<Document> cursor = collection.find().iterator();
try {
while (cursor.hasNext()) {
System.out.println(cursor.next().toJson());
}
} finally {
cursor.close();
}
}
public static void updateDoc(MongoCollection<Document> collection){
//更新文档(过滤i=1的文档,并更新为i=100)
collection.updateOne(eq("i", 10), new Document("$set", new Document("i", 110)));
}
public static void deleteDoc(MongoCollection<Document> collection) {
//删除i=100的文档
collection.deleteOne(eq("i", 110));
}
mongodb的shell可以执行javascript脚本,用for循环语句可批量插入文档。
> for(var i = 0;i < 10; i ++){
... db.persion.insert({name: 'tom_'+ i})
... }
> db.persion.find()
{ "_id" : ObjectId("5a6c8a80c70097e60431ebc9"), "name" : "tom_0" }
{ "_id" : ObjectId("5a6c8a80c70097e60431ebca"), "name" : "tom_1" }
{ "_id" : ObjectId("5a6c8a80c70097e60431ebcb"), "name" : "tom_2" }
{ "_id" : ObjectId("5a6c8a80c70097e60431ebcc"), "name" : "tom_3" }
{ "_id" : ObjectId("5a6c8a80c70097e60431ebcd"), "name" : "tom_4" }
{ "_id" : ObjectId("5a6c8a80c70097e60431ebce"), "name" : "tom_5" }
{ "_id" : ObjectId("5a6c8a80c70097e60431ebcf"), "name" : "tom_6" }
{ "_id" : ObjectId("5a6c8a80c70097e60431ebd0"), "name" : "tom_7" }
{ "_id" : ObjectId("5a6c8a80c70097e60431ebd1"), "name" : "tom_8" }
{ "_id" : ObjectId("5a6c8a80c70097e60431ebd2"), "name" : "tom_9" }
>
设置参数为true,当查询不到的时候则自动insert一条数据如果查询到则做update操作
> db.persion.update({_id: 1},{_id: 1, name: 'tom'}, true)
insertOrUpdate之后再加true参数 需要配合$set修改器使用
> db.persion.update({_id: 1},{$set:{_id: 1, name: 'tom'}}, false, true)
表4-1 MongoDB数据库操作参数说明
修改器 |
说明 |
$inc |
对指定的键做加法操作,如果指定的键不存在,则新创建这个键,并且赋值为$inc指定的值 |
$set |
给指定的键赋值,如果指定的键不存在,则自动创建 |
$unset |
清除一个键和值 |
$push |
对数组进行操作,push将一个元素追加到集合的末尾(不管这个元素是否存在于数组中),如果数组不存在,则首先创建数组,如果键值不是数组类型,则会报错 |
$addToSet |
pushAll的去重版本,即$addToSet实现了Java的Set集合的特性(Set中不能包含相同的元素) |
$pop |
从数组中移除一个元素: · {$pop:{"key":1}}从数组末尾删除 · pop:{"key":-1}}从数组开头删除 |
$pull |
删除数组中指定元素 |
$pullAll |
删除数组中多个指定元素 |
$rename |
修改指定键的键名 |
· $inc案例:
> db.persion.insert({name: 'tom', age: 20})
> db.persion.find()
{ "_id" : ObjectId("5a6c93dec70097e60431ebd3"), "name" : "tom", "age" : 20 }
//找到年龄为20的人,加上1
> db.persion.update({age: 20},{$inc:{age: 1}})
> db.persion.find()
{ "_id" : ObjectId("5a6c93dec70097e60431ebd3"), "name" : "tom", "age" : 21 }
· $set案例:
> db.persion.insert({name: 'tom', age: 20})
> db.persion.find()
{ "_id" : ObjectId("5a6c93dec70097e60431ebd3"), "name" : "tom", "age" : 20 }
//更新name: tom -> jack
> db.persion.update({age: 20},{$set:{name: 'jack'}})
> db.persion.find()
{ "_id" : ObjectId("5a6c93dec70097e60431ebd3"), "name" : "jack", "age" : 20 }
· $unset案例:
> db.persion.insert({name: 'tom', age: 20})
> db.persion.find()
{ "_id" : ObjectId("5a6c93dec70097e60431ebd3"), "name" : "tom", "age" : 20 }
//删除name属性
> db.persion.update({age: 20},{$unset:{name: ''}})
> db.persion.find()
{ "_id" : ObjectId("5a6c93dec70097e60431ebd3"), "age" : 20 }
· $push案例:
> db.persion.insert({_id: 1, arr: [1, 2, 3]})
> db.persion.find()
{ "_id" : 1, "arr" : [ 1, 2, 3 ] }
//给arr属性增加一个值
> db.persion.update({_id: 1}, {$push: {arr: 4}})
> db.persion.find()
{ "_id" : 1, "arr" : [ 1, 2, 3, 4 ] }
· $addToSet案例:
{ "_id" : 1, "arr" : [ 1, 2, 3, 4, 5, 6, 7 ] }
> db.persion.update({_id: 1}, {$addToSet: {arr: 1}})
> db.persion.find()
{ "_id" : 1, "arr" : [ 1, 2, 3, 4, 5, 6, 7 ] }
> db.persion.update({_id: 1}, {$addToSet: {arr: 8}})
> db.persion.find()
{ "_id" : 1, "arr" : [ 1, 2, 3, 4, 5, 6, 7, 8 ] }
· $pop案例:
{ "_id" : 1, "arr" : [ 1, 2, 3 ] }
> db.persion.update({_id:1},{$pop:{arr:1}})
> db.persion.find()
{ "_id" : 1, "arr" : [ 1, 2 ] }
>
{ "_id" : 1, "arr" : [ 1, 2, 3 ] }
> db.persion.update({_id:1},{$pop:{arr:-1}})
> db.persion.find()
{ "_id" : 1, "arr" : [ 2, 3 ] }
>
· $pull案例:
{ "_id" : 1, "arr" : [ 1, 2, 3 ] }
> db.persion.update({_id:1},{$pull:{arr:2}})
> db.persion.find()
{ "_id" : 1, "arr" : [ 1, 3 ] }
>
· $pullAll案例:
{ "_id" : 1, "arr" : [ 1, 2, 3 ] }
> db.persion.update({_id:1},{$pullAll:{arr:[2,3]}})
> db.persion.find()
{ "_id" : 1, "arr" : [ 1 ] }
>
· $rename案例:
{ "_id" : 1, "arr" : [ 1, 2, 3 ] }
> db.persion.update({_id:1},{$rename:{arr:'arr2'}})
> db.persion.find()
{ "_id" : 1, "arr2" : [ 1 ] }
>
MongoDB中聚合主要用于处理数据(诸如统计平均值,求和等),并返回计算后的数据结果。
表4-2 MongoDB聚合操作参数相关说明
条件符 |
功能 |
示例 |
说明 |
$ sum |
求和 |
db.persion.aggregate([{$group: {_id: '$age', num_total: {$sum: '$age'}}}]) |
以age为_id,求所有age相同的数据中age的总和 |
$ avg |
平均值 |
db.persion.aggregate([{$group: {_id: '$favorite', avg: {$avg: '$age'}}}]) |
以favorite为_id,求所有favorite相同的人的age平均值 |
$ min |
集合中最小值 |
db.presion.aggregate([{$group: {_id: '$favorite', min: {$min: '$age'}}}]) |
以favorite为_id,求favorite相同的人里age最小的 |
$ max |
集合中最大值 |
db.presion.aggregate([{$group: {_id: '$favorite', max: {$max: '$age'}}}]) |
以favorite为_id,求favorite相同的人里age最大的 |
$ push |
在结果文档中插入值到一个数组中 |
db.persion.aggregate([{$group: {_id: '$favorite', _age: {$push: '$age'}}}]) |
统计所有favorite相同的人的age,将其存入_age数组中 |
$ addToSet |
在结果文档中插入值到一个数组中,但不创建副本 |
db.persion.aggregate([{$group: {_id: '$favorite', _age: {$addToSet: '$age'}}}]) |
统计所有favorite相同的人的age,将其存入_age数组中。如果_age数组已存在相同的值则不会存入 |
$ first |
根据资源文档的排序获取第一个文档数据 |
db.persion.aggregate([{$group: {_id: '$favorite', first_name: {$first: '$name'}}}]) |
求相同favorite中第一个出现的人的name |
$ last |
根据资源文档的排序获取第一个文档数据 |
db.persion.aggregate([{$group: {_id: '$favorite', first_name: {$last: '$name'}}}]) |
求相同favorite中最后个出现的人的name |
MongoDB其它常用接口函数,详情请参见官网https://docs.mongodb.com/manual/。
可以通过修改mongodb.conf中的配置参数来调节MongoDB的性能,部分配置参数说明如表5-1所示。
表5-1 MongoDB配置参数说明
参数名称 |
参数说明 |
operationProfiling |
开启慢查询 mode: <string> # 慢查询模式 可选值,off、slowOp、all,,默认值off。建议开启 slowOpThresholdMs: <int> 阈值,默认值100毫秒 slowOpSampleRate: <double> # 随机采集慢查询的百分比值,sampleRate 值默认为1,表示都采集,0.42 表示采集42%的内容 |
systemLog |
日志配置 destination: file path:自定义路径。例如:"/opt/mongodb/logs/mongodb.log" logAppend: 自定义,true/false timeStampFormat: "iso8601-local":日志使用的时间格式,默认为iso8601-local,可选值为ctime、iso8601-utc、iso8601-local |
net |
网络配置 bindIp: "0.0.0.0" 绑定的ip,与bindIpAll 参数是互斥的 bindIpAll: <boolean> 是否绑定本地所有ip,与bindIp参数是互斥的 port: 27017 绑定的端口,分片集群默认值27017(副本集集群默认值为27018) maxIncomingConnections: 500 最大同时连接数,默认值为65536 wireObjectCheck: <boolean> 对客户端的写入进行验证,会有较小的性能影响,默认为 True. |
storage |
数据储存配置 dbPath: "/opt/mongodb/data/" mongod 数据储存的位置 indexBuildRetry: <boolean> mongod 在下次启动重新构建不完整索引,默认为true,不能与replication.replSetName一起使用 repairPath: <string> 当启动数据库修复命令(repair)时,该目录为临时使用的操作目录,将产生操作过程的临时文件。当修复结束后,该目录为空 journal: 数据存储的日志记录功能。 enabled: <boolean> 是否开启journal日志。在64位系统默认为true,在32位系统为false,建议启用 commitIntervalMs: <num> 设置日志储存到磁盘的间隔时间,默认为100毫秒,可以设置为1-500 |
MongoDB默认是不会进行切割日志的,除非我们配置了logRotate =rename,并且重启MongoDB服务,才会进行切割日志的,那么为了避免实际中我们一个日志文件过大,我们需要对日志进行切割,有三个办法:
· 通过MongoDB管理命令进行切割
use admin
db.runCommand({logRotate:1})
使用该命令时需要在MongoDB运行时指定日志文件路径。--logpath [file],或者在配置文件中指定。
· 通过Linux系统自带的服务logrotate进行切割
首先我们需要配置MongoDB参数logRotate = reopen,logappend = true,然后配置Linux系统自带的logrotate。配置文件放置在/etc/logrotate.d/,切割配置文件示例:
/var/log/mongodb/{
rotate 180
daily
size 100M
olddir /opt/mongodb/log/oldlog
copytruncate
dateext
compress
notifempty
missingok
}
· 通过向进程发送SIGUSR1信号来切割日志
如果我们的进程id是19555,那么我们可以通过以下命令来切割日志。只要我们执行了该命令,日志就会立即进行切割。
kill -SIGUSR1 19555
不同款型规格的资料略有差异, 详细信息请向具体销售和400咨询。H3C保留在没有任何通知或提示的情况下对资料内容进行修改的权利!