1

以下の疑似コードが、PySpark(Azure Databricks) から Azure Data Lake に保存されている日付範囲内の複数の寄木細工のファイルを読み取る効率的な方法であるかどうかを知りたいです。注: 寄木細工のファイルは日付で分割されていません。

私は uat/EntityName/2019/01/01/EntityName_2019_01_01_HHMMSS.parquet 規則を使用して、ADL にデータを格納するために、Nathan Marz 著の書籍 Big Data で提案されているように、少し変更を加えました (year=2019 の代わりに 2019 を使用)。

* ワイルドカードを使用してすべてのデータを読み取ります。

df = spark.read.parquet(uat/EntityName/*/*/*/*)

文字列操作を使用して EntityName_2019_01_01_HHMMSS.parquet からタイムスタンプを抽出し、TimestampType() に変換する列 FileTimestamp を追加します。

df.withColumn(add timestamp column)

フィルターを使用して関連データを取得します。

start_date = '2018-12-15 00:00:00'
end_date = '2019-02-15 00:00:00'
df.filter(df.FileTimestamp >= start_date).filter(df.FileTimestamp < end_date)

基本的に、私は PySpark を使用して、U-SQL で利用できるきちんとした構文をシミュレートしています。

@rs = 
  EXTRACT 
      user    string,
      id      string,
      __date  DateTime
  FROM 
    "/input/data-{__date:yyyy}-{__date:MM}-{__date:dd}.csv"
  USING Extractors.Csv();

@rs = 
  SELECT * 
  FROM @rs
  WHERE 
    date >= System.DateTime.Parse("2016/1/1") AND
    date < System.DateTime.Parse("2016/2/1");
4

1 に答える 1

1

データを分割する正しい方法は、データで year=2019、month=01 などの形式を使用することです。

次のようなフィルタを使用してこのデータをクエリすると、次のようになります。

df.filter(df.year >= myYear)

次に、Spark は関連するフォルダーのみを読み取ります。

フィルタリング列名がフォルダー名に正確に含まれていることが非常に重要です。Spark を使用してパーティション分割されたデータ (年、月、日など) を書き込む場合、パーティション分割列は parquet ファイルに書き込まれないことに注意してください。代わりに、パスから推測されます。ただし、データフレームが書き込み時にそれらを必要とすることを意味します。また、パーティション化されたソースから読み取るときに、列として返されます。

フォルダー構造を変更できない場合は、正規表現または Glob を使用して Spark が読み取るフォルダーをいつでも手動で減らすことができます。しかし明らかに、これはより手作業で複雑です。

更新: さらなる例複数のファイルを S3 から Spark データフレームに読み込み、存在しないファイルを渡すことはできますか?

また、Bill Chambers による「Spark - The Definitive Guide: Big Data Processing Made Simple」から:

パーティショニングは、書き込み時にどのデータを (どこに) 格納するかを制御できるツールです。パーティション分割されたディレクトリ (またはテーブル) にファイルを書き込むときは、基本的に列をフォルダーとしてエンコードします。これにより、後で読み込むときに大量のデータをスキップできるため、データセット全体をスキャンする代わりに、問題に関連するデータのみを読み込むことができます。...

これはおそらく、リーダーが操作する前に頻繁にフィルター処理するテーブルがある場合に使用できる、最も簡単な最適化です。たとえば、パーティションでは日付が特に一般的です。これは、ダウンストリームで、(レコードのリスト全体をスキャンするのではなく) 前の週のデータのみを確認したいことがよくあるためです。

于 2019-03-03T12:32:53.910 に答える