MapReduce性能优化_6. 优化 Shuffle & Sort 阶段

本文翻译于 《Hadoop in Practice - 1》, 摘抄自: 大牛翻译系列

6.4.3 优化洗牌(shuffle)和排序阶段

技术46 规避使用reduce

技术47 过滤和投影

技术48 使用combine

技术49 用Comparator进行超快排序

洗牌和排序阶段都很耗费资源。洗牌需要在map和reduce任务之间传输数据,会导致过大的网络消耗。排序和合并操作的消耗也是很显著的。这一节将介绍一系列的技术来缓解洗牌和排序阶段的消耗。

技术46 规避使用reduce

Reduce在用于连接数据集的时候将会产生大量的网络消耗。

问题

需要考虑在MapReduce规避reduce的使用。

方案

通过将MapReduce参数setNumReduceTasks设置为0来创建一个只有map的作业。

讨论

洗牌和排序阶段一般都是用来连接数据集。但连接操作并不一定需要洗牌和排序,正如第4章中所介绍的。满足一定条件的连接可以只在map端运行。那么就只需要只有map的作业了。设置只有map的作业的命令如下。

job.setNumReduceTasks(0);

小结

一个只有map的作业的OutputFormat是和普通作业中reduce的OutputFormat一样。如图6.39所示。

如果无法规避reduce,那么就要尽量减小它对你的作业执行时间的影响。

 

技术47 过滤和投影

Map到Reduce之间传输数据要通过网络,这个成本很高。


问题

需要减少被洗牌的数据。


方案

减少map输出的每条记录的大小,并尽可能地减少map输出的数据量。


讨论

过滤和投影是关系运算中的概念,用以减少需要处理的数据。这些概念也可以用到MapReduce中减少map任务需要输出的数据。以下是过滤和投影的简明定义:

  • 过滤是减少map输出的数据量。
  • 投影是减少map输出的每条记录的大小。

以下是上述概念的演示代码:

<pre style="line-height: 21px; font-family: 'Courier New' !important; background-color: inherit;"><pre style="font-family: 'Courier New' !important; background-color: inherit;"><span style="color: rgb(0, 128, 128); background-color: inherit;">1</span> Text outputKey = <span style="color: rgb(0, 0, 255); background-color: inherit;">new</span> Text();
<span style="color: rgb(0, 128, 128); background-color: inherit;"> 2</span> Text outputValue = <span style="color: rgb(0, 0, 255); background-color: inherit;">new</span> Text();
<span style="color: rgb(0, 128, 128); background-color: inherit;"> 3</span><span style="color: rgb(0, 128, 128); background-color: inherit;"> 4</span> @Override
<span style="color: rgb(0, 128, 128); background-color: inherit;"> 5</span><span style="color: rgb(0, 0, 255); background-color: inherit;">public</span><span style="color: rgb(0, 0, 255); background-color: inherit;">void</span> map(LongWritable key, Text value,
<span style="color: rgb(0, 128, 128); background-color: inherit;"> 6</span>                 OutputCollector<Text, Text> output,
<span style="color: rgb(0, 128, 128); background-color: inherit;"> 7</span>                 Reporter reporter) <span style="color: rgb(0, 0, 255); background-color: inherit;">throws</span> IOException {
<span style="color: rgb(0, 128, 128); background-color: inherit;"> 8</span><span style="color: rgb(0, 128, 128); background-color: inherit;"> 9</span>     String v = value.toString();
<span style="color: rgb(0, 128, 128); background-color: inherit;">10</span><span style="color: rgb(0, 128, 128); background-color: inherit;">11</span><span style="color: rgb(0, 0, 255); background-color: inherit;">if</span> (!v.startsWith("10.")) {
<span style="color: rgb(0, 128, 128); background-color: inherit;">12</span>         String[] parts = StringUtils.split(v, ".", 3);
<span style="color: rgb(0, 128, 128); background-color: inherit;">13</span>         outputKey.set(parts[0]);
<span style="color: rgb(0, 128, 128); background-color: inherit;">14</span>         outputValue.set(parts[1]);
<span style="color: rgb(0, 128, 128); background-color: inherit;">15</span>         output.collect(outputKey, outputValue);
<span style="color: rgb(0, 128, 128); background-color: inherit;">16</span>     }
<span style="color: rgb(0, 128, 128); background-color: inherit;">17</span> }

 
  
 
 


