MongoDB持续灌入大数据遇到的一些问题

首先这类NoSQL数据库的设计宗旨基本是“读多写少”。

而我们的需求是:有一大批数据(5亿条记录,每条100B左右)。需要灌入MongoDB。

考虑到数据规模,事先已经做好了Sharding,10台机器。

1、并发12进程,持续灌入数据。

一开始速度很快,基本10W/s,到了1亿6千万左右,开始变成龟速。经过仔细检查,mongos中报大量如下错误:

其实很很容易理解,灌入速度太暴力,导致很多后台进程如分片、迁移Shard的任务一直拿不到锁。

最后导致Shard1上面有130个Chunk,其他上面就是3~5个。

杀掉进程后,Mongo开始逐渐均衡,但考虑到时间会很长,遂删除数据。

2、灌数据建索引。

我们对灌入的数据需要建一些索引,之前没有经验,在配置好Shard后就ensureIndex了,导致到达1亿条后速度明显变慢。

其实这种先写后读的需求,完全可以等全部插入后再建索引,防止大量的锁竞争。

3、关于数据分块大小

默认的64MB,对于千万级别是可以的。像我们这种,就要适当调大,不然反复的split会导致性能下降。如果再加上持续插入数据,很可能导致一直无法split,当分片过大后就无法再进行迁移了。

4、关于自动Balance及我们的策略

经过仔细阅读文档,我发现MongoDB的Balance做的非常好,是后台自动完成的。但有一个缺陷:就是前面提到的,前台数据插入优先级更高,Balance只能在空闲时候做。

因此,我把5亿条数据分为10部分,每部分插入完成后,等待Balance平衡后,再插入下一部分。一般来说平衡的过程是非常快的,等一会再插入,能保证持续不断的性能。

关于查看各个Shard上的Chunk数量:

此外,还修改了Chunk Size为256MB,如3中所述。

Leave a Reply

Your email address will not be published.