Hadoop MR替换为Spark步骤详解

将Hadoop的计算引擎从MapReduce (MR) 替换为Spark是一个非常常见且合理的架构演进。Spark以其卓越的内存计算、DAG执行引擎和友好的API,在大多数场景下性能远超MR。

以下是详细的替换步骤、考量因素以及最佳实践。

核心思想:Spark on YARN

最关键的一点是:替换MR并不意味着要卸载或移除Hadoop。恰恰相反,Spark与Hadoop生态系统结合得非常紧密,最佳部署模式是 Spark on YARN

  • Hadoop YARN:作为统一的资源管理和调度平台,同时为MR、Spark以及其他计算框架(如Tez, Flink)提供服务。
  • Hadoop HDFS:作为稳定的数据存储层
  • 计算引擎:从MapReduce 替换为 Spark

所以,你的Hadoop集群(YARN和HDFS)仍然是至关重要的基础设施,你只是换了一个更高效的计算引擎来在上面运行。


替换步骤详解

第一步:环境准备与Spark部署
  1. 安装Spark

    • Apache Spark官网下载与你的Hadoop版本(如Hadoop 3.x)预编译的版本。
    • 将Spark解压到集群所有节点的相同目录下,例如 /opt/module/spark
  2. 配置Spark(关键步骤)
    进入 $SPARK_HOME/conf 目录,进行以下配置:

    • spark-env.sh (复制 spark-env.sh.template)
      # 配置JAVA_HOME
      export JAVA_HOME=/path/to/your/jdk
      # 配置Hadoop配置目录,让Spark能找到YARN和HDFS的配置
      export HADOOP_CONF_DIR=${HADOOP_HOME}/etc/hadoop
      export YARN_CONF_DIR=${HADOOP_HOME}/etc/hadoop
      # (可选) 指定Spark History Server,便于查看历史任务日志
      export SPARK_HISTORY_OPTS="-Dspark.history.fs.logDirectory=hdfs://mycluster/spark-history"
      
    • spark-defaults.conf (复制 spark-defaults.conf.template)
      # 指定Spark任务运行在YARN上
      spark.master    yarn
      # (可选) 设置事件日志目录,用于History Server
      spark.eventLog.enabled true
      spark.eventLog.dir hdfs://mycluster/spark-history
      # (可选) 配置一些默认资源,如Executor内存、核心数
      spark.executor.memory    4g
      spark.executor.cores     2
      
    • slaves (复制 slaves.template): 这个文件在Standalone模式下有用,在YARN模式下不需要配置,因为由YARN管理节点。
  3. 分发Spark
    使用 rsyncscp 将配置好的Spark目录分发到所有工作节点。

  4. 启动Spark History Server (可选)
    如果需要查看已完成任务的历史日志,可以启动它。

    $SPARK_HOME/sbin/start-history-server.sh
    

第二步:任务迁移 - 重写代码

这是最主要的工作量所在。你需要将原有的MR任务用Spark的API重写。

组件MapReduce (Java)Spark (Scala/Python/Java)说明
Driver无直接对应SparkSession/SparkContextSpark任务的入口点,负责协调和调度。
MapperMapper Classmap, flatMap, filter 等转换操作对初始数据进行处理,一对一的转换。
ReducerReducer ClassreduceByKey, groupByKey, agg 等聚合操作对Shuffle后的数据进行聚合。
Job一个MR Job一个Spark Application
Shuffle显式且昂贵隐式(由算子触发)但优化得更好Spark的Shuffle管理更高效。

