Spark多文件输出的两种形式

#所需环境版本
jdk=1.8
scala.version=2.11.0
spark.version=2.3.2
hadoop.verison=2.7.2
import org.apache.hadoop.io.{IntWritable, Text}
import org.apache.spark.{SparkConf, SparkContext}
import scala.collection.mutable.ArrayBuffer

object Main {
  def main(args: Array[String]): Unit = {
    val sparkConf = new SparkConf()
      .setAppName("test")
      .setMaster("local[2]")
      .set("spark.serializer", "org.apache.spark.serializer.KryoSerializer")
      .registerKryoClasses(Array(classOf[IntWritable], classOf[Text]))
    val sc = new SparkContext(sparkConf)
    process(sc)
    sc.stop()
  }

  def process(sc: SparkContext) = {
    val output = "output"
    val buffer = new ArrayBuffer[(String,String)]
    for(i <- 1 to 1000){
      val key = (Math.random() * 10).toInt.toString
      buffer +=((key,s"value_${key}"))
    }
sc.makeRDD(buffer).saveAsHadoopFile(output,classOf[String],classOf[String],classOf[RDDMultipleTextOutputFormat])
    val output1 = "output1"
    val buffer1 = new ArrayBuffer[(IntWritable,Text)]
    for(i <- 1 to 1000){
      val key = (Math.random() * 10).toInt
      buffer1 +=((new IntWritable(key),new Text(s"value_${key}")))
    }
 sc.makeRDD(buffer1).saveAsNewAPIHadoopFile(output1,classOf[IntWritable],classOf[Text],classOf[MultipleFileOutputFormat])
  }
}
import org.apache.hadoop.mapred.lib.MultipleTextOutputFormat
class RDDMultipleTextOutputFormat extends MultipleTextOutputFormat[String, String]{
  override def generateFileNameForKeyValue(key:String, value:String, name:String): String ={
    key
  }
}
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.RecordWriter;
import org.apache.hadoop.mapreduce.TaskAttemptContext;
import org.apache.hadoop.mapreduce.lib.output.FileOutputCommitter;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;

public class MultipleFileOutputFormat extends FileOutputFormat {
    private static final Map<Integer, String> FILENAMES = new HashMap<Integer, String>(){
        {
            put(0, "file0");
            put(1, "file1");
            put(2, "file2");
            put(3, "file3");
            put(4,"file4");
            put(5, "file5");
            put(6, "file6");
            put(7, "file7");
            put(8, "file8");
            put(9, "file9");
        }
    };
    protected static final String CODESET = "utf-8";
    protected static final byte[] newline;
    static {
        try {
            newline = "\n".getBytes(CODESET);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException("failed to get newline bytes, ", e);
        }
    }
    public Path getPathForWorkFile(TaskAttemptContext context, String prefix) throws IOException {
        FileOutputCommitter committer = (FileOutputCommitter) getOutputCommitter(context);
        return new Path(committer.getWorkPath(), prefix);
    }
    @Override
    public RecordWriter getRecordWriter(TaskAttemptContext job) throws IOException {

        final TaskAttemptContext myJob = job;
        final Configuration conf = job.getConfiguration();
        final FileSystem fs = FileSystem.get(conf);

        return new RecordWriter<IntWritable, Text>() {
            LineRecorderWriter[] outWriter = new LineRecorderWriter[FILENAMES.size()];
            @Override
            public void write(IntWritable key, Text value) throws IOException, InterruptedException {
                if(outWriter[key.get()] == null){
                    Path filePath = getPathForWorkFile(myJob, FILENAMES.get(key.get()));
                    outWriter[key.get()] = new LineRecorderWriter(fs, filePath);
                }
                outWriter[key.get()].write(key, value);
            }
            @Override
            public void close(TaskAttemptContext context) throws IOException, InterruptedException {
                for(LineRecorderWriter writer : outWriter){
                    if(writer != null)
                        writer.close(context);
                }
            }
        };
    }

    public static class LineRecorderWriter extends RecordWriter<IntWritable, Text> {
        FSDataOutputStream out;

        public LineRecorderWriter(FileSystem fs, Path path) throws IOException {
            out = fs.create(path);
        }
        @Override
        public void write(IntWritable key, Text value) throws IOException, InterruptedException {
            out.write(value.toString().getBytes(CODESET));
            out.write(newline);
        }
        @Override
        public void close(TaskAttemptContext context) throws IOException, InterruptedException {
            out.close();
        }
    }
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spark on YARN有两种处理模式,分别是Client模式和Cluster模式。 1. Client模式: 在Client模式下,Spark应用程序的驱动程序运行在提交应用程序的客户端机器上。客户端向YARN ResourceManager提交应用程序,并且将应用程序的JAR包和依赖文件分发到集群的NodeManager上。然后,驱动程序启动一个SparkContext来与集群通信,并在集群上分配和管理任务。这种模式下,驱动程序负责监控应用程序的执行过程和收集结果。 优点: - 可以方便地在客户端机器上查看应用程序的日志和输出结果。 - 对于开发和调试应用程序来说比较方便,可以快速获取反馈。 缺点: - 如果客户端机器断开连接或关闭,驱动程序也会停止运行。 - 客户端机器的资源会被使用来运行驱动程序,可能会影响到其他任务的执行。 2. Cluster模式: 在Cluster模式下,Spark应用程序的驱动程序运行在YARN集群中的某个节点上。客户端只需要向YARN ResourceManager提交应用程序,并将应用程序的JAR包和依赖文件分发到集群的NodeManager上。然后,驱动程序在集群中的某个节点上启动一个SparkContext来与集群通信,并在集群上分配和管理任务。这种模式下,驱动程序不受客户端机器断开连接的影响。 优点: - 驱动程序运行在集群中,不会受到客户端机器的限制。 - 可以更好地利用集群资源,提高任务的并行度和整体执行性能。 缺点: - 对于开发和调试应用程序来说相对麻烦,需要通过查看集群日志来获取反馈。 - 不方便查看应用程序的日志和输出结果,需要通过其他方式获取。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值