为什么Hadoop作业需要这么多线程?

时间:2014-02-17 21:09:37

标签: java multithreading hadoop apache-pig

我对Hadoop的理解是,每个计算节点上的并行性是通过为每个核心启动单独的jvms来实现的。

我观察到每个jvm拥有数十个线程,每个节点导致数千个线程。我想不出任何产生这么多线程的理由。这是怎么回事?

例如,这是一个简单的猪脚本,用于解析和过滤一些jsons:

/*
 * Get tweets with GPS
 */
REGISTER $JAR;

json_eb = LOAD '$IN_DIRS' USING com.twitter.elephantbird.pig.load.JsonLoader('-nestedLoad') as (json:map[]);

--parse json with twitter's library
parsed0 = FOREACH json_eb GENERATE  STRSPLIT(json#'id',':').$2 AS tweetId:chararray,
                                    STRSPLIT(json#'actor'#'id',':').$2 AS userId:chararray,
                                    json#'postedTime' AS postedTime:chararray,
                                    json#'geo'#'coordinates' AS gps:chararray;
parsed1 = FILTER parsed0 BY (gps IS NOT NULL);

STORE parsed1 INTO '$OUT_DIR' USING PigStorage();

我运行此脚本,mapred用户在我的节点上启动33个进程(我有32个核心):

rfcompton@node19 ~> ps -u mapred | grep -v PID | wc -l
33

看顶部:

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                                                                                    
  484 mapred    39  16 1576m 362m  18m S 130.8  0.3   0:09.48 java                                                                                                                                      
32427 mapred    34  16 1664m 369m  18m S 122.2  0.3   0:08.67 java                                                                                                                                      
32694 mapred    36  16 1502m 239m  18m S 115.6  0.2   0:07.94 java                                                                                                                                      
32218 mapred    33  16 1669m 401m  18m S 114.6  0.3   0:10.29 java  
...

jvms似乎每个都有大约40个线程:

rfcompton@node19 ~> cat /proc/484/status | grep Threads
Threads:    43

总之,mapred在32核节点上有超过一千个线程:

rfcompton@node19 ~> ps -u mapred | grep -v PID | awk '{system("cat /proc/"$1"/status")}' | grep Threads | awk '{ SUM += $2} END { print SUM }'
1655

编辑:根据Paul的回答,在阅读“Hadoop - The Definitive Guide”中的相关部分后,似乎有40个主题是我应该期待的。它们的存在是为了通过HTTP将映射的输出提供给作业的后期阶段。

  

输出文件的分区可供减压器使用   HTTP。用于提供文件分区的工作线程数   由任务tracker.http.threads属性控制 - 此设置   是每个tasktracker,而不是每个map任务槽。默认值40可能需要   对于运行大型工作的大型集群而言正在增加。

2 个答案:

答案 0 :(得分:5)

所有hadoop实现我见过多线程。基本上,将工作从地图任务转移到减速器的大多数任务都是平行化的,地图任务和减少任务本身也是如此。

检查“Hadoop - The Definitive Guide”,作者提到了许多多线程的进程。其中包括

  1. Reducers有一小部分“复印机”线程来获取并行中的地图输出。
  2. Mappers本身可以是多线程的(MultithreadedMapper)
  3. DataNodes具有在HDFS上复制数据的线程。
  4. 根据群集的配置方式,您可以在同一台计算机上安装DataNodes和TaskTrackers,这可以开始添加到很多线程中。

    我猜大量使用并发性具有显着的性能优势,这就是实现者走这条路的原因。

答案 1 :(得分:0)

正如Chrylis所提到的,JVM有一些GC线程,可能还有其他线程正在运行。

对于用户应用程序,多个线程非常有用。

此示例是打开文件,读取每一行然后执行一些处理的情况。当线程从文件读取时,CPU通常不会工作太多,因为它将花费大部分时间等待慢速硬盘返回数据。通过使用多个线程,可以更好地利用CPU。如果你的程序使用线程,一些线程可能正在做一些有用的事情,而其他线程正在等待IO操作完成。

我没有使用Hadoop,但我认为在拆分工作时,一个节点实际上可能因此而运行多个作业。它们可能还包含一些线程,用于与集群的其他部分进行协调。