Mongo DB优化
一、环境配置
描述 | 详情 | 备注 |
---|---|---|
Mongo DB 版本 | 7.0.3 | |
Mongo 服务器内存 | 32G | |
Java应用服务器内存 | 32G |
二、问题描述
每天至少15亿的数据,对每分钟约120万的数据进行统计并实时写入Mongo。
理想的效果是:60s的数据60s内写入到Mongo当中。
目前差距较大,当库的数据量与cache size基本持平后,此后的数据写入,60s的数据平均约需要120s才能完整写入到Mongo当中。
三、分析指标
以下是一些参数指标的说明
IOPS(Input/Output Operations Per Second)
在数据库管理中,IOPS
这个术语,也就是每秒处理的I/O请求数量。IOPS
对数据库性能的影响很大,如果IOPS
过高,会导致数据库性能下降并增加响应的延迟时间。
- 优化磁盘
数据库IOPS过高可能与磁盘的性能有关。如果磁盘性能不佳,那么IOPS就会过高,这会对数据库性能产生负面影响。因此,通过采用优化的磁盘可以解决IOPS过高的问题。
一种优化磁盘的方法是使用RD(冗余磁盘阵列)技术。RD可以将多个磁盘组合在一起,以提高性能和可靠性。例如,RD 10可以将四个磁盘相互组合,提供较高的性能和更好的可靠性。此外,选择更快的磁盘(如SSD)也可以提高IOPS的性能。- 优化查询
一个常见的原因导致IOPS过高是过多和复杂的查询。执行大量和复杂的查询需要大量的I/O操作,从而导致IOPS过高。因此,可以采取优化查询的方法来减少IOPS的使用情况。
一种优化查询的方法是创建索引。索引可以提高查询性能,从而减少IOPS的使用。在确保需要创建的索引时,可以使用覆盖索引来代替查询,这可以减少查询时间和IOPS的使用。此外,可以避免使用不必要的SQL命令,并尽量减少数据库访问量,从而减少IOPS。- 优化缓存
为了保证数据库可以在需要时快速响应,通常都会缓存查询结果。然而,如果缓存未正确优化,将会导致IOPS过高。
一种优化缓存的方法是使用高速缓存。缓存可以减少数据库I/O并快速响应查询,从而减少IOPS。另外,合理设置缓存锁定策略可以确保数据库在访问大量数据时仍能高效运行。- 升级系统
如果使用的是旧的数据库系统,可能由于系统限制导致IOPS过高。在这种情况下,升级系统可能是解决IOPS过高问题的更佳方法。
升级系统可以提高磁盘性能并增加系统的内存容量。这可以改善数据库的性能,并减少IOPS的使用。
IOPS是数据库管理中一个重要的指标。IOPS过高可能会导致数据库性能下降。在解决IOPS过高问题时,需要优化磁盘、查询、缓存和系统。优化这些因素可以提高IOPS的性能并减少数据库性能下降的可能性。
连接质量
连接数
内存相关参数
cache size
在admin数据库查看当前内存情况
use admin;
db.serverStatus().wiredTiger.cache['maximum bytes configured']/1024/1024/1024;
# 输出 表示10G
20
# 内存使用情况
db.serverStatus().mem
# 输出
{ bits: 64, resident: 17978, virtual: 22889, supported: true }
缓存命中率
Write Concern
在MongoDB中,WriteConcern用于设置写操作的确认级别,它决定了在写入数据到数据库之前需要满足的复制集成员确认数量。不同的WriteConcern级别会影响数据的持久性和可用性。
以下是几种常见的WriteConcern选项:
- W1: 表示写操作至少需要从一个复制集成员(通常是主节点)那里得到确认。这是默认设置,提供了一定程度的数据安全,但不是最严格的。
- W2: 表示写操作需要从至少两个复制集成员那里得到确认。这增加了数据的安全性,因为即使主节点失败,仍有其他节点确认了写操作。
- W3: 类似地,W3要求至少三个成员确认。这进一步提高了数据的可靠性,适用于需要更高一致性的场景。
- UNACKNOWLEDGED: 也称为w:0,写操作不等待任何确认。这提供了最高的写操作速度,但数据可能丢失,因为没有确认,无法保证数据已写入。
- JOURNALED: 这个选项要求写操作在被写入到日志之前返回成功。这样即使在写入到数据文件之前服务器崩溃,数据也能通过日志恢复。
- MAJORITY: 写操作需要被大多数复制集成员确认。这提供了最高的数据一致性,因为即使主节点失败,大多数节点已经确认了写操作,数据不会丢失
// Java中设置WriteConcern
MongoTemplate mongoTemplate = new MongoTemplate(mongoClient, mongoDatabase);
mongoTemplate.setWriteConcern(WriteConcern.W1);
Retry Writes
ticket
查看并发写ticket和并发读ticket的使用情况
db.serverStatus().wiredTiger.concurrentTransactions
示例
{
write: {
out: 0,
available: 7,
totalTickets: 7,
immediatePriorityAdmissionsCount: Long('3590106'),
addedToQueue: Long('357309'),
removedFromQueue: Long('357309'),
queueLength: Long('0'),
startedProcessing: Long('14629553'),
processing: Long('0'),
finishedProcessing: Long('14629553'),
totalTimeProcessingMicros: Long('4890553838'),
canceled: Long('0'),
newAdmissions: Long('31788'),
totalTimeQueuedMicros: Long('25766074')
},
read: {
out: 0,
available: 7,
totalTickets: 7,
immediatePriorityAdmissionsCount: Long('7720779'),
addedToQueue: Long('0'),
removedFromQueue: Long('0'),
queueLength: Long('0'),
startedProcessing: Long('16459'),
processing: Long('0'),
finishedProcessing: Long('16459'),
totalTimeProcessingMicros: Long('52406818'),
canceled: Long('0'),
newAdmissions: Long('6118'),
totalTimeQueuedMicros: Long('0')
},
monitor: {
timesDecreased: Long('0'),
timesIncreased: Long('2293'),
totalAmountDecreased: Long('0'),
totalAmountIncreased: Long('787')
}
}
修改
db.adminCommand( { setParameter: 1,wiredTigerConcurrentReadTransactions: 128 )
db.adminCommand( { setParameter: 1,wiredTigerConcurrentWriteTransactions: 128} )
wiredTigerCacheSizeGB
storage.wiredTiger.engineConfig.cacheSizeGB
db.serverStatus().wiredTiger.concurrentTransactions
查看wt缓存信息
db.serverStatus().wiredTiger.cache
oplog
主节点
rs.printReplicationInfo()
从节点
rs.printSecondaryReplicationInfo()
四、分析手段
tcmalloc
db.serverStatus().tcmalloc
{
generic: {
current_allocated_bytes: Long('17552072896'),
heap_size: Long('23869124608')
},
tcmalloc: {
pageheap_free_bytes: 406224896,
pageheap_unmapped_bytes: Long('4862578688'),
max_total_thread_cache_bytes: 1073741824,
current_total_thread_cache_bytes: 431320072,
total_free_bytes: 1048248128,
central_cache_free_bytes: 616902712,
transfer_cache_free_bytes: 25344,
thread_cache_free_bytes: 431320072,
aggressive_memory_decommit: 0,
pageheap_committed_bytes: Long('19006545920'),
pageheap_scavenge_count: 4669875,
pageheap_commit_count: 7313135,
pageheap_total_commit_bytes: Long('1652114251776'),
pageheap_decommit_count: 4669875,
pageheap_total_decommit_bytes: Long('1633107705856'),
pageheap_reserve_count: 16721,
pageheap_total_reserve_bytes: Long('23869124608'),
spinlock_total_delay_ns: Long('817709250086'),
release_rate: 1,
formattedString: '------------------------------------------------\n' +
'MALLOC: 17552073344 (16739.0 MiB) Bytes in use by application\n' +
'MALLOC: + 406224896 ( 387.4 MiB) Bytes in page heap freelist\n' +
'MALLOC: + 616902712 ( 588.3 MiB) Bytes in central cache freelist\n' +
'MALLOC: + 25344 ( 0.0 MiB) Bytes in transfer cache freelist\n' +
'MALLOC: + 431319624 ( 411.3 MiB) Bytes in thread cache freelists\n' +
'MALLOC: + 105512960 ( 100.6 MiB) Bytes in malloc metadata\n' +
'MALLOC: ------------\n' +
'MALLOC: = 19112058880 (18226.7 MiB) Actual memory used (physical + swap)\n' +
'MALLOC: + 4862578688 ( 4637.3 MiB) Bytes released to OS (aka unmapped)\n' +
'MALLOC: ------------\n' +
'MALLOC: = 23974637568 (22864.0 MiB) Virtual address space used\n' +
'MALLOC:\n' +
'MALLOC: 1008400 Spans in use\n' +
'MALLOC: 263 Thread heaps in use\n' +
'MALLOC: 4096 Tcmalloc page size\n' +
'------------------------------------------------\n' +
'Call ReleaseFreeMemory() to release freelist memory to the OS (via madvise()).\n' +
'Bytes released to the OS take up virtual address space but no physical memory.\n'
}
}
mongostat
insert query update delete getmore command dirty used flushes vsize res qrw arw net_in net_out conn set repl time
*3737 *0 *4543 *0 0 8|0 5.9% 80.5% 0 21.5G 18.1G 0|2 0|0 2.62k 152k 72 mgset-77648783 SEC May 28 23:35:52.667
*2745 *0 *3413 *0 0 16|0 6.4% 80.6% 0 21.5G 18.1G 0|1 0|0 3.28k 158k 72 mgset-77648783 SEC May 28 23:35:53.667
*3819 1 *4877 *0 0 10|0 6.9% 80.0% 0 21.5G 18.1G 0|14 0|0 2.72k 151k 72 mgset-77648783 SEC May 28 23:35:54.667
*873 *0 *1143 *0 0 4|0 6.3% 80.0% 0 21.5G 18.1G 0|8 0|0 848b 149k 72 mgset-77648783 SEC May 28 23:35:55.662
*2409 *0 *2818 *0 0 16|0 6.5% 80.6% 0 21.5G 18.1G 0|1 0|0 3.88k 158k 72 mgset-77648783 SEC May 28 23:35:56.664
*2253 2 *2733 *0 0 5|0 6.0% 79.9% 0 21.5G 18.1G 0|6 0|0 1.77k 151k 72 mgset-77648783 SEC May 28 23:35:57.662
*3016 *0 *4199 *0 0 8|0 6.9% 80.8% 0 21.5G 18.1G 0|14 0|0 2.66k 151k 72 mgset-77648783 SEC May 28 23:35:58.667
*1919 *0 *2539 *0 0 12|0 5.8% 79.9% 0 21.5G 18.1G 0|8 0|0 2.31k 156k 72 mgset-77648783 SEC May 28 23:35:59.662
*2548 *0 *3288 *0 0 8|0 6.6% 80.4% 0 21.5G 18.1G 0|16 0|0 2.58k 152k 72 mgset-77648783 SEC May 28 23:36:00.666
*1018 *0 *1405 *0 0 4|0 5.8% 80.0% 0 21.5G 18.1G 0|16 0|0 985b 149k 72 mgset-77648783 SEC May 28 23:36:01.662
insert query update delete getmore command dirty used flushes vsize res qrw arw net_in net_out conn set repl time
*3765 *0 *4384 *0 0 8|0 6.5% 79.9% 0 21.5G 18.1G 0|3 0|0 2.62k 152k 72 mgset-77648783 SEC May 28 23:37:12.670
*1412 1 *1653 *0 0 16|0 6.1% 80.2% 0 21.5G 18.1G 0|11 0|0 3.55k 159k 72 mgset-77648783 SEC May 28 23:37:13.667
*2557 1 *3211 *0 0 8|0 5.7% 79.9% 0 21.5G 18.1G 0|13 0|0 2.73k 152k 72 mgset-77648783 SEC May 28 23:37:14.664
*4443 *0 *4636 *0 0 9|0 6.6% 80.0% 0 21.5G 18.1G 0|14 0|0 1.96k 172k 72 mgset-77648783 SEC May 28 23:37:15.665
*768 *0 *930 *0 0 16|0 5.8% 80.0% 0 21.5G 18.1G 0|6 0|0 4.17k 158k 72 mgset-77648783 SEC May 28 23:37:16.666
*5532 *0 *5854 *0 0 5|0 7.0% 80.8% 0 21.5G 18.1G 0|16 0|0 1.16k 150k 72 mgset-77648783 SEC May 28 23:37:17.666
*833 *0 *1108 *0 0 8|0 5.8% 79.9% 0 21.5G 18.1G 0|12 0|0 2.66k 152k 72 mgset-77648783 SEC May 28 23:37:18.670
*4252 1 *4890 *0 0 25|0 6.7% 80.4% 0 21.5G 18.1G 0|13 0|0 3.98k 170k 72 mgset-77648783 SEC May 28 23:37:19.666
*974 *0 *756 *0 0 10|0 6.0% 80.0% 0 21.5G 18.1G 0|16 0|0 2.74k 153k 72 mgset-77648783 SEC May 28 23:37:20.666
*5363 *0 *6098 *0 0 3|0 7.0% 80.4% 0 21.5G 18.1G 0|15 0|0 981b 149k 72 mgset-77648783 SEC May 28 23:37:21.666
insert query update delete getmore command dirty used flushes vsize res qrw arw net_in net_out conn set repl time
*404 *0 *675 *0 0 16|0 5.9% 79.9% 0 21.5G 18.1G 0|14 0|0 3.83k 159k 72 mgset-77648783 SEC May 28 23:37:22.661
*5003 *0 *6848 *0 0 8|0 7.1% 80.7% 0 21.5G 18.1G 0|16 0|0 2.10k 152k 72 mgset-77648783 SEC May 28 23:37:23.663
*572 1 *865 *0 0 8|0 5.9% 79.9% 0 21.5G 18.1G 0|10 0|0 2.72k 152k 72 mgset-77648783 SEC May 28 23:37:24.660
*5095 *0 *6986 *0 0 10|0 7.4% 80.9% 0 21.5G 18.1G 0|16 0|0 2.02k 154k 72 mgset-77648783 SEC May 28 23:37:25.662
*2033 *0 *2511 *0 0 9|0 6.6% 80.0% 0 21.5G 18.1G 0|13 0|0 2.69k 151k 72 mgset-77648783 SEC May 28 23:37:26.669
*722 *0 *1023 *0 0 5|0 5.9% 79.9% 0 21.5G 18.1G 0|2 0|0 1.16k 150k 72 mgset-77648783 SEC May 28 23:37:27.668
*4161 *0 *5720 *0 0 16|0 6.5% 79.9% 0 21.5G 18.1G 0|14 0|0 3.87k 159k 72 mgset-77648783 SEC May 28 23:37:28.663
*2284 *0 *2809 *0 0 3|0 6.6% 80.4% 0 21.5G 18.1G 0|15 0|0 973b 149k 72 mgset-77648783 SEC May 28 23:37:29.664
*4049 *0 *5073 *0 0 10|0 7.0% 79.9% 0 21.5G 18.1G 0|16 0|0 2.75k 153k 72 mgset-77648783 SEC May 28 23:37:30.663
*1373 *0 *2123 *0 0 10|0 6.3% 80.0% 0 21.5G 18.1G 0|13 0|0 2.16k 155k 72 mgset-77648783 SEC May 28 23:37:31.663
mongotop
ns total read write 2024-05-28T23:43:43+08:00
xxx_20240528_6406084 1417ms 0ms 1417ms
xxx_20240528_0725531 1397ms 0ms 1397ms
xxx_20240528_8856946 1387ms 0ms 1387ms
xxx_20240528_0175569 1217ms 0ms 1217ms
xxx_20240528_8646720 1215ms 0ms 1215ms
xxx_20240528_6782718 1210ms 0ms 1210ms
xxx_20240528_6451855 1209ms 0ms 1209ms
xxx_20240528_7605422 1208ms 0ms 1208ms
xxx_20240528_9036211 1207ms 0ms 1207ms
xxx_20240528_9501806 1207ms 0ms 1207ms
ns total read write 2024-05-28T23:43:44+08:00
xxx_20240528_0316213 1037ms 0ms 1037ms
xxx_20240528_5686785 1029ms 0ms 1029ms
xxx_20240528_9556887 1029ms 0ms 1029ms
xxx_20240528_4446114 1028ms 0ms 1028ms
xxx_20240528_4916983 1028ms 0ms 1028ms
xxx_20240528_5316734 1028ms 0ms 1028ms
xxx_20240528_5136207 1027ms 0ms 1027ms
xxx_20240528_6761994 1027ms 0ms 1027ms
xxx_20240528_6976899 1025ms 0ms 1025ms
xxx_20240528_4786826 1018ms 0ms 1018ms
ns total read write 2024-05-28T23:43:45+08:00
xxx_20240528_5086178 1187ms 0ms 1187ms
xxx_20240528_9501806 1177ms 0ms 1177ms
xxx_20240528_5897015 1176ms 0ms 1176ms
xxx_20240528_0116200 1159ms 0ms 1159ms
xxx_20240528_9346970 1152ms 0ms 1152ms
xxx_20240528_4226695 1128ms 0ms 1128ms
xxx_20240528_9436049 1128ms 0ms 1128ms
xxx_20240528_1955099 1125ms 0ms 1125ms
xxx_20240528_8686703 1121ms 0ms 1121ms
xxx_20240528_7056649 1116ms 0ms 1116ms
五、优化方向
- 增加cachesize(这是最直接效果最明显的方式,当然成本也很高哦)
- dirty百分比
- 增加oplog集合大小
- 缓存命中率
- tcmallocReleaseRate(释放速度字段来调节缓存的释放速度tcmallocReleaseRate)
- 操作系统-ulimit
- 操作系统-IO调度算法
六、结论
该文章在草稿箱待了有三个月了,那段时间公司的业务最初期望的是Mongo DB
能够完成任务,但最后无论是怎样的优化都无法达到理想效果。经调研后,还是采用了数据仓库,选用了阿里云的ADB
,Mongo DB
作为辅助手段,仅做一些简单数据统计的存储。
注意:本人是Mongo DB的新手用户,欢迎留言指导,不胜感激!
参考链接
- 链接: 参考文章-如何解决数据库iops过高问题
- 链接: 参考文章-阿里云Mongo DB 最佳实践
- 链接: 参考文章-阿里云数据库Mongo DB版
- 链接: 参考文章-MongoDB的性能问题之MongoDB 磁盘IO高问题
- 链接: 参考文章-阿里云-MongoDB 内存高问题(解释了60%的cachesize)
- 链接: 参考文章-调优mongodb内存设置
- 链接: 参考文章-MONGODB 内存使用分析与判断内存是否缺少
- 链接: 参考文章-千亿级数据迁移 mongodb 成本节省及性能优化实践
- 链接: 参考文章-spring boot 整合 mongodb 高级配置
- 链接: 参考文章-mongodb修改Read/Write tickets
- 链接: 参考文章-MongoDB性能分析之WiredTiger引擎
- 链接: 参考文章-解决MongoDB磁盘IO问题的三种方法
- 链接: 参考文章-阿里云主机SSD实例磁盘测试及IO调度算法调整