我对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可能需要 对于运行大型工作的大型集群而言正在增加。
答案 0 :(得分:5)
所有hadoop实现我见过多线程。基本上,将工作从地图任务转移到减速器的大多数任务都是平行化的,地图任务和减少任务本身也是如此。
检查“Hadoop - The Definitive Guide”,作者提到了许多多线程的进程。其中包括
根据群集的配置方式,您可以在同一台计算机上安装DataNodes和TaskTrackers,这可以开始添加到很多线程中。
我猜大量使用并发性具有显着的性能优势,这就是实现者走这条路的原因。
答案 1 :(得分:0)
正如Chrylis所提到的,JVM有一些GC线程,可能还有其他线程正在运行。
对于用户应用程序,多个线程非常有用。
此示例是打开文件,读取每一行然后执行一些处理的情况。当线程从文件读取时,CPU通常不会工作太多,因为它将花费大部分时间等待慢速硬盘返回数据。通过使用多个线程,可以更好地利用CPU。如果你的程序使用线程,一些线程可能正在做一些有用的事情,而其他线程正在等待IO操作完成。
我没有使用Hadoop,但我认为在拆分工作时,一个节点实际上可能因此而运行多个作业。它们可能还包含一些线程,用于与集群的其他部分进行协调。