草庐IT

mongodb 分片 - block 的大小不同

coder 2023-10-29 原文

我刚接触 mongodb。 由于我必须存储 +-5000 万份文档,我不得不设置一个带有两个副本集的 mongodb 分片集群

文档看起来像这样:

{
    "_id" : "predefined_unique_id",
    "appNr" : "abcde",
    "modifiedDate" : ISODate("2016-09-16T13:00:57.000Z"),
    "size" : NumberLong(803),
    "crc32" : NumberLong(538462645)
}

分片键是 appNr(之所以选择是因为出于查询性能的原因,所有具有相同 appNr 的文档都必须留在一个 block 中)。 通常多个文档具有相同的appNr

加载大约 200 万条记录后,我看到 block 是均衡的,但是当运行 db.my_collection.getShardDistribution() 时,我得到:

Shard rs0 at rs0/...
 data : 733.97MiB docs : 5618348 chunks : 22
 estimated data per chunk : 33.36MiB
 estimated docs per chunk : 255379

Shard rs1 at rs1/...

 data : 210.09MiB docs : 1734181 chunks : 19
 estimated data per chunk : 11.05MiB
 estimated docs per chunk : 91272

Totals
 data : 944.07MiB docs : 7352529 chunks : 41
 Shard rs0 contains 77.74% data, 76.41% docs in cluster, avg obj size on shard : 136B
 Shard rs1 contains 22.25% data, 23.58% docs in cluster, avg obj size on shard : 127B

我的问题是我应该做哪些设置才能使数据在分片之间平均分配?我想了解数据是如何分成 block 的。我已经定义了一个范围分片键和 block 大小 264。

最佳答案

MongoDB 使用与集合关联的分片键将数据分成 block 。 block 由分片数据的子集组成。每个 block 都有一个基于分片键的包含的下限和独占的上限。

分片键值空间被分割成更小的范围或 block 的图表。 mongos 根据分片键值将写入路由到适当的 block 。当 block 增长超过配置的 block 大小时,MongoDB 会拆分块。插入和更新都可以触发 block 拆分。

The smallest range a chunk can represent is a single unique shard key value. A chunk that only contains documents with a single shard key value cannot be split.

block 大小将对分片产生重大影响。

MongoDB 中的默认 block 大小为 64 兆字节。我们可以增加或减少 block 大小。但是修改 block 大小应该在考虑以下项目后进行

  1. 以更频繁的迁移为代价,小块导致数据分布更均匀。这会在查询路由 (mongos) 层产生费用。
  2. 大块导致更少的迁移。从网络角度和查询路由层的内部开销来看,这都更有效。但是,这些效率是以潜在的数据分布不均为代价的。
  3. block 大小影响要迁移的每个 block 的最大文档数。
  4. 在对现有集合进行分片时, block 大小会影响最大集合大小。分片后, block 大小不限制集合大小。

通过引用这些信息和您的分片键“appNr”,这会因为 block 大小而发生。

尝试将 block 大小而不是 264MB(您当前拥有的大小)调整为较小的大小,并查看文档分布是否有变化。但这将是一种反复试验的方法,并且需要大量的时间和迭代。

引用:https://docs.mongodb.com/v3.2/core/sharding-data-partitioning/

希望对您有所帮助!

关于mongodb 分片 - block 的大小不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40908424/

