MongoDB的奇怪插入时间

时间:2014-09-18 04:42:41

标签: performance mongodb mongodb-.net-driver

我需要节省大量的传感器测量值,并且我在MongoDB上做了一些基准测试。

数据: 这是我正在使用的“架构”:

public class BetterConsolidatedTag
{
    public ObjectId Id { get; set; }

    /// <summary>
    /// The base time to which the offset values relate.
    /// </summary>
    public DateTime BaseTime { get; set; }

    /// <summary>
    /// The name of the data series
    /// </summary>
    public string Name { get; set; }

    /// <summary>
    /// Values of the series in this time frame. The values are saved as offsets in milliseconds from the BaseTime.
    /// </summary>
    [BsonElement]
    private SortedDictionary<int, object> OffsetValues { get; set; }
}

我们的想法是,不是自己保存每个测量值,而是在一小时内整合特定传感器的所有测量值。因此,每个文档代表一小时内特定传感器的所有测量值,从BaseTime开始。 定义了两个索引:BaseTime_1_Name_1和Name_1_BaseTime_1。

数据库 MongoDB使用以下硬件在Windows Server 2012 R2 Standard上运行:

  • 处理器:Intel(R)Xeon(R)CPU X5675 @ 3.07GHz,3059 Mhz,6 Core(s),12个逻辑处理器
  • RAM:96GB
  • 磁盘:带有RAID 1的300GB本地磁盘(IBM ServeRAID M5015)
  • 网络:英特尔®82575EB千兆以太网控制器

基准 为简单起见,我的模拟以恒定速率生成数据 - 我生成的数据代表所有不同传感器的一小时并将其保存到数据库中。我记录了保存这个一小时数据所需的时间(如上所述,每次都包含相同数量的样本)。 数据生成在我的桌面上(Windows 7 Enterprise,i7,8GB RAM,SSD),它使用官方的MongoDB C#驱动程序通过网络将数据发送到MongoDB服务器。测试期间我没有对桌面做任何特别的事情 - 主要是互联网浏览和不时在Excel中绘制测量值。在此期间,除了我之外没有人连接到远程服务器,在基准测试期间没有人将我的基准测试连接到MongoDB。

结果 这是一个图表,描绘了插入时间(以毫秒为单位)与数据库中样本总数的函数关系(数据库的总大小约为200GB,保存在101个文件中): Sensor data insertion time

并进行一些缩放: Sensor data insertion time zoomed to lower values 我无法理解这些结果。我预计插入时间会随着时间的推移略有增长 - 有两个索引,随着文档数量的增加,预计维护这些索引的时间会更长。此外,我预计一旦数据不再适合物理内存并且分页开始更频繁地发生,插入时间应该变得更高,但是图形看起来并不像事情变得更糟的时间点。 我真正不明白的是为什么这个图看起来好像它是由三个不同的图组成的 -   - 一个生长非常缓慢,并且几乎保存所有数据点的(这是我期望的所有结果看起来像)   - 一个增长得更快并保持更少分数的一个(也许这些是分页发生的时间?但是在物理内存被填满的时候,它会在图中出现“跳跃”) - 一个疯狂增长并拥有大约40个数据点的人。这些数据点似乎以大约每15分钟的恒定速率发生。我想也许这些是MongoDB创建一个新文件的时间,但数据保存在101个文件中,而这些奇怪的测量只有大约40个。

这些结果有意义吗?如果没有,可能是什么问题?我应该在服务器上寻找神秘的后台工作吗?硬件问题?

编辑:高点对应于文件创建没有意义,因为随着数据变大,创建文件不会花费更多时间。也许MongoDB在后台做了某种压缩?大部分时间都是小的压缩(第二个“图形”,有时是完全压缩(第三个和最高的“图形”)。随着数据变大,压缩需要更长时间。或者垃圾收集,这可能是有意义的。我猜也可以用这种行为来表示吗?

编辑2 :嗯,MongoDB是用C ++编写的,所以我猜GC是不可能的。所以现在背景压缩是我最好的猜测。

1 个答案:

答案 0 :(得分:2)

默认情况下,MongoDB会在一分钟内执行一次fsync,因此一旦一分钟就会有更慢的插入 - 这是数据实际保存到磁盘的时间点,剩下的时间就是“#”。 s仅保存在内存中。将其设置为每秒同步数据(如果可能,则在每次写入时),图形看起来会有所不同。