04 特色及优势
对象模型,快速响应业务变化:
- 多形性:同一个集合中可以包含不同字段(类型)的文档对象。
- 动态性:线上修改数据模式,修改是应用与数据库均无须下线。
- 数据治理:支持使用JSONSchema 来规范数据模式。在保证模式灵活动态的前提下,提供数据治理能力。
快速的开发:
- 只存储在一个存储区读写。
- 反范式、无关联的组织极大优化查询速度。
- 程序 API 自然,开发速度快。
原生的高可用:
- Replica Set - 2 to 50 个成员,建议单数。
- 自恢复。
- 多中心容灾能力。
- 滚动服务,最小化服务终端。
横向扩展能力:
- 需要的时候无缝扩展。
- 应用全透明。
- 多种数据分布策略。
- 轻松支持 TB-PB 数量级。
06 基本操作
tar -xvf dump.tar.gz |
// 插入 |
a <> 1
{a: {$ne: 1}}
a > 1
{a: {$gt: 1}}
a >= 1
{a: {$gte: 1}}
a < 1
{a: {$lt: 1}}
a <= 1
{a: {$lte: 1}}
a=1 OR b=1
{$or: [{a: 1}, {b: 1}]}
a IS NULL
{a: {$exists: false}}
a IS (1,2,3)
{a: {$in: [1, 2, 3]}}
// 同时满足 |
// 投影 projection |
// remove |
08 聚合查询
Aggregation Framework
- Pipeline
- Stage
pipeline = [stage1, stage2, ...] |
- $match 过滤
- $project 投影
- $sort 排序
- $group 分组
- $skip $limit 结果限制
- $lookup 左外连接
09 聚合查询实验
// 计算总合计 |
10 复制集机制及原理
由3个以上具有投票权的节点组成:
- 1个主节点 PRIMARY:接收写入操作和选举时投票。
- 两个或多个从节点 SECONDARY:复制主节点上的新数据和选举时投票。
数据是如何复制的:
- 当一个修改操作,无论是插入、更新或删除,到达主节点时它对数据的操作将被记录下来(经过些必要的转换),这些记录称为 oplog。
- 从节点通过在主节点上打开一个 tailable 游标不断获取新进入主节点的 oplog,并在自己的数据上回放,以此保持跟主节点的数据一致。
通过选举完成故障恢复:
- 具有投票权的节点之间两两互相发送心跳。
- 当5次心跳未收到时判断为节点失联。
- 如果失联的是主节点,从节点会发起选举,选出新的主节点。
- 如果失联的是从节点则不会产生新的选举。
- 选举基于RAFT一致性算法实现,选举成功的必要条件是大多数投票节点存活。
- 复制集中最多可以有50个节点,但具有投票权的节点最多7个。
影响选举的因素:
- 整个集群必须有大多数节点存活。
- 被选举为主节点的节点必须:
- 能够与多数节点建立连接
- 具有较新的 oplog
- 具有较高的优先级(如果有配置)
复制集节点有以下常见的选配项:
- 是否具有投票权(v 参数):有则参与投票。
- 优先级(priority 参数):优先级越高的节点越优先成为主节点。优先级为0的节点无法成为主节点。
- 隐藏(hidden 参数):复制数据,但对应用不可见。隐藏节点可以具有投票仅,但优先级必须为0。
- 延迟(slaveDelay 参数):复制 n 秒之前的数据,保持与主节点的时间差。
复制集注意事项:
- 关于硬件:
- 因为正常的复制集节点都有可能成为主节点,它们的地位是一样的,因此硬件配置上必须致;
- 为了保证节点不会同时岩机,各节点使用的硬件必须具有独立性。
- 关于软件:
- 复制集各节点软件版本必须一致,以避免出现不可预知的问题。
- 增加节点不会增加系统写性能!
11 搭建 MongoDB 复制集
mkdir -p runtime/data_db{1,2,3} && \ |
12 全家桶
13 模型设计基础
- Entity
- Attribute
- Relationship
概念模型 CDM -> 逻辑模型 LDM -> 物理模型 PDM
对象 -> 实体、属性、关系 -> 表结构、字段列表、主外建
14 JSON 文档模型设计
无模式的由来:可以省略无论建模的具体过程,物理模型可省。
设计原则:
- 性能 Performance
- 开发易用 Ease of Development
15 基础设计
集合、字段、基础形状 -> 引用及关联 -> 最终模式
业务需求及逻辑模型 –逻辑导向-> 基础建模 —> 集合、字段、基础形状
一个文档 16MB max.
内嵌为主。
16 工况细化
技术需求、读写比例、方式及数据 –技术导向-> 工况细化 —> 引用及关联
引用模式 $lookup:
db.contacts.aggregate([ |
使用引用方式:
- 内嵌文档太大
- 内嵌文档或数组元素频繁修改
- 内嵌文档数组元素持续增长且没有封顶
使用引用的设计:
- 没有主外键的检查
- $lookup 只支持 left outer join
- $lookup 的关系目标(from)不能是分片表
17 模式套用
经验和学习 –模式导向-> 套用设计模式 -> 优化的模型
时序数据,分桶设计:利用文档内嵌组,将一个时间段的数据聚合到一个文档里。大量减少文档数据量,大量减少索引占用空间。
18 设计模式集锦
大文档,很多字段,很多索引。列转行。列数据变化为数组。多语言多国家属性,类似字段需要建立很多索引。转化为数组,一个索引解决所有查询问题。
模型灵活了,如何管理文档不同版本?增加一个版本字段。schema_version。
统计网页点击流量。近似计算。if random(0,9)==0 increment by 10。
业绩排名、游戏排名等精确统计。消耗资源多,聚合计算时间长。用预聚合字段。模型中直接增加统计字段,每次更新数据时同时更新统计值。
19 写操作事务 writeConcern
{ w: <value>, j: <boolean>, wtimeout: <number> } |
rs.status(); |
// 配置延迟节点,模拟网络延迟 |
20 读操作事务 readPreference
配置:
- mongodb://…/?replicaSet=rs&readPrefence=secondary
- 通过驱动API,MongoCollection.withReadPrefence(ReadPrefence readPref)
- Mongo Shell: db.collection.find({}).readPref(“secondary”)
实验:
// 主节点 |
21 读操作事务 readConcern
enableMajorityReadConcern: true
// 从节点 1、2 |
majority 约为:Read Committed。
22 多文档事务
- Atomocity 原子性
- Consistency 一致性 writeConcern,readConcern
- Isolation 隔离性 readConcern
- Durability 持久性 Journal and Replication
实验启用事务后的隔离性:
db.tx.drop(); |
实验可重复读 Repeatable Read:
db.tx.drop(); |
实验写冲突:
db.tx.drop(); |
- 事务默认 60s 内完成。
- 多文档事务中的读操作必须使用主节点读。
23 Change Stream
类似触发器。
- 触发方式:异步 | 同步(事务保证)
- 触发位置:回调事件 | 数据库触发器
- 触发次数:每个订阅事件的客户端 | 1次
- 故障恢复:从上此断点重新触发 | 事务回滚
基于 oplog 实现。被追踪的变更事件主要包括:
- insert/update/delete
- drop
- rename
- dropDatabase
- invalidate:drop/rename/dropDatabase 将导致 invalidate 被触发,并关闭 chage stream
可重复读。未开启 majority readConcern 的集群无法使用 Change Stream。当集群无法满足 {w: “majority”} 时,不会触发 Change Stream。
可以使用集合管道的过滤步骤过滤事件。
25 分片集群机制及原理
- 路由节点 mongos
- 配置节点 mongod
- 数据节点 mongod
分片集群数据发布方式
- 基于范围 查询性能好,数据分布可能不均匀
- 基于哈希 发布均匀,范围查询效率低;日志、物联网
- Zone 数据天然分区
25 分片集群设计
- 片键 shard key 文档中的一个字段
- 文档 doc
- 块 chunk
- 分片 shard
- 集群 cluster
片键:
- 取值基数范围要大
- 取值范围应尽可能均匀
- 对主要查询要具有定向能力
组合片键。{user_id:1, time:1}
27 分片集群搭建及扩容
# 1 配置域名解析 |
28 监控最佳实践
- MongoDB Ops Manager
- Percona
- 程序脚本
如何获取监控数据:
- db.serverStatus() 从上次开机到现在为止
- db.isMaster()
- monogostats
- db.serverStatus().opcounters
29 备份与恢复
- 延迟节点备份
- 全量备份+Oplog增量,Oplog 幂等性 支持重放
- mongodump –oplog;不遗漏 dump 时的数据
- mongorestore –oplogReplay
31 安全架构
db.createRole({ |
32 安全加固实践
# 禁止脚本执行 |
33 索引机制(一)
- Index、Key、DataPage
- Covered Query/FETCH
- IXSCAN/COLLSCAN 索引扫描/集合扫描
- Big O Notation 时间复杂度
- Query Shape 查询的形状
- Index Prefix 索引前缀
- Selectivity 过滤器 选择区别度大的
- B-数结构
B-树和B+树都是常见的多路搜索树结构,常用于数据库索引和文件系统中。它们的主要区别在于如何存储和检索数据。
B-树是一种自平衡的搜索树,其中每个节点可以存储多个键和对应的值,并支持在O(log n)时间内进行搜索、插入和删除操作。B-树的每个节点都包含了一个子节点数组,可以用来搜索和遍历树。在B-树中,所有节点都可以存储键和值,而非仅仅是叶子节点。
B+树与B-树非常相似,但是只有叶节点包含了所有的键和值,而且所有叶节点都通过指针链接在一起。这意味着在B+树上进行查找只需要搜索一条从根节点到叶节点的路径,而在B-树中可能需要搜索多个节点。B+树的非叶子节点只包含键,而不包含值,这使得B+树在维护索引时更加高效。
因此,B+树比B-树更适用于存储和检索大量数据,尤其是数据库和文件系统中的索引。B+树的叶子节点形成了一个有序链表,可以方便地进行区间查找和遍历。而B-树则更适合内存较小的情况下,例如缓存。
34 索引机制(二)
.explain(true) 查看:
executionTimeMillis
totalDocsExamined
executionStages.docsExamined
executionStages.inputStage.stage
组合索引 ESR 原则,Equal(最前) Sort(中间) Range(最后)
db.member.createIndex({city:1}, {background: true})
36 性能诊断工具
mongostat 了解 MongoDB 运行状态的工具。
- dirty 没有刷盘的比例 <5%
- used
- qrw 排队的请求
- con 连接数量
mongotop 了解集合压力状态
41 应用场景及选型
优点:
- 横向扩展能力,数据量或并发量增加时候架构可以自动扩容
- 灵活模型,适合迭代开发,数据模型多变场景
- JSON 数据结构,适合微服务/REST API
44 关系型数据库迁移
从基于关系型数据库应用迁移到 MongoDB 的理由:
- 高并发需求(数千 - 数十万 ops),关系型数据库不容易扩展
- 快速迭代 - 关系型模式太严谨
- 灵活的 JSON 模式
- 大数据量需求
- 地理位置查询
- 多数据中心跨地域部署
References
– EOF –