首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >hadoop负载均衡

hadoop负载均衡
EN

Stack Overflow用户
提问于 2012-07-21 11:27:59
回答 3查看 931关注 0票数 1

我有多个不同的密钥生成,格式如下:

"71 1 2“、"69 2 3”、"68 56“等。

但是,我发现这些对中的大多数都去了相同的减速器。

即使我实现了一个自定义分区程序,我们在其中使用hash_val % numReducers的getNumPartitioner方法也主要返回值,它会将值分组到加载它们的几个缩减程序中,而其他缩减程序仍然是空闲的。,根据我的理解,我们可以使用WritableComparator对键进行排序,但不能控制键去不同的reducers。

有没有办法改善负载均衡?请帮帮忙。

为了让我的解释更清楚,我附上了下面的一些代码:

代码语言:javascript
复制
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);

输出:

hash a: 1620857277 part_a: 7 hash b: 1621780797 part_b: 7 hash c: 1619933757 part_c: 7

正如我们所看到的,不同的关键点往往映射到相同的reducer。

请帮帮我!谢谢!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-07-21 15:07:10

首先,您不能简单地采用java取模操作,因为有时hashcode可能是负的,并且肯定不存在所谓的负分区。所以你可能会取一个绝对值。

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

代码语言:javascript
复制
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);
}
票数 1
EN

Stack Overflow用户

发布于 2012-07-21 19:59:17

看起来你有一个数据倾斜的问题,你需要在你的分区工具中更聪明一点。下面是一些你可以尝试的东西:

  • Hadoop附带了一个MurmurHash实现。你可以试着在你的分区程序中使用它来代替hashCode(),也许这会让你获得更多的partitions.
  • Maybe,你需要超越散列。有没有什么关于你的密钥是如何生成的,你可以利用它来获得更均匀的分布?例如,在键"71 1 2“上,您是否可以拆分空间并按分区数修改第一个数字(例如71)?

您没有提到数据中的一些键是否实际上是重复的。如果是这样的话,custom combiner可能会有所帮助。

票数 1
EN

Stack Overflow用户

发布于 2015-08-28 05:14:39

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11589202

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档