在MongoDB中创建了一个由11446615个文档组成的集合。
每份文件都有以下形式:
{
"_id" : ObjectId("4e03dec7c3c365f574820835"),
"httpReferer" : "http://www.somewebsite.pl/art.php?id=13321&b=1",
"words" : ["SEX", "DRUGS", "ROCKNROLL", "WHATEVER"],
"howMany" : 3
}
httpReferer :只是一个网址
单词:从上面的网址解析的单词。列表的大小在15到90之间。
我打算使用此数据库来获取具有类似内容的网页列表。
我将使用单词字段查询此集合,以便在此字段中创建(或者更确切地说,开始创建)索引:
db.my_coll.ensureIndex({words: 1})
创建此集合需要很长时间。我尝试了两种方法(下面的测试是在我的笔记本电脑上完成的):
我主要关注的是减少生成集合的时间。我不需要复制(至少现在)。查询也不一定要轻快。
现在,问题的时间:
我只有一台机器有一个磁盘我可以运行我的应用程序。运行多个数据库实例并在它们之间拆分数据是否有意义?
答案 0 :(得分:15)
是,对单个服务器上的分片确实有意义。
目前,MongoDB仍然使用每个mongodb服务器的全局锁。 创建多个服务器将使服务器彼此锁定。
如果您运行具有单独NUMA的多核计算机,则可以 也提高了表现。
如果您的服务器的负载增加太多,则初始分片可以在将来更轻松地进行水平扩展。你现在也可以这样做。
机器各不相同。我建议编写自己的批量插入基准程序并启动各种MongoDB服务器分片。我有一个16核的RAIDed机器,我发现3-4个分片似乎是我的重写数据库的理想选择。我发现我的两个NUMA是我的瓶颈。
答案 1 :(得分:5)
在现代(2015年)与mongodb v3.0.x一起使用mmap进行集合级锁定,这会略微提高写入吞吐量(假设您写入多个集合),但是如果使用有线文件引擎有文档级锁定,它具有更高的写入吞吐量。这消除了在单个机器上进行分片的需要。虽然技术上仍然可以通过在单个机器上进行分片来提高mapReduce的性能,但在这种情况下,您最好只使用可以利用多个内核的聚合框架。如果你非常依赖map reduce算法,那么使用像Hadoop这样的东西最有意义。
分割mongodb的唯一原因是水平缩放。因此,如果单个机器无法容纳足够的磁盘空间,内存或CPU功率(罕见),则分片将变得有益。我认为真的很少有人有足够的数据需要进行分片,甚至是大型企业,特别是因为有线网提供了压缩支持,可以将磁盘使用率降低80%以上。很少有人使用mongodb来大规模地执行CPU密集查询,因为有更好的技术可以做到这一点。在大多数情况下,IO是性能中最重要的因素,除非您运行大量复杂的聚合,否则很少有查询是CPU密集型的,即使插入时也会对地理空间进行索引。
你需要进行分片的最可能的原因是,如果你有很多消耗大量内存的索引,有线网可以减少这种情况,但它仍然是分片的最常见原因。在一台机器上进行分片可能会导致不必要的开销,而且几乎没有或可能没有任何好处。
答案 2 :(得分:2)
这不一定是一个mongo问题,这是一个普遍的操作系统问题。您的数据库使用有三个可能的瓶颈。
如果是网络,请尽可能重写网络协议,否则请将其分享给其他计算机。在CPU的情况下,如果您在几个核心上100%但其他核心是免费的,则在同一台计算机上进行分片将提高性能。如果磁盘被充分利用,则在它们之间添加更多磁盘和分片 - 比添加更多机器更便宜。
答案 3 :(得分:1)
不,在单个服务器上进行分片是没有意义的。
有一些例外情况,但它们主要归结为与运行map / reduce或javascript等相关的并发问题。
答案 4 :(得分:-2)
这在副本集教程的第一段中得到了解答