迁移示例:WordCount

  • MapReduce (Java):

    // 代码较长,需要定义Mapper, Reducer, Job类,设置各种参数...
    public class WordCountMapper extends Mapper<...> {
        protected void map(...) {
            // split line and output (word, 1)
        }
    }
    public class WordCountReducer extends Reducer<...> {
        protected void reduce(...) {
            // sum values and output (word, count)
        }
    }
    // ... main 方法中组装的代码很长
    
  • Spark (Scala):

    val sc = SparkSession.builder().appName("WordCount").getOrCreate().sparkContext
    val textFile = sc.textFile("hdfs://.../input.txt")
    val wordCounts = textFile.flatMap(line => line.split(" "))
                             .map(word => (word, 1))
                             .reduceByKey(_ + _)
    wordCounts.saveAsTextFile("hdfs://.../output")
    sc.stop()
    

    Spark (Python):

    from pyspark.sql import SparkSession
    spark = SparkSession.builder.appName("WordCount").getOrCreate()
    sc = spark.sparkContext
    text_file = sc.textFile("hdfs://.../input.txt")
    word_counts = text_file.flatMap(lambda line: line.split(" ")) \
                           .map(lambda word: (word, 1)) \
                           .reduceByKey(lambda a, b: a + b)
    word_counts.saveAsTextFile("hdfs://.../output")
    sc.stop()
    

可以看到,Spark代码简洁明了,表达力更强。


第三步:提交与运行

迁移完成后,使用 spark-submit 脚本来提交任务到YARN集群。

$SPARK_HOME/bin/spark-submit \
  --class org.apache.spark.examples.SparkPi \ # 你的主类
  --master yarn \
  --deploy-mode cluster \    # 或者 client,通常用cluster
  --driver-memory 2g \
  --executor-memory 4g \
  --executor-cores 2 \
  --num-executors 10 \
  /path/to/your/spark-job.jar \
  [application-arguments]

关键参数:

  • --master yarn: 指定运行在YARN上。
  • --deploy-mode cluster/client: cluster模式将Driver端运行在YARN的ApplicationMaster中,更适合生产环境;client模式Driver运行在提交任务的机器上,常用于调试。
  • 其他资源参数(--executor-memory等)会传递给YARN,YARN会据此分配Container。

重要考量因素与最佳实践

  1. 资源分配

    • Spark on YARN时,要合理设置Executor的内存和CPU核心数,避免与集群中其他服务(如HBase)或其它YARN任务争抢资源,导致OOM(内存溢出)或效率低下。
    • 需要在YARN的 capacity-scheduler.xml 中合理配置队列资源。
  2. 数据本地性

    • Spark和MR一样,会优先将任务调度到存有数据的节点上,以减少网络传输。确保Spark节点也是HDFS的DataNode。
  3. 依赖管理

    • 如果你的Spark作业依赖第三方JAR包,可以使用 spark-submit--jars 参数上传,或者预先放到集群所有节点的类路径下。
  4. 监控与调试

    • YARN Web UI (http://<resource-manager-host>:8088): 查看所有YARN应用的状态、日志和资源使用情况。
    • Spark Web UI: 每个Spark应用都有自己的Web UI(URL在YARN UI中会提供),可以查看详细的DAG图、Stage、Task执行情况、Shuffle数据量等,是性能调优的利器。
    • Spark History Server: 查看已完成应用的历史信息。
  5. 性能调优

    • 序列化: 使用Kryo序列化(spark.serializer org.apache.spark.serializer.KryoSerializer)来减少序列化大小和时间。
    • 内存管理: 调整 spark.executor.memoryOverhead 以及堆内/堆外内存比例,防止Shuffle或缓存时溢出。
    • Shuffle调优: 调整 spark.sql.shuffle.partitions 来控制Shuffle后的分区数,避免过多或过少的分区导致性能问题。

总结

将Hadoop的MR替换为Spark是一个“低风险、高收益”的操作,核心流程是:

  1. 部署Spark:配置为 Spark on YARN 模式。
  2. 代码重写:用Spark的API(RDD/DataFrame/Dataset)重写原有的MR任务。这是主要工作量。
  3. 提交运行:使用 spark-submit 将任务提交到YARN。
  4. 监控调优:利用Web UI和日志监控任务运行状态,并进行性能调优。

通过这种方式,你既保留了Hadoop HDFS和YARN的稳定性和可靠性,又享受到了Spark带来的高性能和开发效率,完美实现了计算引擎的升级。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值