我根据 tutorial 进行了基于“_id”列的哈希分片,并将数据分成了两个分片。然后进行了一些基准测试,发现在某些情况下,分片集群甚至比未分片的集群更慢。
这是测试结果。
最大吞吐量测试:使用十台机器同时运行“mongoimport”将数据加载到目标数据库中,以测试数据库的最大写入速度。
结果:
分片集群可以插入39500个文档/秒。
未分片集群可以插入27400个文档/秒。
单实例mongoimport测试:只使用一台机器运行“mongoimport”将数据加载到目标数据库中。
结果:
分片集群可以插入14285个文档/秒。
未分片集群可以插入14085个文档/秒。
使用mongodb java驱动程序进行单实例数据加载:只使用一个实例通过调用mongodb java驱动程序的api将数据加载到目标数据库中。
结果:
分片集群可以插入4630个文档/秒。
未分片集群可以插入17544个文档/秒。
第一个测试的结果非常合理。将数据库分片成2片,并且吞吐量增加了约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();
}
MongoClient
吗?像这样:new MongoClient(Arrays.asList( new ServerAddress("localhost", 27017), new ServerAddress("localhost", 27018), new ServerAddress("localhost", 27019)));
- Babl