查询路由器为什么要在MongoDB集群中存储所有数据?

3

我正在尝试建立 MongoDB 集群,已经拥有了 1 个配置服务器,1 个查询路由器和 2 个 mongod 实例。以下是我设置集群的脚本:

mongod --configsvr --port 27010 --dbpath ~/mongodb/data1
mongos -configdb localhost:27010 --port 27011 
mongod --port 27012 --dbpath ~/mongodb/data2 
mongod --port 27013 --dbpath ~/mongodb/data3 

sh.addShard("localhost:27012")
sh.addShard("localhost:27013")

sh.enableSharding("tags")
db.tweets.ensureIndex( { _id : "hashed" } )
sh.shardCollection("tags.tweets", { "_id": "hashed" } )

为了插入数据,我正在使用以下脚本。
connection = pymongo.MongoClient("mongodb://localhost:27011")
db=connection.tags
tweets = db.tweets


def main(jsonfile):
    f = open(jsonfile)

    for line in f.readlines():
        try:
            tweet_dict = json.loads(line)
            result = tweets.insert_one(tweet_dict)
            print result.inserted_id
        except  Exception as e:
            print "Unexpected error:", type(e), e
            sys.exit()

为什么我尝试插入的推文会被分片,而我尝试插入的所有推文也都存储在查询路由器中?这种行为是预期的吗?

集群的整个目的是横向扩展(即推文在机器之间分散),因此所有推文都累积在查询路由器中似乎不合常理?

有人能解释为什么会这样吗?为什么查询路由器有我插入的所有推文?


2
你为什么认为你的查询路由器拥有所有推文?显然,查询路由器在磁盘上没有数据存储(就像其他Mongo角色的--dbpath一样)。所以我不知道你为什么会得出这样的结论。 - nobody
哦,如果我在你发布这篇文章的那天看到了它,我也会说同样的话,并暂停你的问题(应该是这样的,其中至少之一的原因是这是一个dba.stackexchange.com的问题)。但现在已经来不及了!所以你似乎在问“为什么写操作没有被分配到每个分片?”这更加切题,使用了正确的术语。 - Blakes Seven
所以,正如他们所说的那样,“问题”来了。什么被插入到“_id”中?正如文档所述,单调值对于散列键是一件好事,因为它们将分布得很好。但是,如果每个新的“_id”值实际上并不是从前一个值“递增”的话,那么散列索引就会失败,并且无法保证它们将写入何处,因此它们可能会成为“热点”。明白了吗?与人沟通比设置赏金要更有效。 - Blakes Seven
这个问题毫无意义,是不可能的。Mongos是无状态的,不存储任何数据。在这个测试集群中,由于哈希分片键的存在,数据将均匀地存储在2个mongod节点中,而不考虑_id内容。请考虑阅读MongoDB文档,您对MongoDB系统的了解似乎很浅。 - Maxime Beugnet
1个回答

1
你问为什么你插入的推文“也被存储在查询路由器中”。简短的答案是,每个文档的唯一副本仅存储在其中一个底层分片服务器上,查询路由器上没有任何内容被存储。mongos进程没有使用--dbpath参数启动,因此它没有任何地方可以存储数据。
我建立了一个与你类似的环境,然后使用类似于你的Python脚本连接到mongos(也称为查询路由器),并将200个文档插入到tags.tweets中。现在,当我连接到mongos并计算tags.tweets中的文档数量时,它找到了200个。
$> mongo --port 27011 tags
mongos> db.tweets.count()
200

然而,当我运行getShardDistribution时,它显示第一个片段上有文档 91,第二个片段上有文档 109

mongos> db.tweets.getShardDistribution()

 Shard shard0000 at localhost:27301
  data : 18KiB docs : 91 chunks : 2
  estimated data per chunk : 9KiB
  estimated docs per chunk : 45

 Shard shard0001 at localhost:27302
  data : 22KiB docs : 109 chunks : 2
  estimated data per chunk : 11KiB
  estimated docs per chunk : 54

 Totals
  data : 41KiB docs : 200 chunks : 4
  Shard shard0000 contains 45.41% data, 45.5% docs in cluster, avg obj size on shard : 210B
  Shard shard0001 contains 54.58% data, 54.5% docs in cluster, avg obj size on shard : 211B

查询路由器的工作原理是将所有命令传递给底层分片服务器,然后组合它们的响应,然后将结果返回给调用者。上面返回的200的count()只是在每个分片上执行的count()的总和。
有关使用MongoDB分片进行水平扩展的更多信息,请参阅分片文档此处。您可能会发现元数据部分对您当前的问题有所帮助。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接