如何从Docker容器内启动Spark-Mesos作业?

时间:2017-04-18 20:02:26

标签: apache-spark docker pyspark mesos

要点:

是否可以从Docker容器内部提交一个Spark作业,其中1个Mesos主服务器(没有Zookeeper)和1个Mesos代理也分别运行在单独的Docker容器中(目前在同一主机上)?在http://mesos.apache.org/documentation/latest/container-image/中描述的Mesos容器似乎适用于将Mesos应用程序简单地封装在Docker容器中并运行的情况。我的Docker应用程序更具交互性,多个PySpark Mesos作业在运行时根据用户输入进行实例化。 Docker容器中的驱动程序本身不作为Mesos应用程序运行。只有用户发起的作业请求才能作为PySpark Mesos应用程序处理。

具体细节:

我有3个基于centos的Docker容器:7个linux,现在在同一台主机上运行:

  1. Container" Master"运行Mesos Master。

  2. Container" Agent"运行Mesos代理。

  3. 容器"测试"安装Spark和Mesos,运行bash shell并从命令行启动以下PySpark测试程序。

    from pyspark import SparkContext, SparkConf
    from operator import add
    
    # Configure Spark                                               
    sp_conf = SparkConf()
    sp_conf.setAppName("spark_test")
    sp_conf.set("spark.scheduler.mode", "FAIR")
    sp_conf.set("spark.dynamicAllocation.enabled", "false")
    sp_conf.set("spark.driver.memory", "500m")
    sp_conf.set("spark.executor.memory", "500m")
    sp_conf.set("spark.executor.cores", 1)
    sp_conf.set("spark.cores.max", 1)
    sp_conf.set("spark.mesos.executor.home", "/usr/local/spark-2.1.0")
    sp_conf.set("spark.executor.uri", "file://usr/local/spark-2.1.0-bin-without-hadoop.tgz")
    sc = SparkContext(conf=sp_conf)
    
    # Simple computation
    x = [(1.5,100.),(1.5,200.),(1.5,300.),(2.5,150.)]
    rdd = sc.parallelize(x,1)
    tot = rdd.foldByKey(0,add).collect()
    cnt = rdd.countByKey()
    time = [t[0] for t in tot]
    avg = [t[1]/cnt[t[0]] for t in tot]
    print 'tot=', tot
    print 'cnt=', cnt
    print 't=', time
    print 'avg=', avg
    
  4. 我使用的相关软件版本如下:

    • Hadoop:2.7.3
    • Spark:2.1.0
    • Mesos:1.2.0
    • Docker:17.03.1-ce,build c6d412e

    以下工作正常:

    • 我可以使用Spark的MASTER=local[N] N=1N=4来运行上面的简单PySpark测试程序。

    • 我可以在Mesos日志和Mesos用户界面(UI)中看到Mesos代理和主服务器正常运行。 Mesos UI显示代理连接了大量资源(cpu,内存,磁盘)。

    • 我可以使用/usr/local/mesos-1.2.0/build/src/examples/python/test-framework 127.0.0.1:5050从Test容器内成功运行Mesos Python测试。这似乎证实可以从我的Test容器中访问Mesos容器,但这些测试不使用Spark。

    这是失败:

    使用Spark的MASTER=mesos://127.0.0.1:5050,当我从Test容器内部启动PySpark测试程序时,Mesos Master和Agent的日志中都有活动,并且在失败前的几秒内, Mesos UI显示为作业分配的资源,这些资源完全在可用的范围内。然而,PySpark测试程序失败了: WARN scheduler.TaskSchedulerImpl:初始作业没有接受任何资源;检查您的集群UI以确保工作人员已注册并具有足够的资源

    我遵循的步骤如下。

    启动Mesos Master:

    docker run -it --net=host -p 5050:5050 the_master
    

    主人日志中的相关摘录显示:

      

    I0418 01:05:08.540192 27 master.cpp:383] Master 15b354eb-6a20-4bc9-a13b-6533b1e91bd2(localhost)在127.0.0.1:5050上启动
      I0418 01:05:08.540210 27 master.cpp:385]启动时的标志: - agent_ping_timeout =" 15secs" --agent_reregister_timeout =" 10分钟" --allocation_interval =" 1secs" --allocator =" HierarchicalDRF" --authenticate_agents ="假" --authenticate_frameworks ="假" --authenticate_http_frameworks ="假" --authenticate_http_readonly ="假" --authenticate_http_readwrite ="假" --authenticators =" CRAMMD5" --authorizers ="本地" --framework_sorter =" DRF" --help ="假" --hostname_lookup ="真" --http_authenticators ="碱性" --initialize_driver_logging ="真" --log_auto_initialize ="真" --logbufsecs =" 0" --logging_level =" INFO" --max_agent_ping_timeouts =" 5" --max_completed_frameworks =" 50" --max_completed_tasks_per_framework =" 1000" --max_unreachable_tasks_per_framework =" 1000" --quiet ="假" --recovery_agent_removal_limit =" 100%" --registry =" replicated_log" --registry_fetch_timeout =" 1mins" --registry_gc_interval =" 15分钟" --registry_max_agent_age ="2周" --registry_max_agent_count =" 102400" --registry_store_timeout =" 20secs" --registry_strict ="假" --root_submissions ="真" --user_sorter =" DRF" --version ="假" --webui_dir =" /usr/local/mesos-1.2.0/build /../的src / WebUI中" --work_dir ="在/ var / lib中/ mesos" --zk_session_timeout =" 10secs"

    启动Mesos代理:

    docker run -it --net=host -e MESOS_AGENT_PORT=5051 the_agent
    

    代理商的日志显示:

      

    I0418 01:42:00.234244 40 slave.cpp:212]启动时的标志: - appc_simple_discovery_uri_prefix =" http://" --appc_store_dir =" / TMP / mesos /存储/ APPC" --authenticate_http_readonly ="假" --authenticate_http_readwrite ="假" --authenticatee =" CRAMMD5" --authentication_backoff_factor =" 1secs" --authorizer ="本地" --cgroups_cpu_enable_pids_and_tids_count ="假" --cgroups_enable_cfs ="假" --cgroups_hierarchy =" / SYS / FS / cgroup中" --cgroups_limit_swap ="假" --cgroups_root =" mesos" --container_disk_watch_interval =" 15secs" --containerizers =" mesos" --default_role =" *" --disk_watch_interval =" 1mins" --docker ="搬运工" --docker_kill_orphans ="真" --docker_mesos_image ="火花mesos剂试验" --docker_registry =" HTTPS://registry-1.docker.io" --docker_remove_delay =" 6小时" --docker_socket =" /var/run/docker.sock" --docker_stop_timeout ="为0ns" --docker_store_dir =" / TMP / mesos /存储/搬运工" --docker_volume_checkpoint_dir ="在/ var /运行/ mesos /隔离器/搬运工/体积" --enforce_container_disk_quota ="假" --executor_registration_timeout =" 1mins" --executor_shutdown_grace_period =" 5secs" --fetcher_cache_dir =" / TMP / mesos /取" --fetcher_cache_size =" 2GB" --frameworks_home ="" --gc_delay ="1周" --gc_disk_headroom =" 0.1" --hadoop_home ="" --help ="假" --hostname_lookup ="真" --http_authenticators ="碱性" --http_command_executor ="假" --http_heartbeat_interval =" 30secs" --initialize_driver_logging ="真" --isolation =" POSIX / CPU,POSIX / MEM" --launcher =" POSIX" --launcher_dir =" /usr/local/mesos-1.2.0/build/src" --logbufsecs =" 0" --logging_level =" INFO" --max_completed_executors_per_framework =" 150" --oversubscribed_resources_interval =" 15secs" --perf_duration =" 10secs" --perf_interval =" 1mins" --qos_correction_interval_min ="为0ns" --quiet ="假" --recover ="重新连接" --recovery_timeout =" 15分钟" --registration_backoff_factor =" 1secs" --revocable_cpu_low_priority ="真" --runtime_dir ="在/ var /运行/ mesos" --sandbox_directory =" / MNT / mesos /沙箱" --strict ="真" --switch_user ="假" --systemd_enable_support ="假" --systemd_runtime_directory =" /运行/ systemd /系统" --version ="假" --work_dir ="在/ var / lib中/ mesos"

    我对Mesos Master和Agent都收到以下警告,但忽略它,因为我现在正在同一台主机上运行所有内容:

      

    Master / Agent绑定到loopback接口!无法与远程调度程序或代理程序通信。您可能想要设置' - ip'标记为可路由的IP地址。

    事实上,我分配可路由IP地址而不是127.0.0.1的测试无法改变我在此描述的任何行为。

    启动测试容器(使用bash shell进行测试):

    docker run -it --net=host the_test /bin/bash
    

    在所有三个容器(Master,Agent和Test)中设置了一些相关的环境变量:

      

    HADOOP_HOME =的/ usr /本地/ Hadoop的2.7.3
      HADOOP_CONF_DIR =的/ usr /本地/ Hadoop的2.7.3的/ etc / hadoop的
      SPARK_HOME =的/ usr /本地/火花2.1.0
      SPARK_EXECUTOR_URI =文件:////usr/local/spark-2.1.0-bin-without-hadoop.tgz
      MASTER = mesos://127.0.0.1:5050
      PYSPARK_PYTHON =在/ usr /本地/ anaconda2 /斌/ Python的
      PYSPARK_DRIVER_PYTHON =在/ usr /本地/ anaconda2 /斌/ Python的
      PYSPARK_SUBMIT_ARGS = - driver-memory = 4g pyspark-shell
      MESOS_PORT = 5050
      MESOS_IP = 127.0.0.1
      MESOS_WORKDIR =的/ var / lib中/ mesos
      MESOS_HOME =的/ usr /本地/ mesos-1.2.0
      MESOS_NATIVE_JAVA_LIBRARY =在/ usr / local / lib目录/ libmesos.so
      MESOS_MASTER = mesos://127.0.0.1:5050
      PYTHONPATH =:在/ usr /本地/火花2.1.0 /蟒:/usr/local/spark-2.1.0/python/lib/py4j-0.10.1-src.zip

    从Test容器内部运行Mesos(非Spark)测试:

    /usr/local/mesos-1.2.0/build/src/examples/python/test-framework 127.0.0.1:5050
    

    这会产生以下日志输出(我认为如预期的那样):

      

    I0417 21:28:36.912542 20 sched.cpp:232]版本:1.2.0
      I0417 21:28:36.920013 62 sched.cpp:336]在master@127.0.0.1检测到新的主站:5050
      I0417 21:28:36.920472 62 sched.cpp:352]没有提供凭据。试图在没有认证的情况下注册   I0417 21:28:36.924165 62 sched.cpp:759]框架注册为be89e739-be8d-430e-b1e9-3fe55fa18459-0000
      注册框架ID be89e739-be8d-430e-b1e9-3fe55fa18459-0000
      收到报价be89e739-be8d-430e-b1e9-3fe55fa18459-O0,cpu:16.0和mem:119640.0
      使用报价be89e739-be8d-430e-b1e9-3fe55fa18459-O0启动任务0   使用报价启动任务1 be89e739-be8d-430e-b1e9-3fe55fa18459-O0
      使用报价启动任务2 be89e739-be8d-430e-b1e9-3fe55fa18459-O0
      使用报价启动任务3 be89e739-be8d-430e-b1e9-3fe55fa18459-O0
      使用报价启动任务4 be89e739-be8d-430e-b1e9-3fe55fa18459-O0
      任务0处于状态TASK_RUNNING
      任务1处于状态TASK_RUNNING
      任务2处于状态TASK_RUNNING
      任务3处于状态TASK_RUNNING
      任务4处于状态TASK_RUNNING
      任务0处于状态TASK_FINISHED
      任务1处于状态TASK_FINISHED
      任务2处于状态TASK_FINISHED
      任务3处于状态TASK_FINISHED
      任务4处于状态TASK_FINISHED
      完成所有任务,等待最终框架消息
      收到消息:'数据带有\ x00字节'
      收到消息:'数据带有\ x00字节'
      收到消息:'数据带有\ x00字节'
      收到消息:'数据带有\ x00字节'
      收到消息:'数据带有\ x00字节'
      所有已完成的任务以及收到的所有消息都已退出

    从Test容器内运行PySpark测试程序:

    python spark_test.py 
    

    这会产生以下日志输出:

      

    17/04/17 21:29:18 WARN util.NativeCodeLoader:无法为您的平台加载native-hadoop库...在适用的情况下使用builtin-java类   I0417 21:29:19.187747 205 sched.cpp:232]版本:1.2.0
      I0417 21:29:19.196535 188 sched.cpp:336]在master@127.0.0.1检测到新主站:5050
      I0417 21:29:19.197453 188 sched.cpp:352]没有提供凭据。试图在没有认证的情况下注册   I0417 21:29:19.201884 195 sched.cpp:759]框架注册为be89e739-be8d-430e-b1e9-3fe55fa18459-0001
      17/04/17 21:29:34 WARN scheduler.TaskSchedulerImpl:初始作业未接受任何资源;检查您的集群UI以确保工作人员已注册并具有足够的资源

    我在互联网上搜索了这个错误,但是我发现的每个页面都表明这是由于资源分配给Mesos代理程序而导致的常见错误。正如我所提到的,Mesos UI表明有足够的资源。如果您知道为什么我的Spark工作不接受Mesos的资源,或者您对我可以尝试的事情有任何建议,请回复。

    感谢您的帮助。

1 个答案:

答案 0 :(得分:2)

此错误现已解决。如果有人遇到类似的问题,我想在我的情况下发布它是由于没有在Mesos Master和Agent容器中设置HADOOP CLASSPATH。一旦设置,一切都按预期工作。