一、概述
MongoDB的正式版本都是偶数版本,x.x.x,主要版本(x.x)大约每年升级一次,小版本主要是修复问题,通常1-2个月发布一次。
MongoDB支持原生高可用:Application通过Driver连接到Primary节点,一个Primary节点连接多个Secondary节点。
MongoDB支持水平扩展,分片集群:Driver连接多个Mongos,Mongos连接多个Shard,每个Shard都是一个Primary和多个Secondary。
主要用于实现服务的高可用
MongoDB的复制集主要具备如下特征:
一个典型的复制集由3个以上具有投票权的节点构成,一个Primary接受写入操作和选举时投票,两个Secondary复制Primary节点数据和选举时投票。
一个分片不超过3TB,尽量保证在2TB。常用索引必须容纳进内存。
需要多少个分片?
分片数量=max(所需存储容量/单节点挂载容量, 工作集大小/单服务器内存容量0.6, 并发总量/单节点并发量0.7)
如何选择片键?
mongodump -h HostName:Port -d DatabaseName -c CollectionName
使用--oplog
参数实现增量备份。复制从mongodump从开始执行到完成所有的oplog。会输出到dump/oplog.bson
文件。
mongostore -h HostName:port -d DatabaseName -c CollectionName Filename.bson
使用--oplogReplay
参数实现增量恢复。通过—-oplogLimit
参数和--oplogFile
参数实现特定时间点的恢复。
在分片集群的备份中,多个分片可能在发生数据迁移和均衡,导致备份的数据发生错乱,可以通过停止均衡器解决。
writeConcern参数:决定一个写操作落到多少个节点上才算成功。
用于追踪变更,类似于触发器,基于oplog实现,返回的_id可用于断点恢复,有个cursor进行追踪,推送majority条件的变更。
MongoDB的优势?
支持插件式存储引擎,WiredTiger存储引擎和in-memory存储引擎。
MongoDB支持的数据类型:
什么是mongod,默认参数有哪些?
MySQL和MongoDB的区别:
更新操作会立刻fsync到磁盘?
MongoDB支持的索引类型?
MongoDB在A:{B,C}上建立索引,查询A:{B,C}和A:{C,B}都会使用索引吗?
由于MongoDB索引使用B-tree树原理,只会在A:{B,C}上使用索引。
如果块移动操作(moveChunk)失败了,我需要手动清除部分转移的文档吗?
不需要,移动操作是一致并且是确定的。一次失败后,移动操作会不断重试。当完成后,数据只会出现在新的分片里。
数据在什么时候才会扩展到多个分片里?
MongoDB 分片是基于区域(range)的。所以一个集合(collection)中的所有的对象都被存放到一个块(chunk)中,默认块的大小是 64Mb。当数据容量超过64 Mb,才有可能实施一个迁移,只有当存在不止一个块的时候,才会有多个分片获取数据的选项。
更新一个正在被迁移的块(Chunk)上的文档时会发生什么?
更新操作会立即发生在旧的块(Chunk)上,然后更改才会在所有权转移前复制到新的分片上。
如果一个分片(Shard)停止或很慢的时候,发起一个查询会怎样?
如果一个分片停止了,除非查询设置了 “Partial” 选项,否则查询会返回一个错误。如果一个分片响应很慢,MongoDB 会等待它的响应。
什么是Arbiter?
仲裁节点不维护数据集。 仲裁节点的目的是通过响应其他副本集节点的心跳和选举请求来维护副本集中的仲裁。
复制集节点类型有哪些?
MongoDB是OLTP数据库,原则上MySQL和Oracle能做的事情,MongoDB也都可以。MongoDB具有原生的横向扩展能力,灵活的模型支持,适合快速开发迭代,数据模型多变的场景,并且MongoDB使用了JSON数据结构,非常适合微服务领域。
基于功能的选择:
MongoDB | 传统关系型数据库 | |
---|---|---|
亿级以上的数据量支持 | Easy | 分库分表 |
灵活的表结构 | Easy | 数据字典,关联查询 |
高并发读 | Easy | Hard |
高并发写 | Easy | Hard |
跨地区的集群 | Easy | Hard |
数据分片 | Easy | 中间件 |
地址位置查询 | 完整支持 | PostGreSQL还可以,其他的很麻烦 |
聚合计算 | Easy | GroupBY,复杂的SQL |
异构数据 | Easy | 数据字典,关联查询 |
大、宽表 | Easy | 性能局限 |
基于场景的选择:
移动端应用、小程序
场景特点:基于RESTful API,快速迭代,数据结构频繁变化,大部分功能基于地理信息,爆发式的增长,高可用
业界案例:Keep(说实在的, 健身还不如专门请个私教单独一对一),摩拜单车,ADP
电商的海量商品数据
场景特点:商品信息包罗万象,数据库模式设计困难
业界案例:京东商城,小红书,GAP
内容管理:
场景特点:内容数据多样,扩展困难
业界案例:Adobe AEM,SiteCore
物联网IoT
场景特点:传感器数据结构往往是半结构化数据,传感器实时采集的数据量巨大,容易增长到百亿级别
业界案例:华为、Bosch、MindSphere
SaaS应用
场景特点:多租户模式,需求多变,数据增长快
业界案例:ADP、Teambition
主机分流
场景特点:高性能查询,实时同步机制
业界案例:金融行业
实时在线分析
场景特点:流数据计算,快速计算,秒级响应
业界案例:MongoDB缓存机制、MongoDB聚合框架、微分片架构
关系型迁移到MongoDB承载更多的数据和并发
场景特点:数据增长导致性能低,分库分表方案复杂
业界案例:头条、网易、百度、东航、中行
从传统的关系型数据库迁移到MongoDB需要综合考虑的几个问题:
总体架构
模式设计
表结构整合为JSON文档
SQL语句/存储过程/ORM层
原始SQL
存储过程特性
ORM框架
数据迁移
数据迁移的几个方式:
(1)数据库导出导入,导出JSON或者CSV
(2)ETL批量迁移工具,Kettle、Talend
(3)实时同步工具,infomatica、Tapdata(会运行一个Agent),一般是解析日志模式
(4)应用主动迁移
MongoDB作为Spark的存储方案,MongoDB相比HDFS更加细粒度存储,并且支持结构化存储。MongoDB支持索引机制,使得Spark的读取更加快速,HDFS是一次写,多次读,但是MongoDB适合Spark的读写混合场景。MongoDB是在线式存储,毫秒级的SLA。
MongoDB可以通过BI Connector实现与SQL的结合。BI Connector会自动产生DRDL映射文件,然后我们根据映射文件来编写SQL语句实现数据展示。
BI Connector是企业版的,并且是一个独立的服务。
BI Connector暴露的是MySQL驱动构建的解释器,然后作为一个虚拟的MySQL服务。
容灾级别 | 描述 | RPO | RTO |
---|---|---|---|
Level0 | 无灾备源,只有本地的数据备份 | 24小时 | 4小时 |
Level1 | 本地备份+异地保存,将关键数据保存并送到异地 | 24小时 | 8小时 |
Level2 | 双中心主备,通过网络建立热点备份 | 秒级 | 数分钟到半小时 |
Level3 | 双中心双活,互相进行数据备份 | 秒级 | 秒级 |
Level4 | 双中心双活+异地热备,当一个城市的两个中心不可用时切换 | 秒级 | 分钟级 |
网络层解决方案
GSLB实现MongoDB负载均衡器的健康检查,通过域名实现应用层的切换。
应用层解决方案
使用负载均衡技术,虚拟IP技术,使用同一个Session,使用同一套数据。
使用HAProxy或者Nginx作为本地的SLB本地负载均衡器。
数据库层解决方案
通过日志同步或者存储镜像实现数据拷贝。
复制集跨中心2+2+1解决方案
2+2+1保证了主中心的高可用,oplog同步实现了毫秒级的拷贝。
由于复制集只解决了读取的问题,写入还是要在Primary上进行所以不能够保证几个国家的用户体验。
全球多写本质上是一个特殊的分片集群。将集群中的分片节点分区域部署。要实现全球分片多写,那么要实现以下三点条件:
针对要分片的数据集合,模型中增加一个区域字段。
给集群中的每个分片添加区域标签。
sh.addShardTag("shard0", "Asia");
为每个区域指定属于这个区域的分片块范围。
sh.addShardRange("tableName", {"location": "China"}, "Asia");
全球多写的事务性问题:
当海外用户访问读取数据时,希望是从海外本地读取,因此需要设置readPreference:"nearest"
。
writeConcern:"majority"
。readPreference:"nearset"
就会保证从本地读取就近的数据。writeConcern:"majority"
需要写入大部分节点。当然,MongoDB也可以在国内和海外向Oracle那样同时部署两套集群,通过第三方工具实现同步,中间也需要处理数据冲突问题。常见的中间件有:Tapdata和MongoShake。这两个第三方中间件也是基于oplog的。
tcp_keepalive_time
设置为120秒,容忍网络问题。MongoDB中的索引是特殊结构,索引存储在易于遍历的数据集合中,而且使用BTree结构。
创建索引
db.collection.createIndex(<key>, <option>);
参数 | 数据类型 | 描述 |
---|---|---|
background | Boolean | 创建索引会阻塞数据库操作,可以指定为后台操作。 |
unique | Boolean | 是否建立唯一索引 |
name | String | 索引的名称 |
dropDups | Boolean | 3.0版本废弃,建立索引时是否删除重复记录 |
sparse | Boolean | 对文档中不存在的字段数据不建立索引 |
expireAfterSeconds | Integer | 秒,设定索引的TTL |
v | Index version | 索引的版本号 |
weight | Document | 索引权重值,数值在1-99999之间 |
default_language | String | 对于文本类型的索引,决定了分词器规则,默认为英语 |
language_override | String | 对于文本类型的索引,指定了包含在文档中的字段名 |
查看索引
db.collection.getIndexs();
删除索引
db.collection.dropIndexs();
db.collection.dropIndex();
查看创建过程和终止
db.currentOp();
db.killOp();
使用情况
// 获取索引访问信息
$indexStats
// 返回查询计划
explain()
// 控制索引, 强制MongoDB使用特定索引进行查询
hint()
MongoDB可以在任何字段上创建索引,默认情况下会在_id
字段创建索引,_id
索引时为了防止客户端具有相同的值创建的索引,该索引无法删除。在分片集群中使用_id
索引。
将多个键组合到一起,这样可以加速匹配多个键的查询。
db.collection.createIndex( { <field1>: <type>, <field2>: <type2>, ... } )
MongoDB使用多键索引为数组的每个元素创建索引,多键索引可以建立在字符串、数字、内嵌文档类型的数组上。如果创建的字段包含数组的值,那么MongoDB将会自动确定是否创建索引。
db.coll.createIndex( { <field>: < 1 or -1 > } )
MongoDB机制提供了全文索引类型,支持在集合中搜索字符串。
db.collection.createIndex( { key: "text",key:"text" ..... } )
MongoDB提供权重以及通配符的创建方式。查询方式多个字符串空格隔开,排除查询使用“-”。每个全文索引可以通过设置权重来分配不同的搜索程度,默认权重为1,对于文档中的每个索引字段,MongoDB将匹配数乘以权重并将结果相加。 使用此总和,MongoDB然后计算文档的分数
$text
表达式就无法使用hint()函数散列索引使用散列函数来计算索引字段值的散列值。 散列函数会折叠嵌入的文档并计算整个值的散列值,但不支持多键(即数组)索引。
db.collection.createIndex( { _id: "hashed" } )
散列索引支持使用散列分片键进行分片。 基于散列的分片使用字段的散列索引作为分片键来分割整个分片群集中的数据。
通过在命令行方式加入
--auth
参数或者在配置文件添加authorization: enabled
开启安全选项。使用命令行客户端操作:
mongo -uUsername -pPassword --authenticationDatabase DbName
MongoDB的Role建立在Action和Resource上,Action定义了一种动作,Resource表示某个动作可以操作的资源。MongoDB内置权限角色继承关系图如下:
自定义角色和用户分别可以使用createRole()和createUser()。
MongoDB支持TLS/SSL来加密所有的网络数据传输,不管是内部节点还是客户端到服务器。
审计日志记录到syslog:
--auditDestination syslog
审计日志记录到指定文件:
--auditDestination file --auditFormat JSON --auditPath /path/to/auditLog.json
对删除进行审计:
--auditDestination file --auditFormat JSON --auditPath /path/to/auditLog.json --auditFilter '{atype: {$in: ["dropCollection"]}}'
用于了解MongoDB运行状态的工具。
用于了解集合压力的工具
MongoDB会记录超过100ms的查询,会将执行计划输出。
pip install mtools
常用指令:
https://github.com/rueckstiess/mtools
GridFS是MongoDB的一个子模块,主要用于在MongoDB中存储文件,相当于MongoDB内置的一个分布式文件系统。本质上还是讲文件的数据分块存储在集合中,默认的文件集合分为fs.files
和fs.chunks
。fs.files是存储文件的基本信息,比如文件名,大小,上传时间,MD5等。fs.chunks是存储文件真正数据的地方,一个文件会被分割成多个chunk块进行存储,一般为256KB/个。
GridFS的好处是你不用单独去搭建一个文件系统,直接使用Mongodb自带的即可,备份,分片都依赖MongoDB,维护起来也方便。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。