[英]Python read .json files from GCS into pandas DF in parallel
TL;DR: asyncio
、 multi-processing
、 threading
和some other solution
,以并行化从 GCS 读取文件的循环,然后将此数据一起附加到 pandas dataframe,然后写入 BigQuery...
I'd like to make parallel a python function that reads hundreds of thousands of small .json files from a GCS directory, then converts those .jsons into pandas dataframes, and then writes the pandas dataframes to a BigQuery table.
这是 function 的非并行版本:
import gcsfs
import pandas as pd
from my.helpers import get_gcs_file_list
def load_gcs_to_bq(gcs_directory, bq_table):
# my own function to get list of filenames from GCS directory
files = get_gcs_file_list(directory=gcs_directory) #
# Create new table
output_df = pd.DataFrame()
fs = gcsfs.GCSFileSystem() # Google Cloud Storage (GCS) File System (FS)
counter = 0
for file in files:
# read files from GCS
with fs.open(file, 'r') as f:
gcs_data = json.loads(f.read())
data = [gcs_data] if isinstance(gcs_data, dict) else gcs_data
this_df = pd.DataFrame(data)
output_df = output_df.append(this_df)
# Write to BigQuery for every 5K rows of data
counter += 1
if (counter % 5000 == 0):
pd.DataFrame.to_gbq(output_df, bq_table, project_id=my_id, if_exists='append')
output_df = pd.DataFrame() # and reset the dataframe
# Write remaining rows to BigQuery
pd.DataFrame.to_gbq(output_df, bq_table, project_id=my_id, if_exists='append')
这个 function 很简单:
['gcs_dir/file1.json', 'gcs_dir/file2.json', ...]
,GCS 中的文件名列表我必须在几个 GCS 目录上运行这个 function,每个目录都有 ~500K 文件。 由于读取/写入这么多小文件的瓶颈,单个目录的这个过程大约需要 24 小时......如果我可以让它更加并行以加快速度,那就太好了,因为这似乎是一项任务适合并行化。
编辑:下面的解决方案很有帮助,但我对在 python 脚本中并行运行特别感兴趣。 Pandas 正在处理一些数据清理,使用bq load
会抛出错误。 有asyncio和这个gcloud-aio-storage似乎都可能对这项任务有用,可能是比线程或多处理更好的选择......
与其向 python 代码添加并行处理,不如考虑并行多次调用 python 程序。 这是一个技巧,它更容易适用于在命令行上获取文件列表的程序。 因此,为了这篇文章,让我们考虑更改程序中的一行:
您的线路:
# my own function to get list of filenames from GCS directory
files = get_gcs_file_list(directory=gcs_directory) #
新队:
files = sys.argv[1:] # ok, import sys, too
现在,您可以通过这种方式调用您的程序:
PROCESSES=100
get_gcs_file_list.py | xargs -P $PROCESSES your_program
xargs
现在将通过get_gcs_file_list.py
获取文件名 output 并并行调用your_program
多达 100 次,在每行上安装尽可能多的文件名。 我相信文件名的数量仅限于 shell 允许的最大命令大小。 如果 100 个进程不足以处理所有文件,则 xargs 将再次调用your_program
(一次又一次),直到它从标准输入读取的所有文件名都被处理。 xargs
确保同时运行的your_program
调用不超过 100 个。 您可以根据主机可用的资源来改变进程数。
而不是这样做,您可以直接使用bq
命令。
bq 命令行工具是基于 Python 的 BigQuery 命令行工具。
当您使用此命令时,加载发生在 google 的网络中,这比我们创建 dataframe 并加载到表中要快得多。
bq load \
--autodetect \
--source_format=NEWLINE_DELIMITED_JSON \
mydataset.mytable \
gs://mybucket/my_json_folder/*.json
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.