【发布时间】:2017-07-20 05:10:14
【问题描述】:
我有一个 Mongodb 集群,其中包含一个主副本和一个辅助副本作为复制集一起运行。但随着流量的增长,我决定执行分片以获得更快的写入速度。
我根据tutorial 对“_id”列执行了散列分片,并将数据分成两个分片。然后我进行了一些基准测试,发现在某些情况下,分片集群甚至比非分片集群还要慢。
这是测试结果。
-
最大吞吐量测试:使用十台机器同时运行“mongoimport”将数据加载到目标db,以测试db的最大写入速度。
结果:
分片集群可以插入 39500 个文档/秒。
非分片集群可以插入 27400 个文档/秒。
-
单实例mongoimport测试:仅使用一台机器运行“mongoimport”将数据加载到目标数据库中。
结果:
分片集群可以插入14285个文档/秒。
非分片集群可以插入 14085 个文档/秒。
-
mongodb java驱动的单实例数据加载:调用mongodb java驱动的api,只使用一个实例将数据加载到目标数据库中。
结果:
分片集群可以插入 4630 个文档/秒。
非分片集群可以插入 17544 个文档/秒。
第一次测试的结果非常合理。你将 db 分片成一个 2-shard 集群,吞吐量增加了大约 50%,一切都很完美,万岁!
第二个测试有点道理。吞吐量大致相同,但瓶颈可能在数据加载器方面,毕竟我们只使用一个实例加载数据。
但是第三个测试真的让我很烦。分片集群比非分片集群慢得多是没有意义的。另一方面,未分片的数据库具有惊人的速度,甚至比使用 mongoimport 加载数据还要快。
用于加载数据的 java 代码粘贴在下面。我真的无法弄清楚这一点,并提前感谢所有答案。
public static void insert(String host, int port) throws FileNotFoundException,
InterruptedException, ExecutionException {
MongoClient mongoClient = new MongoClient(host, port);
mongoClient.setWriteConcern(WriteConcern.UNACKNOWLEDGED);
MongoDatabase database = mongoClient.getDatabase("my-db");
MongoCollection<Document> collection = database.getCollection("my-collection");
Scanner scan = new Scanner(new File("my-sample-dataset"));
// Pre-load the data into the memory, so that the db load test won't be
// affected by disk I/O time.
Queue<List<String>> resource = new LinkedList<>();
for (int i = 0; i < 100; i++) {
List<String> strs = new ArrayList<>();
for (int j = 0; j < 10000; j++)
strs.add(scan.nextLine());
resource.add(strs);
}
System.out.println("start");
long startTime = System.currentTimeMillis();
while (!resource.isEmpty()) {
List<String> strs = resource.poll();
List<WriteModel<Document>> list = new ArrayList<>();
for (int i = 0; i < 10000; i++) {
list.add(new
InsertOneModel<Document>(Document.parse(strs.get(i))));
}
collection.bulkWrite(list);
}
System.out.println("Finished loading. Time taken: " + (System.currentTimeMillis() - startTime) + "ms");
scan.close();
}
【问题讨论】:
-
您是否尝试通过传递所有副本集主机和端口来创建
MongoClinet?类似new MongoClient(Arrays.asList( new ServerAddress("localhost", 27017), new ServerAddress("localhost", 27018), new ServerAddress("localhost", 27019))); -
您的源数据是否为每条记录指定了_id?
-
这里还有一些提示:chat.stackoverflow.com/rooms/40058/… 尝试检查主机的统计信息,以及文档是如何在它们之间分片的
-
你用的是哪个版本的mongo?
标签: java mongodb performance bulkinsert