Amazon s3 Spark:对大量文件使用Spark进行数据处理时表示SocketException:读取超时

Amazon s3 Spark:对大量文件使用Spark进行数据处理时表示SocketException:读取超时,amazon-s3,mapreduce,apache-spark,spark-streaming,pyspark,Amazon S3,Mapreduce,Apache Spark,Spark Streaming,Pyspark,我在两台具有这些配置的机器上以独立模式运行Spark 500gb内存,4核,7.5 RAM 250gb内存,8核,15 RAM 我在8core机器上创建了一个主设备和一个从设备,给工人7个内核。我已经在4核心机器上创建了另一个具有3个工作核心的从机。用户界面显示8芯和4芯的可用RAM分别为13.7克和6.5克 现在,我必须在15天的时间内处理用户评分的总和。我正在尝试使用Pyspark来实现这一点 这些数据存储在s3存储桶中按天目录的小时文件中,每个文件必须在100MB左右 s3://some_

我在两台具有这些配置的机器上以独立模式运行Spark

  • 500gb内存,4核,7.5 RAM
  • 250gb内存,8核,15 RAM
  • 我在8core机器上创建了一个主设备和一个从设备,给工人7个内核。我已经在4核心机器上创建了另一个具有3个工作核心的从机。用户界面显示8芯和4芯的可用RAM分别为13.7克和6.5克

    现在,我必须在15天的时间内处理用户评分的总和。我正在尝试使用Pyspark来实现这一点 这些数据存储在s3存储桶中按天目录的小时文件中,每个文件必须在100MB左右

    s3://some_bucket/2015-04/2015-04-09/data_files_hour1

    我正在读这样的文件

    a = sc.textFile(files, 15).coalesce(7*sc.defaultParallelism) #to restrict partitions
    
    final_scores = b.mapPartitions(get_tags)
    
    其中,文件是以下格式的字符串“s3://some_bucket/2015-04/2015-04-09/*,s3://some_bucket/2015-04/2015-04-09/*”

    然后我做了一系列的映射和过滤器,并保存结果

    a.persist(StorageLevel.MEMORY_ONLY_SER)
    
    然后我需要做一个reduceByKey来得到几天内的总分

    b = a.reduceByKey(lambda x, y: x+y).map(aggregate)
    b.persist(StorageLevel.MEMORY_ONLY_SER)
    
    然后,我需要对用户已评级的项目的实际术语进行redis调用,因此我像这样调用mapPartitions

    a = sc.textFile(files, 15).coalesce(7*sc.defaultParallelism) #to restrict partitions
    
    final_scores = b.mapPartitions(get_tags)
    
    get_tags函数在每次调用时创建一个redis连接,并调用redis并生成一个(用户、项目、速率)元组 (redis散列存储在4core中)

    我已经调整了SparkConf的设置

    conf = (SparkConf().setAppName(APP_NAME).setMaster(master)
            .set("spark.executor.memory", "5g")
            .set("spark.akka.timeout", "10000")
            .set("spark.akka.frameSize", "1000")
            .set("spark.task.cpus", "5")
            .set("spark.cores.max", "10")
            .set("spark.serializer",      "org.apache.spark.serializer.KryoSerializer")
            .set("spark.kryoserializer.buffer.max.mb", "10")
            .set("spark.shuffle.consolidateFiles", "True")
            .set("spark.files.fetchTimeout", "500")
            .set("spark.task.maxFailures", "5"))
    
    我在客户机模式下使用2g的驱动程序内存运行该作业,因为这里似乎不支持群集模式。 上述过程需要2天(约2.5小时)的数据,并在14天内完全放弃

    这里需要改进什么

  • 在RAM和内核方面,这个基础设施是否不足(这是离线的,可能需要几个小时,但必须在5个小时左右完成)
  • 我应该增加/减少分区的数量吗
  • Redis可能会减慢系统的速度,但按键的数量太多,无法一次性调用
  • 我不确定这项任务在哪里失败了,在读取文件方面还是在减少
  • 如果Scala中有更好的Spark API,我是否应该不使用Python,这是否也有助于提高效率
  • 这是异常跟踪

    Lost task 4.1 in stage 0.0 (TID 11, <node>): java.net.SocketTimeoutException: Read timed out
        at java.net.SocketInputStream.socketRead0(Native Method)
        at java.net.SocketInputStream.read(SocketInputStream.java:152)
        at java.net.SocketInputStream.read(SocketInputStream.java:122)
        at sun.security.ssl.InputRecord.readFully(InputRecord.java:442)
        at sun.security.ssl.InputRecord.readV3Record(InputRecord.java:554)
        at sun.security.ssl.InputRecord.read(InputRecord.java:509)
        at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:934)
        at sun.security.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:891)
        at sun.security.ssl.AppInputStream.read(AppInputStream.java:102)
        at org.apache.http.impl.io.AbstractSessionInputBuffer.read(AbstractSessionInputBuffer.java:198)
        at org.apache.http.impl.io.ContentLengthInputStream.read(ContentLengthInputStream.java:178)
        at org.apache.http.impl.io.ContentLengthInputStream.read(ContentLengthInputStream.java:200)
        at org.apache.http.impl.io.ContentLengthInputStream.close(ContentLengthInputStream.java:103)
        at org.apache.http.conn.BasicManagedEntity.streamClosed(BasicManagedEntity.java:164)
        at org.apache.http.conn.EofSensorInputStream.checkClose(EofSensorInputStream.java:227)
        at org.apache.http.conn.EofSensorInputStream.close(EofSensorInputStream.java:174)
        at org.apache.http.util.EntityUtils.consume(EntityUtils.java:88)
        at org.jets3t.service.impl.rest.httpclient.HttpMethodReleaseInputStream.releaseConnection(HttpMethodReleaseInputStream.java:102)
        at org.jets3t.service.impl.rest.httpclient.HttpMethodReleaseInputStream.close(HttpMethodReleaseInputStream.java:194)
        at org.apache.hadoop.fs.s3native.NativeS3FileSystem$NativeS3FsInputStream.seek(NativeS3FileSystem.java:152)
        at org.apache.hadoop.fs.BufferedFSInputStream.seek(BufferedFSInputStream.java:89)
        at org.apache.hadoop.fs.FSDataInputStream.seek(FSDataInputStream.java:63)
        at org.apache.hadoop.mapred.LineRecordReader.<init>(LineRecordReader.java:126)
        at org.apache.hadoop.mapred.TextInputFormat.getRecordReader(TextInputFormat.java:67)
        at org.apache.spark.rdd.HadoopRDD$$anon$1.<init>(HadoopRDD.scala:236)
        at org.apache.spark.rdd.HadoopRDD.compute(HadoopRDD.scala:212)
        at org.apache.spark.rdd.HadoopRDD.compute(HadoopRDD.scala:101)
        at org.apache.spark.rdd.RDD.computeOrReadCheckpoint(RDD.scala:277)
        at org.apache.spark.rdd.RDD.iterator(RDD.scala:244)
        at org.apache.spark.rdd.MapPartitionsRDD.compute(MapPartitionsRDD.scala:35)
        at org.apache.spark.rdd.RDD.computeOrReadCheckpoint(RDD.scala:277)
        at org.apache.spark.rdd.RDD.iterator(RDD.scala:244)
        at org.apache.spark.rdd.CoalescedRDD$$anonfun$compute$1.apply(CoalescedRDD.scala:93)
        at org.apache.spark.rdd.CoalescedRDD$$anonfun$compute$1.apply(CoalescedRDD.scala:92)
        at scala.collection.Iterator$$anon$13.hasNext(Iterator.scala:371)
        at scala.collection.Iterator$class.foreach(Iterator.scala:727)
        at scala.collection.AbstractIterator.foreach(Iterator.scala:1157)
        at org.apache.spark.api.python.PythonRDD$.writeIteratorToStream(PythonRDD.scala:405)
        at org.apache.spark.api.python.PythonRDD$WriterThread$$anonfun$run$1.apply(PythonRDD.scala:243)
        at org.apache.spark.util.Utils$.logUncaughtExceptions(Utils.scala:1617)
        at org.apache.spark.api.python.PythonRDD$WriterThread.run(PythonRDD.scala:205)
    
    “获取文件”功能如下所示:

    def get_files():
     paths = get_path_from_dates(DAYS)
     base_path = 's3n://acc_key:sec_key@bucket/'
     files = list()
     for path in paths:
        fle = base_path+path+'/file_format.*'
        files.append(fle)
     return ','.join(files)
    
    从日期(天)获取路径是

    def get_path_from_dates(last):
    天数=列表()
    t=0
    
    虽然t是一个小优化,但我创建了两个独立的任务,一个从s3读取并获得加法和,另一个从redis读取转换。第一个任务有大量的分区,因为大约有2300个文件要读取。第二个分区的数量要少得多,以防止redis连接延迟,并且只有一个文件要读取,它位于EC2集群本身。这只是部分内容,仍在寻找改进的建议…

    我在一个类似的用例中:在具有300000多个分区的RDD上执行
    合并。区别在于我使用的是s3a(
    S3AFileSystem.waitAysncCopy
    中的SocketTimeoutException
    )。最后,通过设置更大的
    fs.s3a.connection.timeout
    (Hadoop的
    core site.xml
    )解决了这个问题。希望你能找到线索

    这个问题有很多细节。我建议你把这个问题分成几个单独的问题。例如,您可以选择一个问题来帮助您解决异常,另一个问题来帮助提高性能。谢谢,我同意,但我自己无法深入了解原因,因此无法找到解决方案。因此,我提供了整个背景,以便任何对这个问题感兴趣的人都能得到整个背景,并据此作出回答。这可能看起来像是一个性能调优代码检查,但我非常需要:(我很感激你的情况。我会尽我所能帮助你。关于性能问题,从一个单一的输入分割开始(我假设是一个单一的100MB文件)。你能在你的机器上本地调优你的作业吗(例如,删除AWS组件)?你的代码效率高吗?通常这是效率最高的地方。你能分享更多你的代码吗?@Myles Baker,PFA Job先生的一些部分为了优化,我能广播redis连接吗?