通过前面源码的分析感觉mongodb的分片加上replset就是全部了,啥问题都应该解决了,后来看到了foursquare发生mongodb宕机事件,看了一下宕机事件的分析,当时阅读代码还并未阅读到分片部分,但是准备阅读分片时就决定一定要仔细将分片机制研究清楚,然后可以分析下foursquare宕机原因.后来阅读完分片代码后明白了其分片策略,当时怎么也想不通为什么会产生shard不平衡的状况呢,一个50G,一个66G.后来大体是想明白了,这里记下几个mongodb的问题.
mongodb的分片是按照chunk来做的,chunk发生迁移时原来的chunk将会被删除,这样就发生了问题.chunk的数据是分布在其所在collection中的extent的,其分布的是随机的,其内部数据可能分布在不同的page中,即使将chunk删除了,这样就操作了一个问题,page中部分数据被删除,但是mongodb加载时mmap机制一样会将其map整个页面,访问相应数据时整个页面都会被实体化,一样的占据了整个页面,相当于浪费了很多空间.分片的好处没能够体现出来.foursquare的办法是分片的shard的副本集压缩(相当于磁盘碎片整理)然后再将副本切换为主服务器,10gen给出的办法是他们正在研究在线压缩,不过目前没有进一步消息.
mongodb分片过程中首先是写一个shard上的数据,首先一个chunk,chunk大了拆分,chunk多了迁移,这样就存在一个问题,如果是导入一个数据库,那么会非常慢,因为开始时其只写一个shard,然后将数据迁移到其它shard,这当然很慢,所以这时需要预先手动分片,关闭自动的balance.这样的话mongodb的自动分片机制优势不再.
mongodb的shard key也是需要注意的,选取shard key不好则可能发生一直往某一个shard不断写入数据的状况,其它shard被饥饿着,最后只能靠balance完成平衡,所以选择shard key需慎重.
10gen正在研发hash shard key,2.4版本将提供这个hash shard key功能,将用hash来分发数据到shard,这样将影响范围查询的性能,具体怎样还有待检验,另外如果是hash,那么添加新的服务器怎么办呢,还得等10gen1月份的2.4版本发布,到时候来分析吧.
总之理想很丰满,现实很骨感,分片加replset不是万能的,要想一个高性能有时候还是得自己手动来做一些事.