小结

过滤和投影是在需要显著减少MapReduce作业运行时间时最容易的方法中的两种。

如果已经应用了这两种方法,但还需要进一步减少运行时间。那么就可以考虑combine。

 

技术48 使用combine

Combine可以在map阶段进行聚合操作来减少需要发送到reduce的数据。它是一个map端的优化工具,以map的输出作为输入。


问题

需要在过滤和投影后进一步减少运行时间。


方案

定义一个combine。在作业代码中使用setCombinerClass来调用它。


讨论

在map输出数据到磁盘的过程中,有两个子过程:溢洒(spill)子过程,合并子过程。Combine在这两个子过程中都会被调用,如图6.40所示。为了让combine在分组数据中效率最大,可以在两个子过程调用combine之前进行初步(precursory)的排序。

 

与设置map类类似,作业使用setCombinClass来设置combine。

<pre style="line-height: 21px; font-family: 'Courier New' !important; background-color: inherit;">job.setCombinerClass(Combine.<span style="color: rgb(0, 0, 255); background-color: inherit;">class</span>);
 
 

Combine的实现必须严格遵从reduce的规格说明。这里将假定使用技术39种的map。将map的输出中的记录按照下述条件合并:第二个八进制数相同。代码如下。

<pre style="line-height: 21px; font-family: 'Courier New' !important; background-color: inherit;"><span style="color: rgb(0, 128, 128); background-color: inherit;"> 1</span><span style="color: rgb(0, 0, 255); background-color: inherit;">public</span><span style="color: rgb(0, 0, 255); background-color: inherit;">static</span><span style="color: rgb(0, 0, 255); background-color: inherit;">class</span> Combine <span style="color: rgb(0, 0, 255); background-color: inherit;">implements</span> Reducer<Text, Text, Text, Text> {
<span style="color: rgb(0, 128, 128); background-color: inherit;"> 2</span><span style="color: rgb(0, 128, 128); background-color: inherit;"> 3</span>     @Override
<span style="color: rgb(0, 128, 128); background-color: inherit;"> 4</span><span style="color: rgb(0, 0, 255); background-color: inherit;">public</span><span style="color: rgb(0, 0, 255); background-color: inherit;">void</span> reduce(Text key, Iterator<Text> values,
<span style="color: rgb(0, 128, 128); background-color: inherit;"> 5</span>                         OutputCollector<Text,
<span style="color: rgb(0, 128, 128); background-color: inherit;"> 6</span>                         Text> output,
<span style="color: rgb(0, 128, 128); background-color: inherit;"> 7</span>                         Reporter reporter) <span style="color: rgb(0, 0, 255); background-color: inherit;">throws</span> IOException {
<span style="color: rgb(0, 128, 128); background-color: inherit;"> 8</span><span style="color: rgb(0, 128, 128); background-color: inherit;"> 9</span>         Text prev = <span style="color: rgb(0, 0, 255); background-color: inherit;">null</span>;
<span style="color: rgb(0, 128, 128); background-color: inherit;">10</span><span style="color: rgb(0, 0, 255); background-color: inherit;">while</span> (values.hasNext()) {
<span style="color: rgb(0, 128, 128); background-color: inherit;">11</span>             Text t = values.next();
<span style="color: rgb(0, 128, 128); background-color: inherit;">12</span><span style="color: rgb(0, 0, 255); background-color: inherit;">if</span> (!t.equals(prev)) {
<span style="color: rgb(0, 128, 128); background-color: inherit;">13</span>                 output.collect(key, t);
<span style="color: rgb(0, 128, 128); background-color: inherit;">14</span>             }
<span style="color: rgb(0, 128, 128); background-color: inherit;">15</span>             prev = ReflectionUtils.copy(job, t, prev);
<span style="color: rgb(0, 128, 128); background-color: inherit;">16</span>         }
<span style="color: rgb(0, 128, 128); background-color: inherit;">17</span>     }
<span style="color: rgb(0, 128, 128); background-color: inherit;">18</span> }
 
 

