MongoDB性能优化

MongoDB是一个高性能可扩展基于文档的NoSQL数据库,高性能也需要在多个关键维度的配置,包括硬件、应用模式、模式设计、索引、磁盘I/O等。

存储引擎

WiredTiger是3.0以后的默认存储引擎,细粒度的并发控制和数据压缩提供了更高的性能和存储效率。3.0以前默认的MMAPv1也提高了性能。在MongoDB复制集中可以组合多钟存储引擎,各个实例实现不同的应用需求。

硬件

MongoDB初衷是采用水平扩展构建集群,而不是价格更高的硬件升级。采用复制保证高可用,自动分片使数据均匀分布在各节点服务器上;in-memory计算提供更高的计算性能,该引擎只有企业版有

硬件配置要求

  • 确保内存设置能满足性能需求:确保内存>索引容量+高频访问数据容量,通过storage.wiredTiger.engineConfig.cacheSizeGB或--wiredTigerCacheSizeGB进行设置。通过监控db.serverStatus()命令查看并评估
  • 写操作负载高的应用采用SSD:SATA接口的SSD提供强大的顺序写性能,能提高MongoDB数据和jounal日志文件的写入速度;同时最为强大的是随机读取性能,这点符合MongoDB的数据访问vi 模式。部署采用RAID-10,比RAID-5/RAID-6减少很多限制,并提供更高性能。
  • 存储引擎配置数据压缩和I/O-intensive worloads:WiredTiger存储引擎支持本地压缩,能够更好的使用多核新处理器资源。
  • 为每个MongoDB服务提供专用服务器:在单一服务器上安装多个MongoDB实例,系统会计算每个实例合适的缓存,并为每个实例分配默认的cache_size。通过storage.wiredTiger.engineConfig.cacheSizeGB参数调整。
  • 使用多路查询路由:在不同服务器上使用多个mongos,最好将mongos部署在应用服务器上。
  • 利用多核心:WiredTiger存储引擎是多线程且可以充分利用CPU多核心。MMAPv1存储引擎因为其并发模型,所以并不要求更多的CPU核心。
  • 开启NTP时间同步服务
  • 禁用NUMA:MongoDB运行在NUMA系统上会导致操作问题,禁用NUMA需要配置mermory interleave policy

编写脚本/etc/init.d/pro-startMongo

...

# disable NUMA

sysctl -w vm.zone_reclaim_mode=0

启动时必须指定numactl方式

numactl --interleave=all <path> <options>

  • 禁用THP:Transparent Huge Pages(THP)是Linux内存管理策略会占用大量的内存

编写脚本/etc/init.d/pro-startMongoDB,加入了前面禁用NUMA部分

# disable transparent hugespages
case $1 in
  start)
    if [ -d /sys/kernel/mm/transparent_hugepage ]; then
      thp_path=/sys/kernel/mm/transparent_hugepage
    elif [ -d /sys/kernel/mm/redhat_transparent_hugepage ]; then
      thp_path=/sys/kernel/mm/redhat_transparent_hugepage
    else
      return 0
    fi

    echo ‘never‘ > ${thp_path}/enabled
    echo ‘never‘ > ${thp_path}/defrag

    re=‘^[0-1]+$‘
    if [[ $(cat ${thp_path}/khugepaged/defrag) =~ $re ]]
    then
      # RHEL 7
      echo 0  > ${thp_path}/khugepaged/defrag
    else
      # RHEL 6
      echo ‘no‘ > ${thp_path}/khugepaged/defrag
    fi

    unset re
    unset thp_path

        # disable NUMA
        sysctl -w vm.zone_reclaim_mode=0
    ;;
esac

更改脚本权限并加入自启动

sudo chmod 755 /etc/init.d/pro-startMongo

sudo chkconfig --add pro-startMongo

通过以下测试是否关闭了THP

cat /sys/kernel/mm/transparent_hugepage/enabled

cat /sys/kernel/mm/transparent_hugepage/defrag

如下显示表示成功

always madvise [never]

  • 设置ulimit:默认的ulimit设置太小,以下是推荐设置

-f (file size): unlimited

-t (cpu time): unlimited

-v (virtual memory): unlimited

-n (open files): 64000

-m (memory size): unlimited

-u (processes/threads): 64000

我是新建/etc/security/limits.d/99-mongodb-nproc.conf文件,加入如下配置:

mongod          soft    fsize     unlimited

mongod          hard    fsize     unlimited

mongod          soft    cpu       unlimited

mongod          hard    cpu       unlimited

mongod          soft    as        unlimited

