• Spark读取HDFS文件,任务本地化(NODE_LOCAL)


    Spark也有数据本地化的概念(Data Locality),这和MapReduce的Local Task差不多,如果读取HDFS文件,Spark则会根据数据的存储位置,分配离数据存储最近的Executor去执行任务。

    这么理解没错,我搭建的Spark集群情况是这样:

    15台DataNode节点的HDFS集群,我在每个DataNode上都部署了一个Spark Worker,并且,启动Spark Application的时候,每个Worker都有一个Executor,这样理论上来说,只要读取HDFS文件,Spark都可以使用本地任务来读取(NODE_LOCAL)。

    在$SPARK_HOME/conf/slaves文件中配置了每个Worker的hostname,之后在Master上,执行$SPARK_HOME/sbin/start-slaves.sh来启动Workers,启动之后集群如图显示:

    需要大数据学习资料和交流学习的同学可以加大数据学习群:724693112 有免费资料分享和一群学习大数据的小伙伴一起努力


     

    进入spark-sql,从hive中扫描一张表,执行情况如下:


     

    奇怪的是,所有读取HDFS文件的Task Locality Level全部是ANY,也就是说,没有一个使用NODE_LOCAL本地化任务,这样导致集群的网络消耗非常大(因为所有的数据都要经网络拷贝一遍),如图,后面那个峰值是执行任务的网络情况:


     

    直接说原因和解决办法吧。

    请注意最上面集群情况的图中,Worker Id和Address中都使用的IP地址作为Worker的标识,而HDFS集群中一般都以hostname作为slave的标识,这样,Spark从HDFS中获取文件的保存位置对应的是hostname,而Spark自己的Worker标识为IP地址,两者不同,因此没有将任务的Locality Level标记为NODE_LOCAL,而是ANY。奇怪的是,我在Spark的slaves文件中都配置的是hostname,为何集群启动后都采用了IP地址?最大的可能是/etc/hosts文件的配置。

    大数据学习交流群:724693112 欢迎想学习大数据和需要大数据学习资料的同学来一起学习。

    解决办法是:没有采用slaves文件+start-slaves.sh的方式启动,而是每台Worker单独启动,

    使用命令:$SPARK_HOME/sbin/start-slave.sh -h ,这样启动之后,Spark WEBUI中Worker Id和Address中都以hostname来显示了,如图:


     

    再次进入spark-sql,执行同样的任务,所有的Task Locality Level都是NODE_LOCAL,没有网络传输,速度比之前快了好几倍。


     

    这才是期望的结果,至于导致salves文件中配置的明明是hostname,为何Spark集群中解析成IP地址的原因,后续再查吧。

  • 相关阅读:
    hdu 2586(最近公共祖先LCA)
    hdu 3394(点双连通)
    hdu 4005(边双连通)
    hdu 2460(tarjan求边双连通分量+LCA)
    【转载】8天学通MongoDB——第四天 索引操作
    【转载】8天学通MongoDB——第三天 细说高级操作
    [转载]MongoDB开发学习 经典入门
    【原创】jQuery 仿百度输入标签插件
    ★《唐琅探案》后记【2】
    ★《唐琅探案》后记【1】
  • 原文地址:https://www.cnblogs.com/feiyudemeng/p/9254003.html
Copyright © 2020-2023  润新知