使用场景
对数据进行合并排序的使用场景很对,不仅是Hbase里有用到,mapreduce的合并也有用到,也许你的业务代码里也须要对数据进行排序。Hbase里storefile的合并排序仍是比较巧妙的。若是让你将有序的小文件合并成有序的大文件,你会怎么作?下面看看Hbase是怎么作的。但愿里面的合并排序方法能对你有所帮助,有错误的地方欢迎拍砖。 |
原理分析
先回顾下归并排序算法:
- Hbase里将多个小的有序的storefile合并成一个大的有序的storefile的过程跟归并排序差很少。可是不知道为何归并排序算法就分出两个小有序集合而不是多个有序集合。Hbase就是多个小的有序集合合并成大的有序集合。
- 下面看看归并排序的思想。将两个有序的小集合合并成一个有序的大集合:好比将集合{1,3,5,7,9}和{2,4,6,8,10}合并成一个大集合。
- 首先你们都知道两个有序集合中最小的两个元素分别是1和2,再从这两个元素中比较谁更小,那么更小的就是这两个集合中最小的元素。好比这里的1和2中1更小,那么1就是这两个集合中最小的元素。下一步把1从集合中取出来放到合并后的集合中{1}。
- 而后在剩下的集合中分别找出两个集合中的最小元素是3和2,再比较两个最小元素谁更小。结果是2比3小,那么就取出2追加到合并后的集合中{1,2}。
- 而后再重复上述动做,每次都取出两个集合中最小元素追加到合并后的集合中,最后获得的集合就是有序的。组后就生成集合{1,2,3,4,5,6,7,8,9,10}。
再看看Hbase是怎么对storefile进行合并排序的:
- 在Hbase里正常状况下每一次将内存memstore的数据刷写到磁盘都会生成一个storefile,长此以往family下面的storefile会变的不少,因此须要合并一下,通常默认的配置就是storefile数量达到3个时就会进行合并。
- 因为内存里memstore是在数据插入的过程当中就排序的,就是数据插入的时候按照顺序插入,因此memstore里的数据是有序的。当memstore的数据刷写到磁盘时,生成的storefile里的数据也是有序的,这样的话各个storefile里的数据就分别有序了。合并的时候须要将各个有序的storefile合并成一个大的有序的storefile。
- 首先将各个须要合并的storefile封装成StoreFileScanner最后造成一个List加载到内存,而后再封装成StoreScanner对象,这个对象初始化的时候会对各个StoreFileScanner进行排序放到内部的队列里,排序是按照各个StoreFileScanner最小的rowkey进行排序的。而后经过StoreScanner的next()方法能够拿到各个StoreFileScanner最小rowkey中的最小rowkey对应的KV对。而后就把取出的KV对追加写入合并后的storefile。由于每次取出的都是各个storefile里最小的数据,因此追加写入合并后的storefile里的数据就是按从小到大排序的有序数据。
- 就这样完成了合并排序,思想跟归并排序差很少,用的也很巧妙。
转载:http://blog.sina.com.cn/s/blog_6ce72fe40101celq.htmlhtml