mongod          hard    as        unlimited

mongod          soft    nofile    64000

mongod          hard    nofile    64000

mongod          soft    nproc     64000

mongod          hard    nproc     64000

应用、模式设计

  • 模式设计:关联模式和嵌套模式,见下图,根据应用设计最合理的模式。
  • 文档的key命名尽量短,比如ParkingId可以改为pid。超过16MB,大文档尽量使用GridFS
  • 在集群环境下,避免scatter-gather查询。其实这依赖于sharding的方式和sharding key的选择,要尽量满足大部分的业务需求。
  • 读写分离设计:在读延迟允许范围内,进行读写分离是个不错的选择,可以大大降低主节点压力。
  • 类似关系型数据库,一些优化建议:只查询和更新需要的字段,减少带宽;避免使用否定条件查询;合理使用覆盖索引并考虑最左前缀匹配原则;

硬盘I/O

  • 预读设置:使用blockdev --setra <value>命令设置预读,单位是512B(扇区大小),不少于32kb,也不要设置太大,浪费I/O,设置大的预读有助于顺序读,具体的配置根据业务需求设定。
  • 使用EXT4或者XFS文件系统。不要使用EXT3哦。
  • 禁止Access Time设置。操作系统会维护文件最后的访问时间metadata,对于数据库意味着每次文件系统每访问一个页就会提交一个写操作,这将降低整个数据库的性能。

编辑/etc/fstab文件,指定noatime和nodiratime

/dev/sdb                /data                   ext4    defaults,noatime,nodiratime        1 2

  • 禁用Huges Pages虚拟内存页,MongoDB使用普通虚拟内存页性能更好,这个前面提到过。
  • 使用RAID10,性能高于RAID-5或RAID-6
  • swap设置:设置充足的swap空间防止OOM程序杀掉mongod进程,对于Linux下的MMAPv1存储引擎,不会使用swap空间,可以少量设置swap空间;Windows下的MMAPv1存储引擎需要设置swap空间;WiredTiger存储引擎,需要设置较大的swap空间。使用WiredTiger测试过程中,发现对于大查询,没有足够的swap空间甚至会报错。在/etc/sysctl.conf设置vm.swappiness为0,尽量使用内存。swap分区尽可能大些,以下是一些建议。测试过程中是128G内存,我设置交换分区内存大小也是128G。

  • 日志和数据文件分开存储,日志存储在普通SAS盘上,数据存储在SSD上。数据库的读一般都是随机读,SSD在随机读性能上表现非常好;日志文件主要是顺序写,速度本身较高,而SSD在顺序读写上的表现非常糟糕,而且比普通SATA性能还要低。Mongodb的日志有journal和syslog,journal日志只能放在dbPath下面的journal目录中,而系统日志可以指定日志路径。journal可以挂载个SATA硬盘设备。这样做到日志和数据分离。
  • 多路径设置:设置storage.wiredTiger.engineConfig.directoryForIndexes使索引和数据分离,设置该参数为true后,会在dbPath下面建立一个index目录,在index目录下挂载一个硬盘设备,使索引和数据做到分离。设置directoryPerDB每个数据库不同目录,对于每个目录最好挂载到不同的硬盘设备上。
  • 压缩:WiredTiger提供snappy和zlib两种数据压缩方式。snappy提供压缩比低但是性能损耗低,zlib压缩比高但性能损耗较高,通过storage.wiredTiger.collectionConfig.blockCompressor参数设置
时间: 2024-10-07 13:29:44

MongoDB性能优化的相关文章

MongoDB性能优化五个简单步骤

大家在使用MongoDB的时候有没有碰到过性能问题呢?这里总结了MongoDB性能优化的五个步骤,希望能够有所帮助. 第一步:找出慢语句 一般来说查询语句太慢和性能问题瓶颈有着直接的关系,所以可以用MongoDB的性能分析工具来找出这些慢语句: db.setProfilingLevel(1, 100); 第二步:使用explain分析 通过使用explain来对这些慢语句进行诊断.此外还可以mtools来分析日志. 第三步:创建索引 分析完之后需要创建新的索引(index)来提升查询的性能.别忘

MongoDB性能优化指南

一.索引 MongoDB 提供了多样性的索引支持,索引信息被保存在system.indexes 中,且默认总是为_id创建索引,它的索引使用基本和MySQL 等关系型数据库一样.其实可以这样说说,索引是凌驾于数据存储系统之上的另一层系统,所以各种结构迥异的存储都有相同或相似的索引实现及使用接口并不足为 奇. 1.基础索引 在字段age 上创建索引,1(升序);-1(降序): db.users.ensureIndex({age:1}) _id 是创建表的时候自动创建的索引,此索引是不能够删除的.当

