AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 52416
Accepted
Adam C
Adam C
Asked: 2013-10-30 06:27:57 +0800 CST2013-10-30 06:27:57 +0800 CST 2013-10-30 06:27:57 +0800 CST

如何确定分片 MongoDB 集群中的块分布(数据和文档数量)?

  • 772

做完所有正确的事情——选择一个合适的分片键,水平扩展,将我的数据分布在几个分片上,我发现我现在没有真正的方法来确定数据在文档数量和数据大小方面的平衡程度。该sh.status()命令将告诉我块是如何按计数分布的,但不会告诉我这些块是由什么组成的。

有很多方法可以推断出这些事情——但它们都有缺点。数据库大小计算方式的变幻莫测意味着,如果数据库中有大量删除,则统计数据可能无法准确反映数据分布。如果我查看每个分片的流量,这可能会给我一些线索,但前提是我的流量很好且可预测。

那么,如何确定每个块中文档的分布、每个块的相对大小以及(当然)这些块当前所在的位置?

mongodb sharding
  • 2 2 个回答
  • 9396 Views

2 个回答

  • Voted
  1. Best Answer
    Adam C
    2013-10-30T06:27:57+08:002013-10-30T06:27:57+08:00

    目前没有内置的方法可以做到这一点,所以需要一个小函数。出于此答案的目的,我按照这些说明创建了一个包含约 100 万个文档的 2 分片集群。接下来我使用这个函数来检查这些文件:

    AllChunkInfo = function(ns, est){
        var chunks = db.getSiblingDB("config").chunks.find({"ns" : ns}).sort({min:1}); //this will return all chunks for the ns ordered by min
        //some counters for overall stats at the end
        var totalChunks = 0;
        var totalSize = 0;
        var totalEmpty = 0;
        print("ChunkID,Shard,ChunkSize,ObjectsInChunk"); // header row
        // iterate over all the chunks, print out info for each 
        chunks.forEach( 
            function printChunkInfo(chunk) { 
    
            var db1 = db.getSiblingDB(chunk.ns.split(".")[0]); // get the database we will be running the command against later
            var key = db.getSiblingDB("config").collections.findOne({_id:chunk.ns}).key; // will need this for the dataSize call
            // dataSize returns the info we need on the data, but using the estimate option to use counts is less intensive
            var dataSizeResult = db1.runCommand({datasize:chunk.ns, keyPattern:key, min:chunk.min, max:chunk.max, estimate:est});
            // printjson(dataSizeResult); // uncomment to see how long it takes to run and status           
            print(chunk._id+","+chunk.shard+","+dataSizeResult.size+","+dataSizeResult.numObjects); 
            totalSize += dataSizeResult.size;
            totalChunks++;
            if (dataSizeResult.size == 0) { totalEmpty++ }; //count empty chunks for summary
            }
        )
        print("***********Summary Chunk Information***********");
        print("Total Chunks: "+totalChunks);
        print("Average Chunk Size (bytes): "+(totalSize/totalChunks));
        print("Empty Chunks: "+totalEmpty);
        print("Average Chunk Size (non-empty): "+(totalSize/(totalChunks-totalEmpty)));
    }  
    

    目前它非常基本,但它可以完成工作。我还在github 上添加了它,并且可能会在那里进一步扩展它。但就目前而言,它会做需要做的事情。在开头描述的测试数据集上,输出如下所示(为简洁起见,删除了一些数据):

    mongos> AllChunkInfo("chunkTest.foo", true);
    ChunkID,Shard,ChunkSize,ObjectsInChunk
    chunkTest.foo-_id_MinKey,shard0000,0,0
    chunkTest.foo-_id_0.0,shard0000,599592,10707
    chunkTest.foo-_id_10707.0,shard0000,1147832,20497
    chunkTest.foo-_id_31204.0,shard0000,771568,13778
    chunkTest.foo-_id_44982.0,shard0000,771624,13779
    // omitted some data for brevity
    chunkTest.foo-_id_940816.0,shard0000,1134224,20254
    chunkTest.foo-_id_961070.0,shard0000,1145032,20447
    chunkTest.foo-_id_981517.0,shard0000,1035104,18484
    ***********Summary Chunk Information***********
    Total Chunks: 41
    Average Chunk Size (bytes): 1365855.024390244
    Empty Chunks: 1
    Average Chunk Size (non-empty): 1400001.4
    

    解释传递给函数的参数:

    第一个参数是要检查的名称空间(字符串),第二个参数(布尔值)是是否使用估计选项。对于任何生产环境,建议使用estimate:true它——如果不使用,则需要检查所有数据,这意味着将其拉入内存,这将是昂贵的。

    虽然该estimate:true版本不是免费的(它使用计数和平均对象大小),但即使在大型数据集上运行也至少是合理的。如果对象大小在某些分片上存在偏差,则估计版本也可能会有些偏差,因此平均大小不具有代表性(这通常很少见)。

    • 11
  2. Landon
    2014-08-01T14:52:30+08:002014-08-01T14:52:30+08:00
    db.collection.getShardDistribution()
    

    这是一个非常好的命令,我经常用于这样的事情。它将显示每个分片的总块、平均块大小、文档计数。它不会像上面的答案那样为您提供每个块的数据,但这非常快,并且可以很好地概述您正在寻找的内容。

    • 3

相关问题

  • Mongo Map-Reduce 还是分片?

  • 使用集群设置 Mongo

  • MongoDB 的 find 和 findone 调用之间的区别

  • 分片对小集合有效吗?

  • 关于操作/管理 MongoDB 的良好资源

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    授予用户对所有表的访问权限

    • 5 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    pedrosanta 使用 psql 列出数据库权限 2011-08-04 11:01:21 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve