首页 > 数据库 >调整 MongoDB 以适应批量加载

调整 MongoDB 以适应批量加载

时间:2024-08-28 09:05:09浏览次数:7  
标签:缓存 target 批量 trigger MongoDB WiredTiger eviction 线程 加载

将几十亿条记录加载到 MongoDB 中,开始时加载速度还不错,但一段时间后就开始明显放缓。通过观察指标进行了一些研究,发现随着时间的推移,WiredTiger 的检查点时间越来越长。检查点时间从最初的几秒到后面的几分钟。在检查点期间,性能基本上是直线下降:

 

WiredTiger检查点

从 MongoDB 4.2 开始,WiredTiger 引擎每 60 秒进行一次全面检查点。这意味着 WiredTiger 缓存中的所有脏页面必须每 60 秒刷新一次到磁盘。请记住,WiredTiger 缓存的默认值是可用内存的 50%,因此我们必须以某种方式限制脏页面的数量,否则就会遭受损失(稍后详述)。

完全检查点会导致性能 “骤降”,有一些方法可以减轻这种影响,但不能完全消除。

顺便说一句,你可能想知道为什么 WiredTiger 的默认缓存值仅为可用内存的 50%,而不是 80-90%。原因是 MongoDB 利用了操作系统的缓存。在 WiredTiger 缓存中,只保留未压缩的页面,而操作系统会在页面(压缩的)写入数据库文件时对其进行缓存。通过为操作系统留出足够的可用内存,我们增加了从操作系统缓冲区获取页面的机会,而不是在页面错误时进行磁盘读取。

 

驱逐过程

驱逐主要是从 WiredTiger 缓存中移除最近使用最少的页面,以便为其他需要尽快访问的页腾出空间。与大多数数据库一样,有专门的后台线程来执行这项工作。让我们看看接下来要调整的可用参数。

 

控制WiredTiger 缓存大小

eviction_trigger=95,eviction_target=80

两个参数表示占 WiredTiger 缓存总量的百分比,并控制整个缓存的使用量。使用量是指干净页和脏页的总和。eviction_trigger默认值是95,即cache_size的95%;eviction_target默认值是80,即cache_size的80%。

 

我们来看一个例子:

假设服务器内存为 200 Gb,WiredTiger 缓存设置为 100 Gb。驱逐线程会尽量将内存使用量控制在 80 Gb 左右(eviction_target)。如果压力过大,缓存使用量增加到高达 95 Gb(eviction_trigger),那么应用程序/客户端线程将被限流。它们会被要求帮助后台线程执行驱逐任务,然后才被允许执行自己的工作,帮助缓解部分压力,代价是增加客户端的延迟。如果这样还不够,缓存达到了配置缓存大小的 100%,操作就会停滞。

 

限制脏页数量

eviction_dirty_trigger=20,eviction_dirty_target=5

这两个参数控制缓存中的脏数据数量。基本上,当脏页的数量达到或超过缓存总大小的 5%,驱逐线程就会介入。脏页面的数量增长到 20%,就会对应用限流,从而增加客户端的延迟。

 

在尖峰或完全检查点中,所有脏页都必须刷新到磁盘上。这将尽可能的耗尽所有磁盘写入能力。这就是为什么会给这些参数设置低默认值,因为我们希望限制数据库在每次检查点时的工作量。

最低可以设置为1%(不支持浮点数值)。在内存较大的服务器上,1% 的使用率还是很高的!现在 256G 的缓存并不罕见,1% 就是 2.56G。每分钟刷新一次。对于磁盘来说,这可能是太多了,这取决于你拥有什么样的硬件。要想进一步减少这一容量,唯一的办法就是减小 WiredTiger 缓存的大小,而这又会带来其他后果。

 

驱逐线程的数量

eviction=(threads_min=4,threads_max=4)

默认情况下,MongoDB 会分配四个后台线程来执行驱逐操作。我们可以选择指定最小和最大线程数,但并不清楚有效线程数是如何确定的。此外,由于某些原因,最大线程数被硬编码为 20。

 

在特殊情况下,默认的 4 个线程不足以跟上脏页的生成速度,Percona 监控和管理 (PMM) 图形就证明了这一点:

 

因此,为了尽量减少夯住,我们需要做的是控制脏页的数量,使检查点所需的时间 “合理”(比方说小于 10 秒)。要知道,更多的线程意味着更多的 IO 带宽和更多的 CPU 资源(由于压缩)。

驱逐调优

在对现有硬件进行了一些实验后,我们决定将驱逐线程数增加到最大 20 个,将脏页阈值降低到 1%到 5%的范围,同时设置一个 1 Gb 的小型 WiredTiger 缓存,这样就能将脏页面数限制在 10-50 Mb。

 

要即时更改设置,我们可以运行以下命令:

db.adminCommand( { "setParameter": 1, "wiredTigerEngineRuntimeConfig": "eviction=(threads_min=20,threads_max=20),checkpoint=(wait=60),eviction_dirty_trigger=5,eviction_dirty_target=1,eviction_trigger=95,eviction_target=80"})

请注意,该命令完成前客户端线程会被阻塞。根据我的经验,通常只需几秒钟,但我也见过在非常繁忙的服务器上需要几分钟的情况。为了安全起见,请计划在维护窗口部署此命令。

 

