我目前正在开发一个由Mongo数据库驱动的移动应用程序,但是现在一切都很好,我们希望添加Sharding,以便为未来做好准备。
为了测试这一点,我们创建了一个实验室环境(运行在Hyper-V中)来测试各种场景的:
已经创建了以下服务器:
已经在C#中创建了一个小型控制台应用程序,以便能够测量执行插入的时间。
此控制台应用程序导入具有以下属性的10.000人:- Name - Firstname -全名-生日- Id
所有10.000条记录仅与“id”不同,所有其他字段对所有记录都是相同的。
需要注意的是,每个测试都精确地运行了3次。每次测试后,数据库都会被删除,这样系统就会再次干净。
测试结果如下:
插入10.000条记录而不分片
Writing 10.000 records | Non-Sharding environment - Full Disk IO #1: 14 Seconds.
Writing 10.000 records | Non-Sharding environment - Full Disk IO #2: 14 Seconds.
Writing 10.000 records | Non-Sharding environment - Full Disk IO #3: 12 Seconds.使用单个数据库碎片插入10.000条记录
备注:已将切分键设置为哈希_id字段。有关(部分)切分信息,请参见下面的Json:
shards:
{ "_id" : "shard0000", "host" : "192.168.137.12:27017" }
databases:
{ "_id" : "DemoDatabase", "primary" : "shard0000", "partitioned" : true }
DemoDatabase.persons
shard key: { "_id" : "hashed" }
unique: false
balancing: true
chunks:
shard0000 2
{ "_id" : { "$minKey" : 1 } } -->> { "_id" : NumberLong(0) } on : shard0000 Timestamp(1, 1)
{ "_id" : NumberLong(0) } -->> { "_id" : { "$maxKey" : 1 } } on : shard0000 Timestamp(1, 2)结果:
Writing 10.000 records | Single Sharding environment - Full Disk IO #1: 1 Minute, 59 Seconds.
Writing 10.000 records | Single Sharding environment - Full Disk IO #2: 1 Minute, 51 Seconds.
Writing 10.000 records | Single Sharding environment - Full Disk IO #3: 1 Minute, 52 Seconds.使用双数据库碎片插入10.000条记录
备注:已将切分键设置为哈希_id字段。有关(部分)切分信息,请参见下面的Json:
shards:
{ "_id" : "shard0000", "host" : "192.168.137.12:27017" }
{ "_id" : "shard0001", "host" : "192.168.137.13:27017" }
databases:
{ "_id" : "DemoDatabase", "primary" : "shard0000", "partitioned" : true }
DemoDatabase.persons
shard key: { "_id" : "hashed" }
unique: false
balancing: true
chunks:
shard0000 2
{ "_id" : { "$minKey" : 1 } } -->> { "_id" : NumberLong("-4611686018427387902") } on : shard0000 Timestamp(2, 2)
{ "_id" : NumberLong("-4611686018427387902") } -->> { "_id" : NumberLong(0) } on : shard0000 Timestamp(2, 3)
{ "_id" : NumberLong(0) } -->> { "_id" : NumberLong("4611686018427387902") } on : shard0001 Timestamp(2, 4)
{ "_id" : NumberLong("4611686018427387902") } -->> { "_id" : { "$maxKey" : 1 } } on : shard0001 Timestamp(2, 5)结果:
Writing 10.000 records | Single Sharding environment - Full Disk IO #1: 49 Seconds.
Writing 10.000 records | Single Sharding environment - Full Disk IO #2: 53 Seconds.
Writing 10.000 records | Single Sharding environment - Full Disk IO #3: 54 Seconds.根据上面执行的测试,分片工作,我添加的碎片越多,性能就越好。然而,我不明白为什么在使用碎片而不是使用单个服务器时,我会面临如此巨大的性能下降。
我需要快速阅读和写作--我认为切分是解决问题的办法,但我似乎遗漏了一些东西。
谁能为我指明正确的方向?
亲切的问候
发布于 2016-02-11 06:51:23
路由服务器和配置服务器、路由服务器和数据节点之间的层会增加延迟。如果您有1ms ping * 10k插入,则您有10秒的延迟时间,在未分割的设置中不会出现。
根据您配置的写关注点级别(如果您配置了任何级别的写确认),您可以在切分环境中给基准测试额外10秒的时间,因为阻塞直到从数据节点接收到确认为止。
如果您的写关注点被设置为确认,并且您有副本节点,那么您还必须等待写入传播到您的副本节点,增加额外的网络延迟。(但您似乎没有副本节点)。而且,根据网络拓扑结构的不同,如果使用默认设置来允许链式复制(从其他二级同步),写关注点可能会增加多个网络延迟层。https://docs.mongodb.org/manual/tutorial/manage-chained-replication/。如果您有额外的索引和写关注点,那么每个副本节点都必须在返回写确认之前写入该索引(但是可以禁用副本节点上的索引)。
如果没有切分和复制(但是有写确认),虽然插入仍然会阻塞插入,但是由于网络层的原因,没有额外的延迟。
哈希_id字段的开销也会累积到10k的几秒钟总数。您可以使用具有高度随机性的_id字段来避免散列,但我认为这对性能影响不大。
https://stackoverflow.com/questions/35272924
复制相似问题