Combine函数必须是可分布的(distributive)。如图6.40(在前面)所示,combine要被调用多次处理多个具有相同输入键的记录。这些记录的顺序是不可预测的。可分布函数是指,不论输入数据的顺序如何,最终的结果都一样。


小结

在MapReduce中combine非常有用,它能够减少map和reduce之间的网络传输数据和网络负载。下一个减少执行时间的有用工具就是二进制比较器。

 

技术49 用Comparator进行超快排序

MapReduce默认使用RawComparator对map的输出键进行比较排序。内置的Writable类(例如Text和IntWritable)是字节级实现。这样不用将字节形式的类解排列(unmarshal)成类对象。如果要通过WritableComparable实现自定义Writable,就有可能延长洗牌和排序阶段的时间,因为它需要进行解排列。

问题

存在自定义的Writable。需要减少作业的排序时间。

方案

实现字节级的Comparator来优化排序中的比较过程。

讨论

在MapReduce中很多阶段,排序是通过比较输出键来进行的。为了加快键排序,所有的map输出键必须实现WritableComparable接口。

<pre style="font-size: 14px; line-height: 21px; font-family: 'Courier New' !important; background-color: inherit;"><span style="font-size: 12px;"><span style="color: rgb(0, 128, 128); background-color: inherit;"> </span><span style="color: rgb(0, 0, 255); background-color: inherit;">public </span><span style="color: rgb(0, 0, 255); background-color: inherit;">interface</span> WritableComparable<T> <span style="color: rgb(0, 0, 255); background-color: inherit;">extends</span> Writable, Comparable<T> {
 }</span>
 
 

如果对4.2.1中的Person类进行改造,实现代码如下。

