Spark 集群

Spark集群部署模式
    1.local
    2.standalone
    3.mesos
    4.yarn

Spark闭包处理  
    分区列表,function,dep Option(分区类, Pair[Key,Value]),首选位置。
    运行job时,spark将rdd打碎变换成task,每个task由一个executor执行。执行    之前,spark会进行task的闭包(closure)计算。闭包是指针对executor可见的变量和方法,以备在rdd的foreach中进行计算。闭包就是串行化后并发送给每个executor.
    
    local模式下,所有spark程序运行在同一JVM中,共享对象,counter是可以累加的。
    原因是所有executor指向的是同一个引用。

    cluster模式下,不可以,counter是闭包处理的。每个节点对driver上的counter是不可见的。只能看到自己内部串行化的counter副本。
    

Spark的应用的部署模式
    格式:   spark-submit --class xxx xx.jar --deploy-mode (client | cluster)
    --deploy-mode指定是否部署driver程序在worker节点上还是在client主机上。

    [client]
    driver运行在client主机上。client可以不在cluster中。
    
    [cluster]
    driver程序提交给spark cluster的某个worker节点来执行。
    worker是cluster中的一员。
    导出的jar需要放置到所有worker节点都可见的位置(如hdfs)才可以。

    不论哪种方式,rdd的运算都在worker执行
    

部署模式验证

1.启动spark集群

2.编写测试类:

package com.mao.scala.scala.deployMode

import java.net.{InetAddress, Socket}

import org.apache.spark.{SparkConf, SparkContext}

object DeployModeTest {

  /**
    * 运行时将数据发送至某个服务器
    * @param str
    */
  def printInfo(str : String): Unit ={
    val ip = InetAddress.getLocalHost.getHostAddress
    val sock = new Socket("192.168.247.205", 8888)
    val out = sock.getOutputStream
    out.write((ip + " : " + str + "\r\n").getBytes)
    out.flush()
    sock.close()
  }

  def main(args: Array[String]): Unit = {
    val conf = new SparkConf()
    conf.setAppName("deploy")
    //conf.setMaster("local[4]")  //本地模式
    //conf.setMaster("spark://s201:7077")  //spark集群模式
    conf.setMaster("yarn")    //yarn集群模式
    val sc  = new SparkContext(conf)
    printInfo("hello world");

    val  rdd1 = sc.parallelize(1 to 10,3)
    val rdd2 = rdd1.map(e =>{
      printInfo("rdd1 map: "+e)
      e * 2
    })
    val rdd3 = rdd2.repartition(2)
    val rdd4 = rdd3.map(e =>{
      printInfo("rdd3 map: "+e)
      e
    })
    val res = rdd4.reduce((a,b)=>{
      printInfo("rdd4 reduce : "+a+","+b)
      a+b
    })
    printInfo("driver : " + res + "")
  }
}

3.打包
        jar
        对于cluster部署模式,必须要将jar放置到所有worker都能够看到的地方才可以,例如hdfs。

4.将jar包上传到spark master服务器

5.提交job到spark集群

#客户端模式运行
spark-submit --class com.mao.scala.scala.deployMode.DeployModeTest --master  spark://s201:7077 --deploy-mode client scalaDemo-1.0-SNAPSHOT.jar

#分发jar到所有节点的相同目录下,在spark集群运行
spark-submit --class com.mao.scala.scala.deployMode.DeployModeTest --master  spark://s201:7077 --deploy-mode cluster scalaDemo-1.0-SNAPSHOT.jar

#上传jar到hdfs,使用hdfs上的文件运行
hdfs dfs -put  scalaDemo-1.0-SNAPSHOT.jar /user/admin/
spark-submit --class com.mao.scala.scala.deployMode.DeployModeTest --master  spark://s201:7077 --deploy-mode cluster hdfs://s201:8020/user/admin/scalaDemo-1.0-SNAPSHOT.jar

 

spark集群的运行方式