开发高性能的MongoDB应用—浅谈MongoDB性能优化(转)

出处:http://www.cnblogs.com/mokafamily/p/4102829.html 性能与用户量 “如何能让软件拥有更高的性能?”,我想这是一个大部分开发者都思考过的问题.性能往往决定了一个软件的质量,如果你开发的是一个互联网产品,那么你的产品性能将更加受到考验,因为你面对的是广大的互联网用户,他们可不是那么有耐心的.严重点说,页面的加载速度每增加一秒也许都会使你失去一部分用户,也就是说,加载速度和用户量是成反比的.那么用户能够接受的加载速度到底是多少呢? 如图,如果页面加载

开发高性能的MongoDB应用—浅谈MongoDB性能优化

关联文章索引: 大数据时代的数据存储,非关系型数据库MongoDB(一) 性能与用户量 “如何能让软件拥有更高的性能?”,我想这是一个大部分开发者都思考过的问题.性能往往决定了一个软件的质量,如果你开发的是一个互联网产品,那么你的产品性能将更加受到考验,因为你面对的是广大的互联网用户,他们可不是那么有耐心的.严重点说,页面的加载速度每增加一秒也许都会使你失去一部分用户,也就是说,加载速度和用户量是成反比的.那么用户能够接受的加载速度到底是多少呢? 如图,如果页面加载时间超过10s那么用户就会离开

【MongoDB】MongoDB 性能优化 - BI查询聚合

在BI服务中通过查询聚合语句分析定位慢查询/聚合分析,小结如下: 慢查询定位: 通过Profile分析慢查询 对于查询优化: 通过添加相应索引提升查询速度: 对于聚合大数据方案: 首先要说明的一个问题是,对于OLAP型的操作,期望不应该太高.毕竟是对于大量数据的操作,光从IO就已经远超通常的OLTP操作,所以要求达到OLTP操作的速度和并发是不现实的,也是没有意义的.但并不是说一点优化空间也没有. 这样优化之后预计在可以提升一部分查询性能,但是并不能解决.原因开头说了,对OLAP就不能期望这么高

【转】mongodb可以通过profile来监控数据 (mongodb性能优化)

开启 Profiling  功能 ,对慢查询进行优化: mongodb可以通过profile来监控数据,进行优化. 查看当前是否开启profile功能用命令 db.getProfilingLevel()  返回level等级,值为0|1|2,分别代表意思:0代表关闭,1代表记录慢命令,2代表全部 db.setProfilingLevel(level);  #level等级,值同上 level为1的时候,慢命令默认值为100ms,更改为db.setProfilingLevel(level,slow

Mysql数据库性能优化(一)

参考 http://www.jb51.net/article/82254.htm 今天,数据库的操作越来越成为整个应用的性能瓶颈了,这点对于Web应用尤其明显.关于数据库的性能,这并不只是DBA才需要担心的事,而这更是我们程序员需要去关注的事情.当我们去设计数据库表结构,对操作数据库时(尤其是查表时的SQL语句),我们都需要注意数据操作的性能.这里,我们不会讲过多的SQL语句的优化,而只是针对MySQL这一Web应用最多的数据库. mysql的性能优化无法一蹴而就,必须一步一步慢慢来,从各个方面

java架构师、高性能、高并发、高可用、高可扩展、性能优化、集群、电商网站架构

15套java架构师.集群.高可用.高可扩展.高性能.高并发.性能优化.Spring boot.Redis.ActiveMQ.Nginx.Mycat.Netty.Jvm大型分布式项目实战视频教程 视频课程内容包含: 高级Java架构师包含:Spring boot.Spring  cloud.Dubbo.Redis.ActiveMQ.Nginx.Mycat.Spring.MongoDB.ZeroMQ.Git.Nosql.Jvm.Mecached.Netty.Nio.Mina.性能调优.高并发.to

15套java互联网架构师、高并发、集群、负载均衡、高可用、数据库设计、缓存、性能优化、大型分布式 项目实战视频教程

* { font-family: "Microsoft YaHei" !important } h1 { color: #FF0 } 15套java架构师.集群.高可用.高可扩 展.高性能.高并发.性能优化.Spring boot.Redis.ActiveMQ.Nginx.Mycat.Netty.Jvm大型分布 式项目实战视频教程 视频课程包含: 高级Java架构师包含:Spring boot.Spring  cloud.Dubbo.Redis.ActiveMQ.Nginx.Mycat