Professional Documents
Culture Documents
优化实践
OPPO文档数据库MongoDB负责人/杨亚洲
个人介绍
OPPO文档数据库mongodb负责人,前滴滴出行专家工程师,负责万亿
级数据量文档数据库mongodb内核研发及运维工作,mongodb中文社区连续
两期一等奖获得者。
一直专注于分布式缓存、数据库、高性能中间件、KV存储引擎等相
关研发,github账号地址:https://github.com/y123456yz
分享目录
1. 推广经验分享
2. 机房多活实现
3. 性能优化案例
4. 成本优化案例
5. 其他
分享主题一
如何把mongodb从淘汰边缘变为公司主流数据库?
如何把mongodb从淘汰边缘变为公司主流数据库?
入职前mongodb状态:
集群抖动
口碑差
新业务想用不敢用
业务考虑迁移已有mongodb到其他数据库
入职一个月内集群数减少15%
如何把mongodb从淘汰边缘变为公司主流数据库?
我做了什么?
优化集群,解决集群抖动问题
内部分享性能优化方法
给重点业务分享mongodb原理
成立mongodb用户群
业务痛点问题及其解决方案实时用户群同步
如何把mongodb从淘汰边缘变为公司主流数据库?
入职2月后,mongodb公司内部状态:
准备迁走的核心业务继续使用mongodb
大数据量业务开始迁移到mongodb
越来越多部门开始使用mongodb
入职1年后,mongodb相关数据增长:
总集群数增长比例:> 700%
总数据量增长比例:> 2000%
读写流量增长比例:> 550%
mongodb用户群用户数增长比例:> 800%
总结:
mongodb赢得用户信任原因总结: 口碑
分享主题二
当前国内对mongodb误解(丢数据、不安全、难维护)?
当前国内对mongodb误解(丢数据、不安全、难维护)?
业务接入过程中经常咨询的几个问题:
误解一. 丢数据
误解二. 不安全,网上一堆说mongodb被黑客攻击,截图一堆新闻
误解三. DBA吐槽mongodb太难维护
谈谈当前国内对mongodb误解(丢数据、不安全、难维护)?
误解原因:
1. mongodb本身很优秀,但是很多DBA和相应开发把控不住
2. 国内系统性的mongodb资料相对欠缺
分享主题三
mongodb机房多活方案-实现成本、性能、一致性"三丰收"
社区mongodb双向同步方案(放弃该方案)
机房A 机房B
客户端 客户端
oppo互联网mongodb:杨亚洲
放弃该方案原因:
1. 成本高
2. 数据一致性问题
3. 人力原因
方案一:同城三机房多活方案(1mongod+1mongod+1mongod方式)
代理层 A机房mongos
... B机房mongos C机房mongos...
oppo互联网mongodb:杨亚洲
shard-1 shard-n
存储层 A机房 A机房
mongod(主) mongod(主)
1. 代理高可用; 2.任一主机房异常,快速选主
3. nearest就近访问 4. 弊端:异地机房存在跨机房写场景
方案二:同城两机房多活方案(2mongod+2mongod+1arbiter模式)
代理层 A机房mongos
... B机房mongos...
oppo互联网mongodb:杨亚洲
C机房 C机房
A机房 B机房 B机房 mongod A机房 B机房 B机房 mongod
mongod(从) mongod(从) mongod(从) (arbiter) mongod(从) mongod(从) mongod(从) (arbiter)
1. 代理高可用; 2.任一主机房异常,快速选主
3. nearest就近访问 4. 弊端:异地机房存在跨机房写场景
方案三:异地三机房多活方案(1mongod+1mongod+1mongod方式)-解决跨机房写
代理层 A机房mongos
... B机房mongos C机房mongos...
oppo互联网mongodb:杨亚洲
1. 每个机房代理通过打标签的方式,代理转发数据到主节点在本机房的分片上去。
2. A机房数据转发到分片shard-1,B机房数据转发到分片shard-2,C机房数据转发到分片
shard-3。
分享主题四
mongodb线程模型瓶颈及其优化方法
mongodb默认线程模型(一个链接一个线程)
worker线程
oppo互联网mongodb:杨亚洲
线程1
listener线程
client客户端
.. 线程2
创建
新连接fd-n
.. 新连接
fd1 线程
...
.. ...
线程n
说明:
1. listener线程负责接受所有的客户端链接
2. listener线程每接收到一个新的客户端链接就创建一个线程,该线程只负责处理该链接请求处理。
该网络线程模型缺陷:
1. 一个链接创建一个线程,如果10万个链接,那么就需要10万个线程,系统负责、内存消耗也会很多
2. 当链接关闭的时候,线程销毁,频繁的线程创建和消耗进一步增加系统负载
典型案例:
1. mysql默认方式、mongodb同步线程模型配置,适用于请求处理比较耗时的场景,如数据库服务
mongodb默认线程模型(动态线程模型:单队列方式)
worker动态线程池
oppo互联网mongodb:杨亚洲
线程1
状态机调 全局队列
线程2
度模块 ..
client请求 ...
..
锁竞
调度 任务n 任务1
争
...
.. 线程n
说明:
1. 该模型把一次请求转换为多个任务:mongodb数据读操作(网络IO)、db层数据访问(磁盘IO)。
2. 任务入队到全局队列,线程池中的线程从队列中获取任务执行。
3. 同一个请求访问被拆分为多个任务,一次请求可能由多个线程处理。
4. 当任务太多,系统压力大的时候,线程池中线程数动态增加;当任务减少,系统压力减少的时候,线程池中线程数动态减少;
该网络线程模型缺陷:
1. 线程池获取任务执行,有全局锁竞争,这里就会成为系统瓶颈
典型案例:
1. mongodb动态adaptive线程模型,适用于请求处理比较耗时的场景,如数据库服务
mongodb优化后线程模型(动态线程模型-多队列方式)
worker动态线程池
队列1 线程1
任务n
... 任务1 锁1
线程2
...
client请求
队列2 ...
调度
... ...
任务n
...
任务1 锁2
...
. ...
hash散列
. oppo互联网mongodb:杨亚洲
任务n
.
... 任务1
线程n-1
锁3
... 线程n
队列n
说明:
把一个全局队列拆分为多个队列,任务入队的时候按照session链接hash散列到各自的队列,工作线程获取获取任务的时候,同理通过同样的
hash算法去对应的队列获取任务,通过这种方式减少锁竞争,同时提升整体性能。
典型案例:
1. OPPO自研mongodb内核多队列adaptive线程模型优化,特定场景性能有很好的提升,适用于请求处理比较耗时的场景,如数据库服务。
分享主题五
并行迁移-集群扩容速率N倍提升优化实践
集群扩容速率N倍提升优化实践-优化前
client client mongos竞争获取分布式锁 mongod(
client 主)
config
mongod( mongod
从) (从)
oppo互联网mongodb:杨亚洲
源分片列表 扩容新增分片列表
mongod( mongod( mongod( mongod mongod( mongod mongod( mongod( mongod( mongod mongod( mongod
从) 从) 从) (从) 从) (从) 从) 从) 从) (从) 从) (从)
迁移过程:
1. 多个mongos代理竞争分布式锁,获取锁成功的代理选择源分片列表中的一个分片进行moveChunk操作。注意:同一时刻只会迁移一个分片的数据。
2. 缺陷:由于整个集群同一个时刻只能迁移一个分片数据,所以迁移速度很慢。
并行迁移-集群扩容速率N倍提升优化实践(优化后)
clients client client mongod(
主)
config
mongod( mongod
从) (从)
mongos1 mongos2 mongos_n
.....
oppo互联网mongodb:杨亚洲
源分片列表 扩容新增分片列表
mongod( mongod( mongod( mongod mongod( mongod mongod( mongod( mongod( mongod mongod( mongod
从) 从) 从) (从) 从) (从) 从) 从) 从) (从) 从) (从)
并行迁移过程:
1. 在特定代理增加并行迁移配置,该代理可以同时触发迁移源分片列表中多个分片的chunk到目标不同分片。
2. 为了避免冲突和提升迁移速度,同一时刻源分片列表中任一分片只能同时迁移一个chunk。同理,目标分片列表中的分片同一时刻只能接受一个chunk。
分享主题六:性能优化案例
案例1.千亿级核心元数据mongodb集群性能数倍提升优化实践
案例2.万亿级数据量mongodb集群性能数十倍提升优化实践
案例1.千亿级数据量mongodb集群性能数倍提升优化实践-背景
业务背景:
1. 核心元数据
2. 数据量千亿级
3. 前期写多读少,后期读多写少
4. 高峰期读写流量百万级
5. 时延敏感
7. 数据增长快,不定期扩容
8. 同城多活集群
案例1.千亿级数据量mongodb集群性能数倍提升优化实践-优化过程
优化策略1:部署及使用方式优化
1. 预分片,写入负载均衡。
2. WriteConcern:{ w: "majority"},写大部分节点成功才返回客户端OK
3. 读写分离,读从优先。
4. enableMajorityReadConcern关闭,有性能损耗。
案例1.千亿级数据量mongodb集群性能数倍提升优化实践-优化过程
优化策略2:存储引擎cache淘汰策略优化
wiredtiger存储引擎cache淘汰策略相关的几个配置如下:
wiredtiger淘汰相关配置 默认值 工作原理
eviction_target 80% 当用掉的内存超过总内存的百分比
到 eviction_target,后台evict线程开始淘汰
eviction_trigger 95% 当用掉的内存超过总内存的 eviction_trigger,用
户线程也开始淘汰
eviction_dirty_target 5% 当cache中脏数据比例超过 eviction_dirty_target,
后台evict线程开始淘汰
eviction_dirty_trigger 20% 当cache中脏数据比例超过 eviction_dirty_trigger,
用户线程也开始淘汰
evict.threads_min 4 后台evict线程最小线程数
evict.threads_max 4 后台evict线程最小线程数
wiredtiger存储引擎cache淘汰策略优化后配置:
eviction_target: 75%,eviction_trigger:97%,eviction_dirty_target: %3,eviction_dirty_trigger:25%,
evict.threads_min:4,evict.threads_max:16
总体思想:evict线程尽早淘汰脏页page到磁盘,增加evict淘汰线程数加快脏数据淘汰,避免
用户请求线程进行脏数据淘汰。
案例1.千亿级数据量mongodb集群性能数倍提升优化实践-优化过程
优化策略3:存储引擎checkpoint优化
存储引擎checkpoint检测点,把当前存储引擎脏数据全部记录到磁盘。触发条件如下:
1.固定周期做一次checkpoint快照,默认60s
2.增量journal日志达到2G
少部分实例存在如下现象:一会儿磁盘IO几乎空闲0%,一会儿磁盘IO短暂性100%。进行如下优
化后可以缓解该问题:
checkpoint=(wait=30,log_size=1GB)
该优化总体思路:缩短checkpoint周期,减少checkpoint期间积压的脏数据,缓解磁盘IO高问题。
遗留问题:SSD盘只有极少数节点有该问题,原因未知,后续继续跟踪。
案例1.千亿级数据量mongodb集群性能数倍提升优化实践-优化过程
客户端 Client Client Client
代理层 A机房mongos
... B机房mongos C机房mongos...
system.sessions优化:
oppo互联网mongodb:杨亚洲
优化前架构图
存储层
shard-1
A机房mongod .. A机房mongod
shard-n
.
B机房mongod C机房mongod B机房mongod C机房mongod
瓶颈点:
1. 代理缓存所有客户端的链接信息到内存中,并定期更新到config库的system.sessions表中。
2. 大流量大数据量集群客户端链接众多,大量更新sessions表,最终主分片性能下降引起整个集群性能瞬间数倍下
降。
案例1.千亿级数据量mongodb集群性能数倍提升优化实践-优化过程
代理层 A机房mongos
... B机房mongos C机房mongos...
system.sessions优化: oppo互联网mongodb:杨亚洲
优化后架构图
存储层
shard-1
A机房mongod .. A机房mongod
shard-n
.
B机房mongod C机房mongod B机房mongod C机房mongod
优化方法:
1. config库的system.sessions表启用分片功能。
2. mongos定期更新优化为散列到不同时间点进行更新。
案例1.千亿级数据量mongodb集群性能数倍提升优化实践-优化过程
优化策略4:sharding集群system.session优化
该优化总体思路:
1. 之前代理集中式更新单个分片,优化为散列到不同时间点更新多个分片。
2. 该优化后system.sessions表更新引起的瞬间性能数倍降低和大量慢日志问题得到了解决。
案例1.千亿级数据量mongodb集群性能数倍提升优化实践-优化过程
优化策略5:tcmalloc内存优化
db.serverStatus().tcmalloc监控发现部分mongod实例pageheap、内存碎片等消耗过高。通过
系统调用分析得出:内存碎片率、pageheap过高,会引起分配内存过程变慢,引起集群性能严重下
降。
该优化总体思路:
借助gperftools三方库中tcmalloc内存管理模块,实时动态调整tcmalloc内存Release Rate,
尽早释放内存,避免存储引擎获取cache过程阻塞变慢。
案例2.万亿级数据量mongodb集群性能数倍提升优化实践
业务背景:
1. 集群存储离线数据
2. 集群总数据量万亿级
3. 前期主要为数据写入,要求万亿级数据几周内尽快全部写入集群
4. 后期主要是读流量,单次查询数据条数比较多,要求快速返回
5. 每隔一定时间周期(周为单位)会有持续性大量写入
案例2.万亿级数据量mongodb集群性能数倍提升优化实践
优化策略1:基础性优化
分享主题六中读写分离、预分片、wiredtiger存储引擎优化、session优化、tcmalloc
使用优化等基础性优化策略同样适用于该集群,具体详见《分享主题六:百万级高并发读写/千
亿级数据量mongodb集群性能数倍提升优化实践》
案例2.万亿级数据量mongodb集群性能数倍提升优化实践
优化策略2:存储模型优化前状况
优化前数据模型结构如下:
{
"_id": ObjectId("5fh2ebd18856960dbac31abc"),
"characteristic": "xxxx",
"key1": "***",
......
"keyn": "***",
}
1. 以上为单条数据的数据模型,该集群总数据量万亿级。
2. 数十万条数据拥有同样的characteristic特性,总特性数总计数百万个。
3. 一次性查询数十个characteristic很慢。
瓶颈点: 一次性查询数十个characteristic特征条件的数据,每个特征拥有数百万数据,一次查询总计千万行数据。由于数据量很
大,每行数据几乎全在磁盘,一次查询需要千万次IO操作,查询成为瓶颈。
案例2.万亿级数据量mongodb集群性能数倍提升优化实践
优化策略2:第一轮数据存储模型优化:
{
"_id": ObjectId("5f29ebd18856960dbac31abc"),
"characteristic": "xxxx"
"group": [
{
"key1": "***"
......
"keyn": "***"
}, #该characteristic下第一条数据
......
{
"key1": "***"
......
"keyn": "***"
} #该characteristic下第n条数据
]
}
该数据模型把相同characteristic特性的数十万数据合并到为一条数据,减少磁盘IO操作,整个读性能会有近百倍提升。
瓶颈点:该轮优化解决了读瓶颈,却引入了新的写瓶颈。
1. 通过$addToSet方式向group数组中去重追加数据,去重遍历过程越来越慢,数据长度越来越长,写性能成为新的瓶颈。
案例2.万亿级数据量mongodb集群性能数倍提升优化实践
优化策略2:第二轮数据存储模型优化:
{
"_id": ObjectId("5f29ebd18856960dbac31abc"),
"characteristic": "xxxx",
"heshNum": num,
"group": [
{
"key1": "***",
......
"keyn": "***",
}, #该characteristic下第一条数据
......
{
"key1": "***",
......
"keyn": "***",
} #该characteristic下第n条数据
]
}
如上,把同一个characteristic特征的数十万数据散列为500份,这样合并后group数组中也就只包含数百条数据信息,这
样$addToSet去重遍历、合并后单条数据过大、mongodb单条数据64M限制问题等瓶颈问题都可以得到解决。
总体数据模型优化思路:通过合理的数据合并操作来减少网络IO、磁盘IO、mongodb内核处理时间,最终使读和写达到平衡。
分享主题七
成本节省-记某服务千亿级数据迁移mongodb,百台SSD服务器节省优化实践
成本节省-千亿级数据迁移mongodb,百台SSD服务器节省优化实践
迁移背景:
需要迁移的数据量数千亿级
源集群磁盘紧张,业务写入快,需要快速完成数据迁移
源集群数据存储于高io ssd服务器
业务对性能没太高要求
目的mongodb集群采用低io 大容量sata盘
迁移难点:
如何快速完成数据迁移?
成本节省-千亿级数据迁移mongodb,百台SSD服务器节省优化实践
写入快
Client 源集群/SSD
单向同步系统 迁移慢
目的mongo集群/SATA
瓶颈点:
由于目的集群为低io大容量sata盘,迁移太慢,源集群磁盘有写满风险
成本节省-千亿级数据迁移mongodb,百台SSD服务器节省优化实践
写入快
Client 源集群/SSD
单向同步系统 同步快
加载数据
拷贝数
据文件
中转mongo集群/大容量SSD 目标mongo大容量SATA集群
优化策略:
同步数据到大容量SSD中转集群
拷贝中转集群数据到目标大容量SATA盘服务器
加载数据
成本节省-千亿级数据迁移mongodb,百台SSD服务器节省优化实践
成本节省:
mongodb默认的snappy压缩算法压缩比约为2.2-3.5倍
zlib压缩算法压缩比约为4.5-7.5倍(本次迁移采用zlib高压缩算法)
千亿级数据迁移mongodb收益:
源集群磁盘消耗:目的集群磁盘消耗 = 8:1(即使目的mongo集群也用SSD服务器,成本也可以节省七倍)
源集群物理资源:百台SSD服务器
目的mongodb集群资源消耗:6台SATA盘服务器
分享主题八
展望-如何实现mongodb与SQL融合
展望:如何实现mongodb与SQL融合
问题背景:
随着mongodb-4.2版本中对分布式事务的支持,以及mongodb-4.4版本产品规划路线图可以看出,
mongodb除了保持nosql特性外,还在朝着newSql方向前行。但是在实际业务接入中发现以下现象:
1. 开发习惯了SQL,转mongodb语法各种不习惯。
2. 运营和数据分析岗位人员只会写SQL,不会mongo语句。
我们能做什么?
1. mongos代理增加mongodb协议和SQL转换支持,用最小开发成本满足业务SQL需求。
2. 5%-10%左右的SQL协议支持,满足90%的用户需求。
分享主题九
其他-那些年我们踩过的坑
其他-那些年我们踩过的坑
“那些年我们踩过的坑” :
实际业务接入mongodb数据库过程中,我们踩过很多坑,包括业务不合理使用、不合理运维、集群
不合理配置、mongodb内核踩坑、误操作等,甚至出现过同一个核心业务几次抖动。
本次分享中集群优化只列举了主要的优化过程,实际优化过程比本次分享内容更加复杂,集群更
多优化细节及数十例典型踩坑过程将逐步在Qconf平台、OPPO互联网、mongodb中文社区发布。
踩坑不可怕,在踩坑过程中学习,学习过程中减少踩坑