MongoDB:单机分片。是不是有意义?
Posted
技术标签:
【中文标题】MongoDB:单机分片。是不是有意义?【英文标题】:MongoDB: Sharding on single machine. Does it make sense?MongoDB:单机分片。是否有意义? 【发布时间】:2011-09-22 14:03:54 【问题描述】:在 MongoDB 中创建了一个包含 11446615 个文档的集合。
每个文档都有以下形式:
"_id" : ObjectId("4e03dec7c3c365f574820835"),
"httpReferer" : "http://www.somewebsite.pl/art.php?id=13321&b=1",
"words" : ["SEX", "DRUGS", "ROCKNROLL", "WHATEVER"],
"howMany" : 3
httpReferer:只是一个网址
单词:从上面的 url 解析的单词。列表的大小在 15 到 90 之间。
我打算使用这个数据库来获取具有相似内容的网页列表。
我将使用 words 字段查询此集合,因此我在此字段上创建(或者更确切地说开始创建)索引:
db.my_coll.ensureIndex(words: 1)
创建此集合需要很长时间。我尝试了两种方法(以下测试是在我的笔记本电脑上完成的):
-
插入和索引 插入耗时 5.5 小时,主要是由于 cpu 密集型数据预处理。编制索引耗时 30 小时。
插入前的索引 将所有数据插入到集合中需要几天时间。
我的主要关注点是减少生成集合的时间。我不需要复制(至少现在)。查询也不必非常快。
现在,是时候提问了:
我只有一台机器和一个磁盘,我可以运行我的应用程序。运行多个数据库实例并在它们之间拆分我的数据是否有意义?
【问题讨论】:
【参考方案1】:在现代(2015 年) 使用 mongodb v3.0.x 时使用 mmap 进行集合级锁定,这会略微增加写入吞吐量(假设您写入多个集合),但如果您使用Wiredtiger 引擎有文档级锁定,具有更高的写入吞吐量。这消除了在单台机器上进行分片的需要。尽管从技术上讲,您仍然可以通过在单台机器上进行分片来提高 mapReduce 的性能,但在这种情况下,您最好只使用可以利用多核的聚合框架。如果您严重依赖 map reduce 算法,那么使用 Hadoop 之类的东西可能最有意义。
对 mongodb 进行分片的唯一原因是水平扩展。因此,如果单台机器无法容纳足够的磁盘空间、内存或 CPU 能力(很少见),那么分片就会变得有利。我认为很少有人有足够的数据进行分片,即使是大型企业,尤其是因为wiredtiger添加了压缩支持,可以将磁盘使用量减少80%以上。也很少有人使用 mongodb 来大规模地执行真正的 CPU 繁重的查询,因为有更好的技术可以做到这一点。在大多数情况下,IO 是影响性能的最重要因素,没有多少查询是 CPU 密集型的,除非您运行大量复杂的聚合,甚至地理空间在插入时都会被索引。
您需要分片的最可能原因是,如果您有很多索引会消耗大量 RAM,wiredtiger 可以减少这种情况,但它仍然是分片的最常见原因。在单台机器上进行分片可能只会导致不必要的开销,几乎没有或可能没有任何好处。
【讨论】:
【参考方案2】:这不一定是 mongo 问题,而是一般操作系统问题。您的数据库使用可能存在三个瓶颈。
-
网络(即您在千兆线路上,您在高峰时间使用大部分线路,但您的数据库并没有真正加载)
CPU(您的 CPU 接近 100%,但磁盘和网络几乎没有运行)
磁盘
在网络的情况下,尽可能重写你的网络协议,否则分片到其他机器。在 CPU 的情况下,如果您在几个内核上 100% 使用但其他内核是免费的,那么在同一台机器上进行分片将提高性能。如果磁盘被充分利用,则添加更多磁盘并在它们之间分片 - 比添加更多机器便宜得多。
【讨论】:
我认为对驱动器进行 RAID 比在 2 个驱动器之间进行分片更具性能和效率。【参考方案3】:是的,在单个服务器上分片确实有意义。
此时,MongoDB 仍然对每个 mongodb 服务器使用全局锁。 创建多个服务器将释放一个服务器从彼此的锁中。
如果您运行具有单独 NUMA 的多核机器,这可以 还可以提高性能。
如果您的服务器负载增加过多,初始分片可以在未来更轻松地进行水平扩展。你不妨现在就去做。
机器各不相同。我建议编写自己的批量插入基准程序并启动各种数量的 MongoDB 服务器分片。我有一台 16 核 RAID 机器,我发现 3-4 个分片似乎是我的重写入数据库的理想选择。我发现我的两个 NUMA 是我的瓶颈。
【讨论】:
2.2 的新“惰性”锁定有什么新结果吗? @sivann 我得调查一下。谢谢。 我读到每台服务器都会相互竞争以使用尽可能多的 RAM,从而迫使其他服务器进行大量分页。对吗?【参考方案4】:不,在单个服务器上分片 a 是没有意义的。
有一些例外情况,但它们主要归结为与运行 map/reduce 或 javascript 等相关的并发问题。
【讨论】:
这很有意义 - 为了利用多个 CPU,您可以在同一硬件上进行分片。在处理大量数据时,它可以显着提高性能(尤其是因为 MongoDB 还不支持分区。) MongoDB 已经使用了多个 CPU/核心。通常人们将分片称为跨多个实例的分区类型。如果您有一些基准或测试表明它“大幅提高了性能”,我会很高兴看到它们。【参考方案5】:这个在副本集教程的第一段就有答案了
http://www.mongodb.org/display/DOCS/Replica+Set+Tutorial
【讨论】:
这是关于复制而不是分片 :) 同时我在ServerFault找到了很好的答案 不使用副本集的分片是没有意义的。 嗯,你能再解释一下吗?我很确定分片和复制是不同的概念。分片是在几个数据库实例之间拆分数据,复制是在几个实例中存储相同的数据。我哪里错了? :) 虽然单个 mongod 可以分片,但这个问题实际上没有任何意义(在一台机器上分片)。 这取决于负载。 Mongo 仍然没有行锁定,它锁定整个 db 以进行提交,因此据说分片到核心数量可以提供更好的性能并减少锁定等待。以上是关于MongoDB:单机分片。是不是有意义?的主要内容,如果未能解决你的问题,请参考以下文章