有关mongodb 分片 - block 的大小不同的更多相关文章

  1. ruby-on-rails - 在 Rails 中将文件大小字符串转换为等效千字节 - 2

    我的目标是转换表单输入,例如“100兆字节”或“1GB”,并将其转换为我可以存储在数据库中的文件大小(以千字节为单位)。目前,我有这个:defquota_convert@regex=/([0-9]+)(.*)s/@sizes=%w{kilobytemegabytegigabyte}m=self.quota.match(@regex)if@sizes.include?m[2]eval("self.quota=#{m[1]}.#{m[2]}")endend这有效,但前提是输入是倍数(“gigabytes”,而不是“gigabyte”)并且由于使用了eval看起来疯狂不安全。所以,功能正常,

  2. ruby - RSpec - 使用测试替身作为 block 参数 - 2

    我有一些Ruby代码,如下所示:Something.createdo|x|x.foo=barend我想编写一个测试,它使用double代替block参数x,这样我就可以调用:x_double.should_receive(:foo).with("whatever").这可能吗? 最佳答案 specify'something'dox=doublex.should_receive(:foo=).with("whatever")Something.should_receive(:create).and_yield(x)#callthere

  3. ruby-on-rails - Enumerator.new 如何处理已通过的 block ? - 2

    我在理解Enumerator.new方法的工作原理时遇到了一些困难。假设文档中的示例:fib=Enumerator.newdo|y|a=b=1loopdoy[1,1,2,3,5,8,13,21,34,55]循环中断条件在哪里,它如何知道循环应该迭代多少次(因为它没有任何明确的中断条件并且看起来像无限循环)? 最佳答案 Enumerator使用Fibers在内部。您的示例等效于:require'fiber'fiber=Fiber.newdoa=b=1loopdoFiber.yieldaa,b=b,a+bendend10.times.m

  4. ruby - 在匿名 block 中产生 - 2

    我没有理解以下行为(另请参阅inthisSOthread):defdef_testputs'def_test.in'yieldifblock_given?puts'def_test.out'enddef_testdoputs'def_testok'endblock_test=procdo|&block|puts'block_test.in'block.callifblockputs'block_test.out'endblock_test.calldoputs'block_test'endproc_test=procdoputs'proc_test.in'yieldifblock_gi

  5. ruby - Ruby 中的单 block AES 解密 - 2

    我需要尝试一些AES片段。我有一些密文c和一个keyk。密文已使用AES-CBC加密,并在前面加上IV。不存在填充,纯文本的长度是16的倍数。所以我这样做:aes=OpenSSL::Cipher::Cipher.new("AES-128-CCB")aes.decryptaes.key=kaes.iv=c[0..15]aes.update(c[16..63])+aes.final它工作得很好。现在我需要手动执行CBC模式,所以我需要单个block的“普通”AES解密。我正在尝试这个:aes=OpenSSL::Cipher::Cipher.new("AES-128-ECB")aes.dec

  6. HBase Region 简介和建议数量&大小 - 2

    Region是HBase数据管理的基本单位,region有一点像关系型数据的分区。region中存储这用户的真实数据,而为了管理这些数据,HBase使用了RegionSever来管理region。Region的结构hbaseregion的大小设置默认情况下,每个Table起初只有一个Region,随着数据的不断写入,Region会自动进行拆分。刚拆分时,两个子Region都位于当前的RegionServer,但处于负载均衡的考虑,HMaster有可能会将某个Region转移给其他的RegionServer。RegionSplit时机:当1个region中的某个Store下所有StoreFile

  7. java - 为什么 ruby​​ modulo 与 java/other lang 不同? - 2

    我基本上来自Java背景并且努力理解Ruby中的模运算。(5%3)(-5%3)(5%-3)(-5%-3)Java中的上述操作产生,2个-22个-2但在Ruby中,相同的表达式会产生21个-1-2.Ruby在逻辑上有多擅长这个?模块操作在Ruby中是如何实现的?如果将同一个操作定义为一个web服务,两个服务如何匹配逻辑。 最佳答案 在Java中,模运算的结果与被除数的符号相同。在Ruby中,它与除数的符号相同。remainder()在Ruby中与被除数的符号相同。您可能还想引用modulooperation.

  8. ruby-on-rails - 无法在 Rails 助手中捕获 block 的输出 - 2

    我在使用自定义RailsFormBuilder时遇到了问题,从昨天晚上开始我就发疯了。基本上我想对我的构建器方法之一有一个可选block,以便我可以在我的主要content_tag中显示其他内容。:defform_field(method,&block)content_tag(:div,class:'field')doconcatlabel(method,"Label#{method}")concattext_field(method)capture(&block)ifblock_given?endend当我在我的一个Slim模板中调用该方法时,如下所示:=f.form_field:e

  9. ruby - 具有两个参数的 block - 2

    我从用户Hirolau那里找到了这段代码:defsum_to_n?(a,n)a.combination(2).find{|x,y|x+y==n}enda=[1,2,3,4,5]sum_to_n?(a,9)#=>[4,5]sum_to_n?(a,11)#=>nil我如何知道何时可以将两个参数发送到预定义方法(如find)?我不清楚,因为有时它不起作用。这是重新定义的东西吗? 最佳答案 如果您查看Enumerable#find的文档,您会发现它只接受一个block参数。您可以将它发送两次的原因是因为Ruby可以方便地让您根据它的“并行赋

  10. ruby-on-rails - 在 RSpec 中,如何以任意顺序期望具有不同参数的多条消息? - 2

    RSpec似乎按顺序匹配方法接收的消息。我不确定如何使以下代码工作:allow(a).toreceive(:f)expect(a).toreceive(:f).with(2)a.f(1)a.f(2)a.f(3)我问的原因是a.f的一些调用是由我的代码的上层控制的,所以我不能对这些方法调用添加期望。 最佳答案 RSpecspy是测试这种情况的一种方式。要监视一个方法,用allowstub,除了方法名称之外没有任何约束,调用该方法,然后expect确切的方法调用。例如:allow(a).toreceive(:f)a.f(2)a.f(1)

随机推荐