131hours to 37mins

上周到这周四一直都在解决我的mapreduce程序的模式问题,应该说写的这个mapreduce程序经历过三次改变,就叫做v1,v2,v3三个版本吧。

v1版本出来后,在写入hbase中的时候,key值没有经过任何的处理,完全按照unicode码的方式存储。起初认为这个过程导致key值的分布过于紧密,因此考虑用md5加密对key值进行映射,使key值离散。然而在v2效率更低,原因猜测是key值在hbase中存储时,还是要按照顺序排放,那么的话就存在大量的io操作,再者经过md5加密后,key值变成了32位的字符串,可能也加大了寻找key值的难度。

第二:程序中存在大量的临时变量,在集群的几千万条记录中来回创建,回收内存,也是会耗费大量的时间和内存。虽然java存在垃圾回收机制,但是也不完美。所以,在从v1到v2的变化中,主要在于代码的优化,能够用静态变量来代替的就用静态变量来处理,以减少变量的来回创建。

v2版本的运行时间是131hours,这简直是无法忍受的。因此必须改变,必须从编程模型中改变。在v1,v2版本中,只是简单的运用了mapreduce这一编程模型中的map部分,对reduce部分没有运用,起初的想法也很简单,从一个表中读取数据,处理过后,放到另外一个表中,很简单。只需要运用到mapreduce分布式这一个特点就可以解决。事实证明,当时的想法过于简单了。 当涉及大量的io操作后,通过将数据以块的形式写入表中,而不是记录的方式,来减少io操作。这是我当时考虑的第一点。后来就想到利用mapreduce这一整个模型来计算。这一点,我和国华师兄不谋而合。

下面就把我的编程模型写下来:

新的优化方案,要减少io操作。涉及mapper,combiner,reducer整个过程,之前的方案只运用了mapper。

mapper设计思路:

1 从unindexedPapers 表中读取每篇paper的authors

2 进行分词

3 以名为key值(经SHA-1加密), 姓+次数(num表示) 作为value 作为输出。 list()

combiner思路:

1 以mapper输出作为输入

2 key2值相同,value2值也相同的,将num相加;key2值相同,value2值不同的,将其组合成一个集合即可

3 将 作为输出

reducer思路

1 将combiner传来的数据再次进行类似的combiner操作

2 从hbase中,以key2作为关键字从hbase中获取records,进行计算合并。

3 计算合并结果,再次插入hbase中。

今天早上在集群上运行这个程序后,最终以37mins中在6台电脑的集群上跑完了3000万条记录。证明方案是可行的。

早上小高兴了一把,不过随之而来的就是以前要考虑的一个问题,如何给出一个合理的数学公式,设计出一个合理的权重出来。下一阶段,要把概率统计的课本在翻看下,和国华师兄在好好分析分析,找出点idea,设计一个合理的数学公式出来。

科研的路真是不容易,各种绊脚石都存在,一一克服吧。

One Response to “131hours to 37mins”

  1. Joseph Pan 说到:

    恭喜恭喜!

Leave a Reply