hadoop负载平衡

hadoop负载平衡,hadoop,mapreduce,Hadoop,Mapreduce,我以以下格式生成了多个不同的密钥: “7112”、“6923”、“6856”等 但是,我发现这些对中的大多数都指向相同的减缩器 即使我实现了一个自定义分区器,我们使用的getNumPartitioner方法hash_val%numReducers也大多返回值,这些值将加载它们的几个还原器分组,而其他还原器保持空闲。 , 根据我的理解,我们可以使用WritableComparator对键进行排序,但不能控制键进入不同的还原器 有没有改进负载平衡的方法?请帮忙 我在下面附上一些代码,以明确我的解释

我以以下格式生成了多个不同的密钥:

“7112”、“6923”、“6856”等

但是,我发现这些对中的大多数都指向相同的减缩器

即使我实现了一个自定义分区器,我们使用的getNumPartitioner方法hash_val%numReducers也大多返回值,这些值将加载它们的几个还原器分组,而其他还原器保持空闲。 , 根据我的理解,我们可以使用WritableComparator对键进行排序,但不能控制键进入不同的还原器

有没有改进负载平衡的方法?请帮忙

我在下面附上一些代码,以明确我的解释:

String a = "71 1 2";
String b = "72 1 1";
String c = "70 1 3";

int hash_a = a.hashCode();
int hash_b = b.hashCode();
int hash_c = c.hashCode();

int part_a = hash_a % 10;
int part_b = hash_b % 10;
int part_c = hash_c % 10;

System.out.println("hash a: "+hash_a+" part_a: "+part_a);
System.out.println("hash b: "+hash_b+" part_b: "+part_b);
System.out.println("hash c: "+hash_c+" part_c: "+part_c);
输出:

散列a:1620857277第a部分:7 散列b:1621780797第b部分:7 散列c:1619933757部分c:7

正如我们看到的,不同的键倾向于映射到同一个减速器


请帮忙!谢谢

首先,您不能简单地接受java模数运算,因为有时哈希代码可能是负数,而且肯定没有所谓的负分区。所以你可以取一个绝对值

第二个是我在网上找到的一个强大的散列函数。它生成64位长的整数,而不是普通的32位整数。同样,这也会遇到负分区的问题,但您可以自己纠正

private static long[] byteTable;
private static final long HSTART = 0xBB40E64DA205B064L;
private static final long HMULT = 7664345821815920749L;

private static long[] createLookupTable() {
byteTable = new long[256];
long h = 0x544B2FBACAAF1684L;
for (int i = 0; i < 256; i++) {
  for (int j = 0; j < 31; j++) {
    h = (h >>> 7) ^ h;
    h = (h << 11) ^ h;
    h = (h >>> 10) ^ h;
  }
  byteTable[i] = h;
}
return byteTable;
}
public static long hash(String s) {
byte[] data = s.getBytes();
long h = HSTART;
final long hmult = HMULT;
final long[] ht = createLookupTable();
for (int len = data.length, i = 0; i < len; i++) {
  h = (h * hmult) ^ ht[data[i] & 0xff];
}
return h;
} 

public static void main(String[] args) {

String a = "71 1 2";
String b = "72 1 1";
String c = "70 1 3";

long hash_a = hash(a);
long hash_b = hash(b);
long hash_c = hash(c);

long part_a = hash_a % 10;
long part_b = hash_b % 10;
long part_c = hash_c % 10;

System.out.println("hash a: "+hash_a+" part_a: "+part_a);
System.out.println("hash b: "+hash_b+" part_b: "+part_b);
System.out.println("hash c: "+hash_c+" part_c: "+part_c);
}
私有静态长[]字节表;
专用静态最终长HSTART=0xBB40E64DA205B064L;
专用静态最终长HMULT=7664345821815920749L;
私有静态long[]createLookupTable(){
byteTable=新长[256];
长h=0x544B2FBACAAF1684L;
对于(int i=0;i<256;i++){
对于(int j=0;j<31;j++){
h=(h>>>7)^h;
h=(h>>10)^h;
}
byteTable[i]=h;
}
返回字节表;
}
公共静态长哈希(字符串s){
字节[]数据=s.getBytes();
长h=HSTART;
最终长hmult=hmult;
final long[]ht=createLookupTable();
for(int len=data.length,i=0;i
看起来您有一个数据倾斜问题,您需要在分区程序中更聪明一点。您可以尝试以下几点:

  • Hadoop附带了一个实现。您可以尝试在分区器中使用它来代替hashCode(),这可能会使分区更加均匀
  • 也许你需要超越散列。是否有任何关于如何生成密钥的信息可供利用以获得更均匀的分发?例如,在键“71 1 2”上,您是否可以在空间上拆分并按分区数修改第一个数字(例如71)

您没有提到数据中的某些键是否确实是重复的。如果是这样的话,a可能会有所帮助

我不确定使用“更好”的散列函数是否有帮助,因为不平衡的分布可能是由于您处理的数据的性质造成的。对于相同的输入,哈希函数总是给出相同的输出

不知道为什么这些哈希代码如此相似,但我总是使用素数的减缩器。为什么不使用默认的HashPartitioner?@Jugde将尝试设置素数减缩器以检查性能是否有所提高。net@Razvan,即使是hash partitioner也不会给出偶数结果。。谢谢!我想,这会解决我的问题。。将实施并查看!Apurv提供的Hash函数确实带来了更好的负载平衡