如果我们想让设置持久化,一种方法是编辑 systemd 单元文件(RH/Centos 上为 /usr/lib/systemd/system/mongod.service),并像下面的示例一样传递 wiredTigerEngineConfigString 参数:

OPTIONS='-f /etc/mongod.conf --wiredTigerEngineConfigString "eviction=(threads_min=20,threads_max=20),eviction_dirty_target=1"'

 

汇总一下

配置

默认值

原理

eviction_target

80

当cachesize已被使用内存超过总内存的百分比到达此值, 那么后台evict线程开始淘汰内存页

eviction_trigger

95

当用掉的内存超过总内存的eviction_trigger, 用户线程也会参数到淘汰内存页工作中

eviction_dirty_target

5

当cachesize中脏数据比例超过该值, 那么后台线程开始将脏数据刷盘

eviction_dirty_trigger

20

当cache中脏数据比例超过该值, 那么用户线程也会参数到淘汰内存页工作中

evict.threads_min|max

4

后台evict线程最小|大数量

 

 

注:这里只是针对单次批量加载做的设置。后期正常业务还是要将cachesize调整成正常值。

 

标签:缓存,target,批量,trigger,MongoDB,WiredTiger,eviction,线程,加载
From: https://www.cnblogs.com/abclife/p/18382577

相关文章

  • shell脚本批量改名
    shell脚本批量修改文件名,遍历文件夹中的*.zip,修改文件名,替换文件名中的abc为test,替换dda为s5  #!/bin/bash#遍历当前目录下所有的.zip文件forfilein*.zip;do#检查文件是否存在,避免空循环if[-f"$file"];then#使用se......
  • Dynamics 365组织服务中的批量操作
    参考原文:https://learn.microsoft.com/en-us/power-apps/developer/data-platform/bulk-operations?tabs=sdk总结版本一次只能批量创建/更新同一个实体的不同记录,不同的还是得走多个。upsert是个丑东西。CreateMultipleRequestcreateMultipleRequest=new(){Targets=en......
  • 怎么快速把多个文件夹的照片批量导出到一个文件夹里?超级好用的三个方法
    在日常工作与生活中,我们经常会遇到需要整理大量照片的情况,尤其是当这些照片分散在多个文件夹中时,手动逐一复制粘贴不仅费时费力,还容易出错。幸运的是,现代科技提供了多种高效便捷的方法来应对这一问题。下面,我将详细介绍三种超级好用的方法,帮助你快速将多个文件夹的照片批量导出......
  • limu|P28|Batch Normalization批量规范化
    目录为什么需要批量规范化困难原因需求如何实现批量规范化公式使用部位为什么卷积层的通道维相当于全连接层的特征维?补充:为什么1*1卷积层相当于逐像素全连接层?深入思考BN的作用代码实现Q&ABatchNorm和LayerNorm的解释与对比为什么需要批量规范化困难训练深层神经网络并使其在较......
  • vue3写一个触底加载hook
    天行健,地势坤--《周易·象传》背景:在一个滚动容器下实现触底加载更多的函数,由于此模块使用的场景较多,因而自己实现了一个滚动加载的hook(顺带尝试了下hook)需求:左侧tab切换时,右侧聊天历史tab要清空并重新请求;右侧触底时,要触发分页请求(如果有);使用dayjs中的fromnow方法以精确体......
  • 图片作为Canvas贴图时要等图片加载完才可以读取canvas
    一、效果二、第一步:canvas.js中封装canvas函数,生成一个canvas对象,标注文字为参数nameunctioncreateCanvas(name){  /**   *创建一个canvas对象,绘制几何图案或添加文字   */  constcanvas=document.createElement("canvas");  constarr=......
  • 图片工具箱:一键批量加水印,守护创意,提升效率!
    前言你是否曾在处理海量图片时,被繁琐的步骤和漫长的等待时间折磨得苦不堪言?是否梦想过拥有一款神器,能让你的图片处理工作变得轻松愉快,从此告别加班的烦恼,迎接升职加薪的曙光?那么,让我向你隆重介绍——图像工具箱!有了这款工具箱,将会发现,原来图像处理可以如此简单高效。它不仅......
  • window环境下关于fMRI的nii文件的预处理的批量代码
    配套fMRI预处理使用。之前预处理忘记删前十秒的文件(为什么要删掉?因为前十秒的文件不稳定),于是59个文件夹不仅要保留删除前十秒还没预处理的文件,还要在每个文件夹里删掉大概一共700个左右的各个预处理步骤遗留下的文件。后面问了chatGPT,写了window脚本挺好用的,省了不少事,这里记录一......
  • Nginx加载Lua环境
    Nginx加载Lua环境开源配置也可以直接部署春哥的开源项⽬OpenResty:http://openresty.org/cn/#安装依赖包[root@linuxprobe]#yuminstall-yreadline-develpcre-developenssl-devel[root@linuxprobe]#cd/soft/src#下载并编译安装openresty[root@linuxprobesrc]#......
  • 用Python给英语单词批量划分音节
    一、问题的缘起最近,有网友在我的视频下面留言,问我可否把英语单词进行音节的划分?我以前也有同样的想法,但是始终没有得到解决。但是,我想使用python,学习英语的人都很多,说不定有人已经编写了类似的模块供我们调用呢?问题截图于是,我就抱着试试看的心情,在网上搜了一下,果然,某搜索......