【发布时间】:2020-04-18 16:15:20
【问题描述】:
我有大约 12K 个二进制文件,每个文件大小为 100mb,并且包含多个具有 变量 长度的压缩记录。我试图找到最有效的方法来读取它们,解压缩然后以镶木地板格式写回。我拥有的集群是 6 个节点,每个节点有 4 个核心。
此时使用下面的伪代码,读取所有文件大约需要 8 小时,写回 parquet 非常慢。
def reader(file_name):
keyMsgList = []
with open(file_name, "rb") as f:
while True:
header = f.read(12)
if not header:
break
keyBytes = header[0:8]
msgLenBytes = header[8:12]
# conver keyBytes & msgLenBytes to int
message = f.read(msgLen)
keyMsgList.append((key, decode(message)))
return keyMsgList
files = os.listdir("/path/to/binary/files")
rddFiles = sc.parallelize(files, 6000)
df = spark.createDataFrame(rddFiles.flatMap(reader), schema)
df.repartition(6000).write.mode("append").partitionBy("key").parquet("/directory")
在这里选择 6000 sc.parallelize(files, 6000) 的原因是创建每个大小为 200 MB 的分区,即 (12k files * 100mb size) / 200MB。作为需要逐字节读取每个文件内容的顺序性质,不确定是否可以进一步优化读取?
同样,写回parquet时,repartition(6000)中的数字是为了保证数据分布均匀,所有executor可以并行写。但是,结果证明这是一个非常缓慢的操作。
一种解决方案是增加执行器的数量,这会提高读取性能但不确定是否会提高写入?
在此处寻找有关如何提高性能的任何建议?
【问题讨论】:
标签: apache-spark pyspark