一、基础原理

我们知道 spark 是用 scala 开发的,而 scala 又是基于 Java 语言开发的,那么 spark 的底层架构就是 Java 语言开发的。如果要使用 python 来进行与 java 之间通信转换,那必然需要通过 JVM 来转换。我们先看原理构建图:

从图中我们发现在 python 环境中我们编写的程序将以 SparkContext 的形式存在,Pythpn 通过于 Py4j 建立 Socket 通信,通过 Py4j 实现在 Python 中调用 Java 的方法,将我们编写成 python 的 SpakrContext 对象通过 Py4j,最终在 JVM Driver 中实例化为 Scala 的 SparkContext。

那么我们再从 Spark 集群运行机制来看:

主节点运行 Spark 任务是通过 SparkContext 传递任务分发到各个从节点,标橙色的方框就为 JVM。通过 JVM 中间语言与其他从节点的 JVM 进行通信。之后 Executor 通信结束之后下发 Task 进行执行。

此时我们再把 python 在每个主从节点展示出来:

这样就一目了然了:主节点的 Python 通过 Py4j 通信传递 SparkContext,最后在 JVM Driver 上面生成 SparkContxt。主节点 JVM Driver 与其他从节点的 JVM Executor 通信传输 SparkContext,JVM Executor 通过分解 SparkContext 为许多 Task,给 pyspark.daemon 调用 pyspark.work 从 socket 中读取要执行的 python 函数和数据,开始真正的数据处理逻辑。数据处理完成之后将处理结果写回 socket,jvm 中通过 PythonRDD 的 read 方法读取,并返回结果。最终 executor 将 PythonRDD 的执行结果上报到 drive 上,返回给用户。

完整了解 PySpark 在集群上运行的原理之后,再看上图就很容易理解了。

Executor 端运行的 Task 逻辑是由 Driver 发过来的,那是序列化后的字节码,虽然里面可能包含有用户定义的 Python 函数或 Lambda 表达式,Py4j 并不能实现在 Java 里调用 Python 的方法,为了能在 Executor 端运行用户定义的 Python 函数或 Lambda 表达式,则需要为每个 Task 单独启一个 Python 进程,通过 socket 通信方式将 Python 函数或 Lambda 表达式发给 Python 进程执行。

二、程序运行原理

1.主节点 JVM 运行过程

当我们提交 pyspark 的任务时,会先上传 python 脚本以及依赖并申请资源,申请到资源后会通过 PythonRunner 拉起 JVM。

首先 PythonRunner 开启 Pyj4 GatewayServer,通过 Java Process 方式运行用户上传的 Python 脚本。

​ 用户 Python 脚本起来后,首先会实例化 Python 版的 SparkContext 对象,并且实例化 Py4j GatewayClient,连接 JVM 中的 Py4j GatewayServer,后续在 Python 中调用 Java 的方法都是借助这个 Py4j Gateway。然后通过 Py4j Gateway 在 JVM 中实例化 SparkContext 对象。

​ 过上面两步后,SparkContext 对象初始化完毕,与其他从节点通信。开始申请 Executor 资源,同时开始调度任务。用户 Python 脚本中定义的一系列处理逻辑最终遇到 action 方法后会触发 Job 的提交,提交 Job 时是直接通过 Py4j 调用 Java 的 PythonRDD.runJob 方法完成,映射到 JVM 中,会转给 sparkContext.runJob 方法,Job 运行完成后,JVM 中会开启一个本地 Socket 等待 Python 进程拉取,对应地,Python 进程在调用 PythonRDD.runJob 后就会通过 Socket 去拉取结果。

2.从节点 JVM 运行过程

当 Driver 得到 Executor 资源时,通过 CoarseGrainedExecutorBackend(其中有 main 方法)通信 JVM,启动一些必要的服务后等待 Driver 的 Task 下发,在还没有 Task 下发过来时,Executor 端是没有 Python 进程的。当收到 Driver 下发过来的 Task 后,Executor 的内部运行过程如下图所示。

Executor 端收到 Task 后,会通过 launchTask 运行 Task,最后会调用到 PythonRDD 的 compute 方法,来处理一个分区的数据,PythonRDD 的 compute 方法的计算流程大致分三步走:

  • 如果不存在 pyspark.deamon 后台 Python 进程,那么通过 Java Process 的方式启动 pyspark.deamon 后台进程,注意每个 Executor 上只会有一个 pyspark.deamon 后台进程,否则,直接通过 Socket 连接 pyspark.deamon,请求开启一个 pyspark.worker 进程运行用户定义的

  • Python 函数或 Lambda 表达式。pyspark.deamon 是一个典型的多进程服务器,来一个 Socket 请求,fork 一个 pyspark.worker 进程处理,一个 Executor 上同时运行多少个 Task,就会有多少个对应的 pyspark.worker 进程。

  • 紧接着会单独开一个线程,给 pyspark.worker 进程输入数据,pyspark.worker 则会调用用户定义的 Python 函数或 Lambda 表达式处理计算。在一边输入数据的过程中,另一边则通过 Socket 去拉取 pyspark.worker 的计算结果。

把前面运行时架构图中 Executor 部分单独拉出来,如下图所示,橙色部分为 JVM 进程,白色部分为 Python 进程,每个 Executor 上有一个公共的 pyspark.deamon 进程,负责接收 Task 请求,并 fork pyspark.worker 进程单独处理每个 Task,实际数据处理过程中,pyspark.worker 进程和 JVM Task 会较频繁地进行本地 Socket 数据通信。

三、总结

