35

我是 NoSQL 世界的新手,正在考虑将我的 MS Sql Server 数据库替换为 MongoDB。我的应用程序(用 .Net C# 编写)与 IP 摄像头交互,并将来自摄像头的每个图像的元数据记录到 MS SQL 数据库中。平均而言,我每天为每个相机插入大约 86400 条记录,并且在当前数据库模式中,我为单独的相机图像创建了单独的表,例如 Camera_1_Images、Camera_2_Images ... Camera_N_Images。单个图像记录由简单的元数据信息组成。像 AutoId、FilePath、CreationDate。为了添加更多细节,我的应用程序为每个摄像头启动单独的进程 (.exe),每个进程每秒在数据库的相关表中插入 1 条记录。

我需要(MongoDB)专家就以下问题提出建议:

  1. 判断 MongoDB 是否适合保存此类数据,最终将针对时间范围进行查询(例如,检索指定小时之间特定相机的所有图像)?关于我的案例基于文档的架构设计有什么建议吗?

  2. 服务器(CPU、RAM、磁盘)的规格应该是什么?有什么建议吗?

  3. 我是否应该考虑在这种情况下进行分片/复制(同时考虑写入同步副本集的性能)?

  4. 在同一台机器上使用多个数据库有什么好处,这样一个数据库将保存所有相机的当天图像,而第二个数据库将用于存档前一天的图像?我正在考虑在单独的数据库上拆分读取和写入。因为所有读取请求都可能由第二个数据库提供服务并写入第一个数据库。它会受益还是没有?如果是,那么任何确保两个数据库始终同步的想法。

欢迎任何其他建议。

4

3 回答 3

30

我自己是 NoSQL 数据库的初学者。因此,我以潜在的反对票为代价来回答这个问题,但这对我来说将是一次很棒的学习经历。

在尽我所能回答您的问题之前,我应该说,如果 MS SQL Server 对您运行良好,那么请坚持下去。您没有提到为什么要使用 MongoDB 的任何正当理由,除了您了解到它是一个面向文档的数据库这一事实。此外,我看到您为每个相机捕获的元数据集几乎相同,即您的模式是动态的。

  • 判断 MongoDB 是否适合保存此类数据,最终将针对时间范围进行查询(例如,检索指定小时之间特定相机的所有图像)?关于我的案例基于文档的架构设计有什么建议吗?

MongoDB 是一个面向文档的数据库,擅长在聚合中查询你称之为文档)。由于您已经将每个摄像头的数据存储在其自己的表中,因此在 MongoDB 中,您将为每个摄像头创建一个单独的集合。以下是您执行日期范围查询的方式。

  • 服务器(CPU、RAM、磁盘)的规格应该是什么?有什么建议吗?

所有 NoSQL 数据库都是为在商品硬件上横向扩展而构建的。但是按照您提出问题的方式,您可能正在考虑通过扩展来提高性能。您可以从一台合理的机器开始,随着负载的增加,您可以继续添加更多服务器(横向扩展)。您无需计划和购买高端服务器。

  • 我是否应该考虑在这种情况下进行分片/复制(同时考虑写入同步副本集的性能)?

MongoDB锁定整个数据库以进行一次写入(但为其他操作产生),并且适用于读取多于写入的系统。所以这取决于你的系统是怎样的。有多种分片方式,并且应该是特定于域的。一个通用的答案是不可能的。但是可以给出一些示例,例如按地理,按分支等进行分片。

另请阅读CAP Theorem 的简单英文介绍

更新了对分片评论的回答

根据他们的文档,您应该考虑部署一个分片集群,如果:

  • 您的数据集接近或超过系统中单个节点的存储容量。
  • 您系统的活动工作集的大小将很快超过系统的最大 RAM 容量。
  • 您的系统有大量的写入活动,单个 MongoDB 实例无法以足够快的速度写入数据以满足需求,并且所有其他方法都没有减少争用。

所以基于最后一点是的。自动分片功能旨在扩展写入。在这种情况下,每个shard都有一个写锁,而不是每个database。但我的答案是理论上的。我建议您从 10gen.com 小组咨询。

于 2012-11-02T08:06:00.097 回答
4