主要是cluster manager的区别。

    local
    [standalone]
        使用SparkMaster进程作为管理节点.

    [mesos]
        使用mesos的master作为管理节点。

    [yarn]
        使用hadoop的ResourceManager作为master节点。不用spark的master.
        不需要启动spark-master节点。也不需要。
        
        确保HADOOP_CONF_DIR和YARN_CONF_DIR环境变量指向了包含了hadoop配置文件的目录。
        这些文件确保向hdfs写入数据并且连接到yarn的resourcemanager.这些配置分发到yarn集群,
        确保所有节点的配置是一致的。配置中设置的所有属性确保所有节点都能找到。

        在yarn上运行spark应用,可以采用两种部署模式。cluster:driver运行在appmaster进程中。
        client:driver运行在client进程中,AppMaster只用于请求资源。

        yarn模式    :--master yarn(yarn-site.xml)
        standalone    : --master spark://s2001:7077
        mesos        : --master mesos//xxx:xxx

spark job 提交到yarn 集群

1.从hadoop/etc/hadoop 复制core-site.xml yarn-site.xml 到spark/conf

2.修改/soft/sparl/conf/spark-env.sh

export HADOOP_CONF_DIR=/soft/hadoop/etc/hadoop
export SPARK_EXECUTOR_INSTANCES=3
export SPARK_EXECUTOR_CORES=1

3.将spark的jars文件放到hdfs上(减少job运行时间)

hdfs dfs -mkdir -p /user/centos/spark/jars
hdfs dfs -put  /soft/spark/jars/*  /user/centos/spark/jars

 4.配置spark属性文件

[/spark/conf/spark-default.conf]
spark.yarn.jars hdfs://mycluster/user/centos/spark/jars/*

 5.提交

#yarn + cluster模式(此模式与spark集群无关)
spark-submit --class com.mao.scala.scala.deployMode.DeployModeTest --master yarn --deploy-mode cluster  hdfs://mycluster/user/admin/scalaDemo-1.0-SNAPSHOT.jar
#yarn + client 模式(此模式与spark集群无关)
spark-submit --class com.mao.scala.scala.deployMode.DeployModeTest --master yarn --deploy-mode client scalaDemo-1.0-SNAPSHOT.jar

 yarn + client 模式异常记录:

Exception in thread "main" org.apache.spark.SparkException: Yarn application has already ended! It might have been killed or unable to launch application master.
	at org.apache.spark.scheduler.cluster.YarnClientSchedulerBackend.waitForApplication(YarnClientSchedulerBackend.scala:89)
	at org.apache.spark.scheduler.cluster.YarnClientSchedulerBackend.start(YarnClientSchedulerBackend.scala:63)
	at org.apache.spark.scheduler.TaskSchedulerImpl.start(TaskSchedulerImpl.scala:164)
	at org.apache.spark.SparkContext.<init>(SparkContext.scala:500)
	at com.mao.scala.scala.deployMode.DeployModeTest$.main(DeployModeTest.scala:23)
	at com.mao.scala.scala.deployMode.DeployModeTest.main(DeployModeTest.scala)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.apache.spark.deploy.JavaMainApplication.start(SparkApplication.scala:52)
	at org.apache.spark.deploy.SparkSubmit$.org$apache$spark$deploy$SparkSubmit$$runMain(SparkSubmit.scala:894)
	at org.apache.spark.deploy.SparkSubmit$.doRunMain$1(SparkSubmit.scala:198)
	at org.apache.spark.deploy.SparkSubmit$.submit(SparkSubmit.scala:228)
	at org.apache.spark.deploy.SparkSubmit$.main(SparkSubmit.scala:137)
	at org.apache.spark.deploy.SparkSubmit.main(SparkSubmit.scala)

原因: 虚拟内存的实际值超过了设置的值,即虚拟内存超限,contrainer被结束,容器没有了,肯定失败

解决办法:停止yarn集群,在hadoop的yarn-site.xml文件增加如下配置,然后重启yarn集群

<!--以下为解决spark-shell 以yarn client模式运行报错问题而增加的配置,估计spark-summit也会有这个问题。2个配置只用配置一个即可解决问题,当然都配置也没问题-->
<!--虚拟内存设置是否生效,若实际虚拟内存大于设置值 ,spark 以client模式运行可能会报错,"Yarn application has already ended! It might have been killed or unable to l"-->
<property>
    <name>yarn.nodemanager.vmem-check-enabled</name>
    <value>false</value>
    <description>Whether virtual memory limits will be enforced for containers</description>
</property>
<!--配置虚拟内存/物理内存的值,默认为2.1,物理内存默认应该是1g,所以虚拟内存是2.1g-->
<property>
    <name>yarn.nodemanager.vmem-pmem-ratio</name>
    <value>4</value>
    <description>Ratio between virtual memory to physical memory when setting memory limits for containers</description>
</property>

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值