一直在想:如何在 Hadoop.MapReduce 中,插入一个 C 写的 HashFunction,既要高效,又要接口简洁。通过命令行实现调用显然是不行的。刚刚终于想出了:使用管道!
一个非常简单的程序,从stdin读入,写到stdout。多简单!至于效率,管道嘛,本质上就是异步的,自然是buffered&asynchronous 模式。
hash 程序
#include <stdio.h> int hash(const char* key) { int h = 234234; for (; *key; ++key) h = h << 3 ^ *key; return h; } int main(int argc, char*[] argv) { char buf[256]; while (fgets(buf, sizeof(buf), stdin) != EOF) { printf("%d\n", hash(buf)); } return 0; }
框架可以一边不断往管道写key,一边从中读取结果,这两个工作完全可以是异步的。对hash程序来说,如果stdin/stdout是全缓冲的,就几乎没有io的开销,因为几百几千次 fgets/printf 才会导致一次系统调用。
对frame程序也是一样的。
在 hadoop.streaming 中,hash 函数目前还必须由 java 类指定,如果使用这种方式,那就更 unix 了。