判断 MongoDB 是否适合保存此类数据,最终将针对时间范围进行查询(例如,检索指定小时之间特定相机的所有图像)?

这个问题太主观了,我无法回答。根据对众多 SQL 解决方案(具有讽刺意味的是不是 MS SQL)的个人经验,如果做得好,我会说它们都一样好。

还:

服务器(CPU、RAM、磁盘)的规格应该是什么?有什么建议吗?

取决于太多只有您知道的变量,但是一小部分商品硬件运行良好。我无法对这个问题给出真实的回答,这将归结为您的测试。

至于架构,我会去找一份结构文件:

{
    _id: {},
    camera_name: "my awesome camera",
    images: [
        { 
            url: "http://I_like_S3_here.amazons3.com/my_image.png" ,
            // All your other fields per image
        }
    ]
}

这应该很容易维护和更新,只要您没有嵌入更深的内容,从那时起它可能会变得有点痛苦,但这取决于您的查询。

不仅如此,这应该有利于分片,因为你在一个文档中拥有你需要的所有数据,如果你要分片,_id你可能会在这里得到完美的设置。

我是否应该考虑在这种情况下进行分片/复制(同时考虑写入同步副本集的性能)?

可能许多人认为他们需要分片,而实际上他们只需要更智能地设计数据库。MongoDB 是非常自由的形式,所以有很多方法可以做错,但话虽如此,也有很多方法可以做对。我个人会牢记分片。复制也非常有用。

在同一台机器上使用多个数据库有什么好处,这样一个数据库将保存所有相机的当天图像,而第二个数据库将用于存档前一天的图像?

即使 MongoDB 的写锁处于数据库级别(当前),我会说:不。正确的文档结构和正确的分片/复制(如果需要)应该能够在单个基于文档的集合中处理这个问题D B。不仅如此,您还可以将集群内的写入和读取定向到某些服务器,从而在集群中的某些机器之间创建并发情况。我会提倡正确使用 MongoDB 的并发特性而不是 DB 分离。

编辑

再次阅读问题后,我从我的解决方案中省略了您每天为每台相机插入 80k+ 图像。因此,我实际上会在一个名为的集合中为每个图像创建一行images,然后是一个camera集合,并像在 SQL 中那样查询这两个选项,而不是嵌入选项。

images集合进行分片应该同样容易camera_id

还要确保将您的工作集考虑到您的服务器。

于 2012-11-02T08:33:49.493 回答
3

判断 MongoDB 是否适合保存此类数据,最终将针对时间范围进行查询(例如,检索指定小时之间特定相机的所有图像)?关于我的案例基于文档的架构设计有什么建议吗?

MongoDB 可以做到这一点。为了获得更好的性能,您可以在时间字段上设置索引。

服务器(CPU、RAM、磁盘)的规格应该是什么?有什么建议吗?

我认为RAM和磁盘很重要。

  • 如果您不想这样做shardingscale out您应该考虑更大的磁盘大小,以便您可以将所有数据存储在其中。
  • 您的热数据应该可以放入您的 RAM。如果不是,那么您应该考虑更大的 RAM,因为 MongoDB 的性能主要取决于 RAM。

我是否应该考虑在这种情况下进行分片/复制(同时考虑写入同步副本集的性能)?

我不知道你有多少摄像头,即使是每秒 1000 次插入,总共 1000 个摄像头对 MongoDB 来说仍然很容易。如果您关心插入性能,我认为您不需要进行分片(除非数据量太大,您必须将它们分成几台机器)。

另一个问题是应用程序的读取频率。它非常高,那么您可以在这里考虑分片或复制。如果您只在一个时间范围内的一台相机上查询,您可以使用 (timestamp + camera_id) 作为您的分片键。

在同一台机器上使用多个数据库有什么好处,这样一个数据库将保存所有相机的当天图像,而第二个数据库将用于存档前一天的图像?

您可以将表格分成两个集合(archivecurrent)。archive如果您只查询日期,则仅设置索引archive。如果没有索引创建的开销,current集合应该受益于插入。

您可以编写一个日常程序将current数据转储到archive.

于 2012-11-02T14:33:53.893 回答