首页 Linux疑难杂症

[yellowbar] 线上的一个服务在业务繁忙的时间内,客户反应app卡顿严重,经过多次分析,最后排查出MongoDB查询在高并发的场景下速度变得很慢。[/yellowbar]

  • 优化1:

MondoDB作为一款优秀的非关键型数据库,对内存的要求较高,线上服务器的内存为64G,经检查不存在内存不足的情况,但在执行free -h命令中发现使用到了部分swap空间,交换分区的使用会使相关程序处理速度比内存慢很多,因此建议在系统内存完全足够的情况下,我们可以完全关闭swap分区,将交换分区的数据强制刷新到内存上。
相关命令:
free -h swapoff -a

  • 优化2

在我们使用mongo命令连接MongoDB的时候,出现了一些警告信息

1.WARNING: Using the XFS filesystem is strongly recommended with the WiredTiger storage engine(强烈建议使用带WiredTiger存储引擎的XFS文件系统)
报这个错是因为我的服务器使用的是EXT4文件系统,官方不建议
在Linux上运行MongoDB时,官方建议使用Linux内核版本2.6.36或更高版本,使用XFS或EXT4文件系统。 如果可能,最好使用XFS,因为它通常与MongoDB表现更好。
使用WiredTiger存储引擎,强烈建议使用XFS,以避免在使用EXT4与WiredTiger时可能发生的性能问题。
使用MMAPv1存储引擎,MongoDB在使用它们之前预先分配其数据库文件,并经常创建大文件。 因此,官方建议使用XFS或EXT4文件系统。 如果可能,请使用XFS,因为它通常与MongoDB表现更好。
由于服务器文件系统更换比较麻烦,虽然可以挂载新硬盘分区来解决,但我们还是先将此项优化保留

2.WARNING: /sys/kernel/mm/transparent_hugepage/enabled is ‘always’.We suggest setting it to ‘never’
3.WARNING: /sys/kernel/mm/transparent_hugepage/defrag is ‘always’.We suggest setting it to ‘never
这两个问题是CentOS7特有的,因为从CentOS7版本开始会默认启用Transparent Huge Pages(THP)
Transparent Huge Pages(THP)本意是用来提升内存性能,但某些数据库厂商还是建议直接关闭THP(比如说Oracle、MariaDB、MongoDB等),否则可能会导致性能出现下降。
我们可以将相关设置关闭,并重启MongoDB
echo "never" > /sys/kernel/mm/transparent_hugepage/enabled
echo "never" > /sys/kernel/mm/transparent_hugepage/defrag

  • 优化3

经过上面两次优化,卡顿问题并没有明显解决,我们这次从MongoDB内部数据结构入手进行优化。

查看MongoDB日志,发现有许多类似的慢查询:
find { find: "exchange_order_detail", filter: { orderId: "E158399120981952" } } planSummary: COLLSCAN
从图中我们可以发现,在对exchange_order_detail进行查询,筛选器是orderId,planSummary的执行计划是COLLSCAN,进行了最慢的全扫描。
其数据集合的数量已有百万多

> db.getCollection("exchange_order_detail").count()
1167720

我们尝试在exchange_order_detail的orderId字段建立索引,其中1代表正排序,background设置为后台创建,不阻塞现有查询

> db.getCollection("exchange_order_detail").createIndex({"orderId":1},{background: true})
设置完后可以执行以下命令查看索引是否建立:
db.getCollection("exchange_order_detail").getIndexes()
[
    {
        "v" : 2,
        "key" : {
            "_id" : 1
        },
        "name" : "_id_",
        "ns" : "bitrade.exchange_order_detail"
    },
    {
        "v" : 2,
        "key" : {
            "orderId" : 1
        },
        "name" : "orderId_1",
        "ns" : "bitrade.exchange_order_detail",
        "background" : true
    },
    {
        "v" : 2,
        "key" : {
            "time" : 1
        },
        "name" : "time_1",
        "ns" : "bitrade.exchange_order_detail",
        "background" : true
    }
]

看到'orderId'的key索引已经建立,对于其他数据集合的慢查询我们也进行了相应索引优化操作。

[purplebar] 经过索引优化后,日志不再继续打印慢查询了,客户反应卡顿问题已解决!![/purplebar]



文章评论