总体而言,PySpark 是借助 Py4j 实现 Python 调用 Java,来驱动 Spark 应用程序,本质上主要还是 JVM runtime,Java 到 Python 的结果返回是通过本地 Socket 完成。虽然这种架构保证了 Spark 核心代码的独立性,但是在大数据场景下,JVM 和 Python 进程间频繁的数据通信导致其性能损耗较多,恶劣时还可能会直接卡死,所以建议对于大规模机器学习或者 Streaming 应用场景还是慎用 PySpark,尽量使用原生的 Scala/Java 编写应用程序,对于中小规模数据量下的简单离线任务,可以使用 PySpark 快速部署提交

PySpark 数据分析基础:PySpark 原理详解相关推荐

  1. Redis基础及原理详解

    Redis基础及原理详解 前言:以下是最近学习redis的一些笔记总结,文中如有不当的地方欢迎批评指正,重在记录与学习,笔芯~~ Nosql概述 演进历史 单机mysql Memcached(缓存)+ ...

  2. 机器学习,深度学习基础算法原理详解(图的搜索、交叉验证、PAC框架、VC-维(持续更新))

    机器学习,深度学习基础算法原理详解(图的搜索.交叉验证.PAC框架.VC-维.支持向量机.核方法(持续更新)) 机器学习,深度学习基础算法原理详解(数据结构部分(持续更新)) 文章目录 1. 图的搜索 ...

  3. 小白入门STM32(2)---控制SG90舵机---基础工作原理详解

    文章目录 序言 一.基础理论 1.1 舵机控制原理--PWM 习题 1.2 定时器 1.2.1 基础定时器 时钟装置 循环计数器 1.2.2 比较定时器 习题 二.实战上手 2.1 设置定时器和单片机 ...

  4. PySpark数据分析基础:PySpark基础功能及DataFrame操作基础语法详解

    目录 前言 一.PySpark基础功能 1.Spark SQL 和DataFrame 2.Pandas API on Spark 3.Streaming 4.MLBase/MLlib 5.Spark ...

  5. 【Java基础】HashMap原理详解

    [Java基础]HashMap原理详解 HashMap的实现 1. 数组 2.线性链表 3.红黑树 3.1概述 3.2性质 4.HashMap扩容死锁 5. BATJ一线大厂技术栈 HashMap的实 ...

  6. Jsp入门1Jsp入门基础简介与工作原理详解

    一)JSP基础简介 1.什么是JSP? JSP全称是Java Server Pages,它和servle技术一样,都是SUN公司定义的一种用于开发动态web资源的技术. JSP这门技术的最大的特点在于 ...

  7. SVM分类器原理详解

    SVM分类器原理详解 标签: svm文本分类java 2015-08-21 11:51 2399人阅读 评论(0) 收藏 举报  分类: 数据挖掘 文本处理(16)  机器学习 分类算法(10)  目 ...

  8. [Python从零到壹] 九.网络爬虫之Selenium基础技术万字详解(定位元素、常用方法、键盘鼠标操作)

    欢迎大家来到"Python从零到壹",在这里我将分享约200篇Python系列文章,带大家一起去学习和玩耍,看看Python这个有趣的世界.所有文章都将结合案例.代码和作者的经验讲 ...

  9. 大数据是什么和大数据技术十大核心原理详解

     一.数据核心原理   从"流程"核心转变为"数据"核心   大数据时代,计算模式也发生了转变,从"流程"核心转变为"数据&quo ...

  10. 大数据技术十大核心原理详解

    一.数据核心原理--从"流程"核心转变为"数据"核心 大数据时代,计算模式也发生了转变,从"流程"核心转变为"数据"核心 ...

最新文章

  1. 聊天软件系统测试用例,QQ聊天框测试用例设计
  2. Cassandra读写性能测试
  3. 再来一次的C语言贪吃蛇小游戏(三)
  4. java 事件驱动 netty_Netty2-事件驱动的NIO框架(使用范例)
  5. MGTemplateEngine 模版发动机简单使用
  6. C# 截取图片的方法
  7. 你应该知道这些有意思的代码
  8. linux date 天之前,linux date命令前后几天的推导
  9. jquery颜色选择器
  10. python pip的配置
  11. 【python】字典与集合的练习题
  12. MediaInfo源代码分析 4:Inform()函数
  13. ValidatorUtil验证工具类判断手机、ip地址、邮箱,身份证等
  14. Apache的网页与安全优化
  15. 哲学家就餐问题与解决方案
  16. 实现游戏的读档和存档
  17. 每日一题:1.function Person(firstName, lastName) { this.firstName = firstName; this.lastName = lastNa
  18. 如何让自己变得更加成熟
  19. 5个人站队,每个人不在原位置有多少种站法
  20. oracle 通信通道异常,(oracle)ORA-03113: 通信通道的文件结尾错误处理

热门文章

  1. oracle getpy,应用实例 - Foxtable 中文帮助文档
  2. JAVA正则表达式匹配多个空格
  3. Telerik DevCraft Ultimate R1 2023
  4. 怎么将流程图转化为N-S图(盒图)?
  5. FPGA实现IRIG-B(DC)码编码和解码的设计
  6. 前端优化常用技术心得
  7. 【学术相关】陈天奇、王威廉等人推荐:ACL最佳论文奖得主给新入行研究者的一点建议...
  8. 2022年深圳市电子商务创新发展扶持计划电商直播基地扶持项目申报指南
  9. 清理oracle系统表空间,Oracle表空间清理
  10. win10中的wsappx进程(开机时,占用过多资源)