外部HiveテーブルはParquetとして保存され、列as_of_dt
とデータはsparkストリーミング経由で挿入されます。現在、毎日新しいパーティションが追加されています。私はmsck repair table
これにより、Hiveメタストアは新しく追加されたパーティション情報を取得します。これが唯一の方法ですか、それともより良い方法がありますか?テーブルを照会するダウンストリームユーザーがmsck repair
データまたは古いデータの非可用性に問題がありますか?私はHiveContext
APIを使用していましたが、refreshTable
オプションを参照してください。代わりにrefreshTable
を使用するのが理にかなっているなら、どんな考えですか?
質問msck repair tableに直接回答するには、テーブルのパーティションがアクティブかどうかを確認します。少数のパーティションを削除し、テーブルのshow partitionsコマンド内に表示したくない場合、msck repair tableはそれらを削除する必要があります。 Msckの修復は、無効化ステートメントまたは更新ステートメントよりも時間がかかりますが、メタデータの無効化は、Hive Metastoreのみを更新するHive内でのみ実行されます。更新はSpark SQLでのみ実行され、Sparkメタデータストアを更新します。
Hiveメタストアは、処理のどこかでパーティションの追加ステップを完了する場合は問題ありませんが、Spark SQLを介してHiveテーブルにアクセスする場合は、Sparkを介してメタデータを更新する必要があります(またはImpalaまたはsparkメタデータを更新する別のプロセス)。
Hiveテーブルのコンテンツを更新または変更すると、Sparkメタストアが同期しなくなる可能性があり、spark.sqlコマンドセットを介してデータをクエリできなくなります。そのデータをクエリする場合は、Sparkメタストアの同期を維持する必要があります。
Sparkバージョンを使用できる場合は、Spark内のパーティションを更新してHiveテーブルに追加し、すべてのメタストアが同期するようにします。以下がその方法です。
//Non-Partitioned Table
outputDF.write.format("parquet").mode("overwrite").load(fileLocation)
spark.sql("refresh table " + tableName)
//Partitioned Table
outputDF.write.format("parquet").mode("overwrite").load(fileLocation + "/" + partition)
val addPartitionsStatement = "alter table" + tableName = " add if not exists partition(partitionKey='" + partition + "') location '" + fileLocation + "/" + partition + "'"
spark.sql(addPartitionsStatement)
spark.sql("refresh table " + tableName)
RefreshTableはキャッシュされたメタデータを更新するように見えますが、Hiveメタデータには影響しません。
Doc 言います:
指定されたテーブルのキャッシュされたすべてのメタデータを無効にして更新します。パフォーマンス上の理由から、Spark SQLまたは使用する外部データソースライブラリは、ブロックの場所など、テーブルに関する特定のメタデータをキャッシュする場合があります。これらがSpark SQL、ユーザーはこの関数を呼び出してキャッシュを無効にする必要があります。
メソッドはHiveメタデータを更新しないため、修復が必要です。