<pre style="font-size: 14px; line-height: 21px; font-family: 'Courier New' !important; background-color: inherit;"><span style="font-size: 12px;"><span style="color: rgb(0, 0, 255); background-color: inherit;">public</span><span style="color: rgb(0, 0, 255); background-color: inherit;">class</span> Person <span style="color: rgb(0, 0, 255); background-color: inherit;">implements</span> WritableComparable<Person> {
<span style="color: rgb(0, 128, 128); background-color: inherit;"> </span><span style="color: rgb(0, 0, 255); background-color: inherit;">private</span> String firstName;
<span style="color: rgb(0, 128, 128); background-color: inherit;"> </span><span style="color: rgb(0, 0, 255); background-color: inherit;">private</span> String lastName;
<span style="color: rgb(0, 128, 128); background-color: inherit;"> </span>    @Override
<span style="color: rgb(0, 128, 128); background-color: inherit;"> </span><span style="color: rgb(0, 0, 255); background-color: inherit;">public</span><span style="color: rgb(0, 0, 255); background-color: inherit;">int</span> compareTo(Person other) {
<span style="color: rgb(0, 128, 128); background-color: inherit;"> </span><span style="color: rgb(0, 0, 255); background-color: inherit;">int</span> cmp = <span style="color: rgb(0, 0, 255); background-color: inherit;">this</span>.lastName.compareTo(other.lastName);
<span style="color: rgb(0, 128, 128); background-color: inherit;"> </span><span style="color: rgb(0, 0, 255); background-color: inherit;">if</span> (cmp != 0) {
<span style="color: rgb(0, 128, 128); background-color: inherit;"> </span><span style="color: rgb(0, 0, 255); background-color: inherit;">return</span> cmp;
<span style="color: rgb(0, 128, 128); background-color: inherit;"> </span>        }
<span style="color: rgb(0, 128, 128); background-color: inherit;"> </span><span style="color: rgb(0, 0, 255); background-color: inherit;">return</span><span style="color: rgb(0, 0, 255); background-color: inherit;">this</span>.firstName.compareTo(other.firstName);
<span style="color: rgb(0, 128, 128); background-color: inherit;"> </span>     }
<span style="color: rgb(0, 128, 128); background-color: inherit;"> </span> ...</span>
 
 

这个Comparator的问题在于,如果要进行比较,就需要将字节形式的map的中间结果数据解排列成Writable形式。解排列要重新创建对象,因此成本很高。

Hadoop中的自带的各种Writable类不但扩展了WritableComparable接口,也提供了基于WritableComparator类的自定义Comparator。代码如下。

<pre style="font-size: 14px; line-height: 21px; font-family: 'Courier New' !important; background-color: inherit;"><span style="font-size: 12px;"><span style="color: rgb(0, 0, 255); background-color: inherit;">public</span><span style="color: rgb(0, 0, 255); background-color: inherit;">class</span> WritableComparator <span style="color: rgb(0, 0, 255); background-color: inherit;">implements</span> RawComparator {
<span style="color: rgb(0, 128, 128); background-color: inherit;"> </span><span style="color: rgb(0, 0, 255); background-color: inherit;">public</span><span style="color: rgb(0, 0, 255); background-color: inherit;">int</span> compare(<span style="color: rgb(0, 0, 255); background-color: inherit;">byte</span>[] b1, <span style="color: rgb(0, 0, 255); background-color: inherit;">int</span> s1, <span style="color: rgb(0, 0, 255); background-color: inherit;">int</span> l1, <span style="color: rgb(0, 0, 255); background-color: inherit;">byte</span>[] b2, <span style="color: rgb(0, 0, 255); background-color: inherit;">int</span> s2, <span style="color: rgb(0, 0, 255); background-color: inherit;">int</span> l2) {
<span style="color: rgb(0, 128, 128); background-color: inherit;"> </span><span style="color: rgb(0, 0, 255); background-color: inherit;">try</span> {
<span style="color: rgb(0, 128, 128); background-color: inherit;">  </span>             buffer.reset(b1, s1, l1);
<span style="color: rgb(0, 128, 128); background-color: inherit;">  </span>             key1.readFields(buffer);
<span style="color: rgb(0, 128, 128); background-color: inherit;">  </span>             buffer.reset(b2, s2, l2);
<span style="color: rgb(0, 128, 128); background-color: inherit;">  </span>             key2.readFields(buffer);
<span style="color: rgb(0, 128, 128); background-color: inherit;">  </span>         } <span style="color: rgb(0, 0, 255); background-color: inherit;">catch</span> (IOException e) {
<span style="color: rgb(0, 128, 128); background-color: inherit;"> </span><span style="color: rgb(0, 0, 255); background-color: inherit;">throw</span><span style="color: rgb(0, 0, 255); background-color: inherit;">new</span> RuntimeException(e);
<span style="color: rgb(0, 128, 128); background-color: inherit;"> </span>         }
<span style="color: rgb(0, 128, 128); background-color: inherit;"> </span><span style="color: rgb(0, 0, 255); background-color: inherit;">return</span> compare(key1, key2);
<span style="color: rgb(0, 128, 128); background-color: inherit;"> </span>     }
<span style="color: rgb(0, 128, 128); background-color: inherit;"> </span><span style="color: rgb(0, 128, 0); background-color: inherit;">/**</span><span style="color: rgb(0, 128, 0); background-color: inherit;"> Compare two WritableComparables.
</span><span style="color: rgb(0, 128, 128); background-color: inherit;"> </span><span style="color: rgb(0, 128, 0); background-color: inherit;">    *
</span><span style="color: rgb(0, 128, 128); background-color: inherit;"> </span><span style="color: rgb(0, 128, 0); background-color: inherit;">    * <p> The default implementation uses the natural ordering,
</span><span style="color: rgb(0, 128, 128); background-color: inherit;"> </span><span style="color: rgb(0, 128, 0); background-color: inherit;">    * calling {</span><span style="color: rgb(128, 128, 128); background-color: inherit;">@link</span><span style="color: rgb(0, 128, 128); background-color: inherit;">21</span><span style="color: rgb(0, 128, 0); background-color: inherit;">    * Comparable#compareTo(Object)}. </span><span style="color: rgb(0, 128, 0); background-color: inherit;">*/</span><span style="color: rgb(0, 128, 128); background-color: inherit;">22</span>     @SuppressWarnings("unchecked")
<span style="color: rgb(0, 128, 128); background-color: inherit;"> </span><span style="color: rgb(0, 0, 255); background-color: inherit;">public</span><span style="color: rgb(0, 0, 255); background-color: inherit;">int</span> compare(WritableComparable a, WritableComparable b) {
<span style="color: rgb(0, 128, 128); background-color: inherit;"> </span><span style="color: rgb(0, 0, 255); background-color: inherit;">return</span> a.compareTo(b);
<span style="color: rgb(0, 128, 128); background-color: inherit;"> </span>     }
<span style="color: rgb(0, 128, 128); background-color: inherit;"> </span>     ...
<span style="color: rgb(0, 128, 128); background-color: inherit;"> </span> }</span>
 
 

要实现字节级的Comparator,需要重载compare方法。这里先学习一下IntWritable类如何实现这个方法。

<pre style="font-size: 14px; line-height: 21px; font-family: 'Courier New' !important; background-color: inherit;"><span style="font-size: 12px;"><span style="color: rgb(0, 128, 128); background-color: inherit;">1 </span><span style="color: rgb(0, 0, 255); background-color: inherit;">public</span><span style="color: rgb(0, 0, 255); background-color: inherit;">class</span> IntWritable <span style="color: rgb(0, 0, 255); background-color: inherit;">implements</span> WritableComparable {
<span style="color: rgb(0, 128, 128); background-color: inherit;"> 2</span><span style="color: rgb(0, 128, 128); background-color: inherit;"> 3</span><span style="color: rgb(0, 0, 255); background-color: inherit;">public</span><span style="color: rgb(0, 0, 255); background-color: inherit;">static</span><span style="color: rgb(0, 0, 255); background-color: inherit;">class</span> Comparator <span style="color: rgb(0, 0, 255); background-color: inherit;">extends</span> WritableComparator {
<span style="color: rgb(0, 128, 128); background-color: inherit;"> 4</span><span style="color: rgb(0, 128, 128); background-color: inherit;"> 5</span><span style="color: rgb(0, 0, 255); background-color: inherit;">public</span> Comparator() {
<span style="color: rgb(0, 128, 128); background-color: inherit;"> 6</span><span style="color: rgb(0, 0, 255); background-color: inherit;">super</span>(IntWritable.<span style="color: rgb(0, 0, 255); background-color: inherit;">class</span>);
<span style="color: rgb(0, 128, 128); background-color: inherit;"> 7</span>         }
<span style="color: rgb(0, 128, 128); background-color: inherit;"> 8</span><span style="color: rgb(0, 128, 128); background-color: inherit;"> 9</span><span style="color: rgb(0, 0, 255); background-color: inherit;">public</span><span style="color: rgb(0, 0, 255); background-color: inherit;">int</span> compare(<span style="color: rgb(0, 0, 255); background-color: inherit;">byte</span>[] b1, <span style="color: rgb(0, 0, 255); background-color: inherit;">int</span> s1, <span style="color: rgb(0, 0, 255); background-color: inherit;">int</span> l1, <span style="color: rgb(0, 0, 255); background-color: inherit;">byte</span>[] b2, <span style="color: rgb(0, 0, 255); background-color: inherit;">int</span> s2, <span style="color: rgb(0, 0, 255); background-color: inherit;">int</span> l2) {
<span style="color: rgb(0, 128, 128); background-color: inherit;">10</span><span style="color: rgb(0, 0, 255); background-color: inherit;">int</span> thisValue = readInt(b1, s1);
<span style="color: rgb(0, 128, 128); background-color: inherit;">11</span><span style="color: rgb(0, 0, 255); background-color: inherit;">int</span> thatValue = readInt(b2, s2);
<span style="color: rgb(0, 128, 128); background-color: inherit;">12</span><span style="color: rgb(0, 0, 255); background-color: inherit;">return</span> (thisValue<thatValue ? -1 :
<span style="color: rgb(0, 128, 128); background-color: inherit;">13</span>             (thisValue==thatValue ? 0 : 1));
<span style="color: rgb(0, 128, 128); background-color: inherit;">14</span>         }
<span style="color: rgb(0, 128, 128); background-color: inherit;">15</span>     }
<span style="color: rgb(0, 128, 128); background-color: inherit;">16</span><span style="color: rgb(0, 128, 128); background-color: inherit;">17</span><span style="color: rgb(0, 0, 255); background-color: inherit;">static</span> {
<span style="color: rgb(0, 128, 128); background-color: inherit;">18</span>         WritableComparator.define(IntWritable.<span style="color: rgb(0, 0, 255); background-color: inherit;">class</span>, <span style="color: rgb(0, 0, 255); background-color: inherit;">new</span> Comparator());
<span style="color: rgb(0, 128, 128); background-color: inherit;">19</span>     }</span>
 
 

如果只使用内置的Writable,那就没有必要实现WritableComparator。它们都自带。如果需要使用自定义的Writable作为输出键,那么就需要自定义WritableComparator。这里基于前述Person类来说明如何实现。

在Person类中,有两个字符串类属性,firstName和lastName。使用writeUTF方法通过DataOutput输出它们。以下是实现代码。

</pre><pre style="font-size: 14px; line-height: 21px; font-family: 'Courier New' !important; background-color: inherit;"><span style="font-size: 12px;"><span style="color: rgb(0, 128, 128); background-color: inherit;"></span></span><pre name="code" class="plain"><pre style="line-height: 21px; font-size: 14px; font-family: 'Courier New' !important; background-color: inherit;"><span style="font-size: 12px;"><span style="color: rgb(0, 128, 128); background-color: inherit;">1</span><span style="color: rgb(0, 0, 255); background-color: inherit;">private</span> String firstName;
<span style="color: rgb(0, 128, 128); background-color: inherit;">2</span><span style="color: rgb(0, 0, 255); background-color: inherit;">private</span> String lastName;
<span style="color: rgb(0, 128, 128); background-color: inherit;">3</span><span style="color: rgb(0, 128, 128); background-color: inherit;">4</span> @Override
<span style="color: rgb(0, 128, 128); background-color: inherit;">5</span><span style="color: rgb(0, 0, 255); background-color: inherit;">public</span><span style="color: rgb(0, 0, 255); background-color: inherit;">void</span> write(DataOutput out) <span style="color: rgb(0, 0, 255); background-color: inherit;">throws</span> IOException {
<span style="color: rgb(0, 128, 128); background-color: inherit;">6</span>     out.writeUTF(lastName);
<span style="color: rgb(0, 128, 128); background-color: inherit;">7</span>     out.writeUTF(firstName);
<span style="color: rgb(0, 128, 128); background-color: inherit;">8</span> }</span>
 
  
 
 

首先需要理解Person对象是如何用字节形式表示的。writeUTF方法输出了字节长度(2个字节),字符内容(字符的长度,L1个字节)。如图6.41描述了字节是如何排列的。

假设需要对lastName和firstName进行字典式地比较(译注:就是看字典中的先后顺序)。显然不能直接用整个字节数组,因为其中还有字符长度。那么Comparator就需要足够聪明到能够跳过字符长度。以下是实现代码。

<pre style="line-height: 21px; font-family: 'Courier New' !important; background-color: inherit;"><span style="color: rgb(0, 128, 128); background-color: inherit;"> 1</span> @Override
<span style="color: rgb(0, 128, 128); background-color: inherit;"> 2</span><span style="color: rgb(0, 0, 255); background-color: inherit;">public</span><span style="color: rgb(0, 0, 255); background-color: inherit;">int</span> compare(<span style="color: rgb(0, 0, 255); background-color: inherit;">byte</span>[] b1, <span style="color: rgb(0, 0, 255); background-color: inherit;">int</span> s1, <span style="color: rgb(0, 0, 255); background-color: inherit;">int</span> l1, <span style="color: rgb(0, 0, 255); background-color: inherit;">byte</span>[] b2, <span style="color: rgb(0, 0, 255); background-color: inherit;">int</span> s2, <span style="color: rgb(0, 0, 255); background-color: inherit;">int</span> l2) {
<span style="color: rgb(0, 128, 128); background-color: inherit;"> 3</span><span style="color: rgb(0, 128, 128); background-color: inherit;"> 4</span><span style="color: rgb(0, 0, 255); background-color: inherit;">int</span> lastNameResult = compare(b1, s1, b2, s2);
<span style="color: rgb(0, 128, 128); background-color: inherit;"> 5</span><span style="color: rgb(0, 0, 255); background-color: inherit;">if</span> (lastNameResult != 0) {
<span style="color: rgb(0, 128, 128); background-color: inherit;"> 6</span><span style="color: rgb(0, 0, 255); background-color: inherit;">return</span> lastNameResult;
<span style="color: rgb(0, 128, 128); background-color: inherit;"> 7</span>     }
<span style="color: rgb(0, 128, 128); background-color: inherit;"> 8</span><span style="color: rgb(0, 0, 255); background-color: inherit;">int</span> b1l1 = readUnsignedShort(b1, s1);
<span style="color: rgb(0, 128, 128); background-color: inherit;"> 9</span><span style="color: rgb(0, 0, 255); background-color: inherit;">int</span> b2l1 = readUnsignedShort(b2, s2);
<span style="color: rgb(0, 128, 128); background-color: inherit;">10</span><span style="color: rgb(0, 0, 255); background-color: inherit;">return</span> compare(b1, s1 + b1l1 + 2, b2, s2 + b2l1 + 2);
<span style="color: rgb(0, 128, 128); background-color: inherit;">11</span> }
<span style="color: rgb(0, 128, 128); background-color: inherit;">12</span><span style="color: rgb(0, 128, 128); background-color: inherit;">13</span><span style="color: rgb(0, 0, 255); background-color: inherit;">public</span><span style="color: rgb(0, 0, 255); background-color: inherit;">static</span><span style="color: rgb(0, 0, 255); background-color: inherit;">int</span> compare(<span style="color: rgb(0, 0, 255); background-color: inherit;">byte</span>[] b1, <span style="color: rgb(0, 0, 255); background-color: inherit;">int</span> s1, <span style="color: rgb(0, 0, 255); background-color: inherit;">byte</span>[] b2, <span style="color: rgb(0, 0, 255); background-color: inherit;">int</span> s2) {
<span style="color: rgb(0, 128, 128); background-color: inherit;">14</span><span style="color: rgb(0, 0, 255); background-color: inherit;">int</span> b1l1 = readUnsignedShort(b1, s1);
<span style="color: rgb(0, 128, 128); background-color: inherit;">15</span><span style="color: rgb(0, 0, 255); background-color: inherit;">int</span> b2l1 = readUnsignedShort(b2, s2);
<span style="color: rgb(0, 128, 128); background-color: inherit;">16</span><span style="color: rgb(0, 0, 255); background-color: inherit;">return</span> compareBytes(b1, s1 + 2, b1l1, b2, s2 + 2, b2l1);
<span style="color: rgb(0, 128, 128); background-color: inherit;">17</span> }
<span style="color: rgb(0, 128, 128); background-color: inherit;">18</span><span style="color: rgb(0, 128, 128); background-color: inherit;">19</span><span style="color: rgb(0, 0, 255); background-color: inherit;">public</span><span style="color: rgb(0, 0, 255); background-color: inherit;">static</span><span style="color: rgb(0, 0, 255); background-color: inherit;">int</span> readUnsignedShort(<span style="color: rgb(0, 0, 255); background-color: inherit;">byte</span>[] b, <span style="color: rgb(0, 0, 255); background-color: inherit;">int</span> offset) {
<span style="color: rgb(0, 128, 128); background-color: inherit;">20</span><span style="color: rgb(0, 0, 255); background-color: inherit;">int</span> ch1 = b[offset];
<span style="color: rgb(0, 128, 128); background-color: inherit;">21</span><span style="color: rgb(0, 0, 255); background-color: inherit;">int</span> ch2 = b[offset + 1];
<span style="color: rgb(0, 128, 128); background-color: inherit;">22</span><span style="color: rgb(0, 0, 255); background-color: inherit;">return</span> (ch1 << 8) + (ch2);
<span style="color: rgb(0, 128, 128); background-color: inherit;">23</span> }
 
 


小结

 writeUTF只支持小于65536字符的字符串类。对于人名来说,是足够了。大点的,可能就不行。这个时候就需要使用Hadoop的Text类来支持更大的字符串。Text类中的Comparator类的二进制字符串比较器的实现机制和刚才介绍的大致相当。(这个修饰真长。)那么针对Text类的lastName和firstName的Comparator的实现方式也会累死。

下一节将介绍如何减小数据倾斜的影响。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值