Delta Lake の詳现: スキヌマの適甚ず進化

おい、ハブル 蚘事の翻蚳をご玹介したす 「デルタ湖ぞのダむビング: スキヌマの匷制ず進化」 著者はBurak Yavuz、Brenner Heintz、Denny Lee。このコヌスの開始に備えお準備されたした。 デヌタ゚ンゞニア オヌタスから。

Delta Lake の詳现: スキヌマの適甚ず進化

デヌタは私たちの経隓ず同様、垞に蓄積され、進化しおいたす。 それに远い぀くためには、私たちの䞖界のメンタル モデルが新しいデヌタに適応する必芁があり、その䞭には新しい次元、぀たり私たちがこれたで知らなかったものを芳察する新しい方法が含たれおいるものもありたす。 これらのメンタル モデルは、新しい情報をどのように分類しお凊理するかを決定するテヌブル スキヌマずあたり倉わりたせん。

ここで、スキヌマ管理の問題が生じたす。 ビゞネスの課題や芁件が時間の経過ずずもに倉化するに぀れお、デヌタの構造も倉化したす。 Delta Lake を䜿甚するず、デヌタの倉化に応じお新しい枬定倀を簡単に導入できたす。 ナヌザヌは、テヌブル スキヌマを管理するための単玔なセマンティクスにアクセスできたす。 これらのツヌルには、ナヌザヌが゚ラヌや䞍芁なデヌタでテヌブルを意図せず汚染しないように保護する Schema Enforcement ず、貎重なデヌタの新しい列を適切な堎所に自動的に远加できるようにする Schema Evolution が含たれたす。 この蚘事では、これらのツヌルの䜿甚法に぀いお詳しく説明したす。

テヌブルスキヌマを理解する

Apache Spark の各 DataFrame には、デヌタ型、列、メタデヌタなどのデヌタの圢匏を定矩するスキヌマが含たれおいたす。 Delta Lake では、テヌブル スキヌマはトランザクション ログ内に JSON 圢匏で保存されたす。

スキヌムの斜行ずは䜕ですか?

スキヌマ匷制 (スキヌマ怜蚌ずも呌ばれたす) は、テヌブルのスキヌマに䞀臎しないレコヌドを拒吊するこずでデヌタ品質を保蚌する Delta Lake のセキュリティ メカニズムです。 予玄制の人気レストランのフロントデスクのホステスのように、テヌブルに入力されたデヌタの各列が、察応する予想される列のリストに含たれおいるかどうか (぀たり、それぞれの列に「予玄」があるかどうか) をチェックしたす。 )、リストにない列を含むレコヌドは拒吊されたす。

スキヌマの匷制はどのように機胜したすか?

Delta Lake は曞き蟌み時のスキヌマ チェックを䜿甚したす。これは、テヌブルぞのすべおの新しい曞き蟌みが、曞き蟌み時にタヌゲット テヌブルのスキヌマずの互換性に぀いおチェックされるこずを意味したす。 スキヌマに矛盟がある堎合、Delta Lake はトランザクションを完党に䞭止し (デヌタは曞き蟌たれたせん)、䟋倖を発生させおナヌザヌに矛盟を通知したす。
Delta Lake は、次のルヌルを䜿甚しお、レコヌドがテヌブルず互換性があるかどうかを刀断したす。 曞き蟌み可胜なデヌタフレヌム:

  • タヌゲットテヌブルのスキヌマにない远加の列を含めるこずはできたせん。 逆に、受信デヌタにテヌブルのすべおの列が完党に含たれおいない堎合は、すべお問題ありたせん。これらの列には、単玔に null 倀が割り圓おられたす。
  • タヌゲットテヌブルの列のデヌタ型ず異なる列デヌタ型を持぀こずはできたせん。 タヌゲット テヌブルの列に StringType デヌタが含たれおいるが、DataFrame 内の察応する列に IntegerType デヌタが含たれおいる堎合、スキヌマの匷制によっお䟋倖がスロヌされ、曞き蟌み操䜜が実行されなくなりたす。
  • 倧文字ず小文字のみが異なる列名を含めるこずはできたせん。 これは、同じテヌブル内に「Foo」ず「foo」ずいう名前の列を定矩するこずはできないこずを意味したす。 Spark は倧文字ず小文字を区別するモヌドたたは倧文字ず小文字を区別しない (デフォルト) モヌドで䜿甚できたすが、Delta Lake は倧文字ず小文字を保持したすが、スキヌマ ストレヌゞ内では区別されたせん。 Parquet は、列情報を栌玍および返すずきに倧文字ず小文字を区別したす。 起こり埗る゚ラヌ、デヌタ砎損、たたはデヌタ損倱 (Databricks で個人的に経隓したこず) を回避するために、この制限を远加するこずにしたした。

これを説明するために、新しく生成された列をただ受け入れるように構成されおいない Delta Lake テヌブルに远加しようずしたずきに、以䞋のコヌドで䜕が起こるかを芋おみたしょう。

# СгеМерОруеЌ DataFrame ссуЎ, кПтПрый Ќы ЎПбавОЌ в Машу таблОцу Delta Lake
loans = sql("""
            SELECT addr_state, CAST(rand(10)*count as bigint) AS count,
            CAST(rand(10) * 10000 * count AS double) AS amount
            FROM loan_by_state_delta
            """)

# ВывестО ОсхПЎМую схеЌу DataFrame
original_loans.printSchema()

root
  |-- addr_state: string (nullable = true)
  |-- count: integer (nullable = true)
 
# ВывестО МПвую схеЌу DataFrame
loans.printSchema()
 
root
  |-- addr_state: string (nullable = true)
  |-- count: integer (nullable = true)
  |-- amount: double (nullable = true) # new column
 
# ППпытка ЎПбавОть МПвый DataFrame (с МПвыЌ стПлбцПЌ) в существующую таблОцу
loans.write.format("delta") 
           .mode("append") 
           .save(DELTALAKE_PATH)

Returns:

A schema mismatch detected when writing to the Delta table.
 
To enable schema migration, please set:
'.option("mergeSchema", "true")'
 
Table schema:
root
-- addr_state: string (nullable = true)
-- count: long (nullable = true)
 
Data schema:
root
-- addr_state: string (nullable = true)
-- count: long (nullable = true)
-- amount: double (nullable = true)
 
If Table ACLs are enabled, these options will be ignored. Please use the ALTER TABLE command for changing the schema.

新しい列を自動的に远加する代わりに、Delta Lake はスキヌマを匷制し、曞き蟌みを停止したす。 どの列 (たたは列のセット) が䞍䞀臎の原因ずなっおいるかを刀断するために、Spark は比范のためにスタック トレヌスから䞡方のスキヌマを出力したす。

スキヌマを匷制する利点は䜕ですか?

スキヌマの適甚はかなり厳栌なチェックであるため、運甚たたは䜿甚の準備ができおいるクリヌンで完党に倉換されたデヌタ セットぞのゲヌトキヌパヌずしお䜿甚するのに最適なツヌルです。 通垞は、デヌタを盎接フィヌドするテヌブルに適甚されたす。

  • 機械孊習アルゎリズム
  • BI ダッシュボヌド
  • デヌタ分析および芖芚化ツヌル
  • 高床に構造化され、厳密に型指定されたセマンティック スキヌマを必芁ずする実皌働システム。

この最埌のハヌドルに向けおデヌタを準備するために、倚くのナヌザヌは、テヌブルに埐々に構造を導入する単玔な「マルチホップ」アヌキテクチャを䜿甚したす。 これに぀いお詳しくは、蚘事をご芧ください。 Delta Lake を䜿甚した実皌働グレヌドの機械孊習。

もちろん、スキヌマの適甚はパむプラむンのどこでも䜿甚できたすが、この堎合、テヌブルぞのストリヌミングはむラむラする可胜性があるこずに泚意しおください。たずえば、受信デヌタに別の列を远加したこずを忘れおいるためです。

デヌタの垌薄化を防ぐ

ここたでで、䞀䜓䜕が倧隒ぎしおいるのかず疑問に思っおいるかもしれたせん。 結局のずころ、特に Delta Lake を初めお䜿甚する堎合は、予期しない「スキヌマの䞍䞀臎」゚ラヌによっおワヌクフロヌが぀たづいおしたうこずがありたす。 必芁に応じおスキヌマを倉曎しお、䜕があっおも DataFrame を蚘述できるようにしおはどうでしょうか?

叀いこずわざにあるように、「XNUMX オンスの予防は XNUMX ポンドの治療に匹敵したす。」 スキヌマの適甚に泚意しないず、ある時点で、デヌタ型の互換性の問題が厄介な問題ずしお浮䞊したす。䞀芋均質な生デヌタ ゜ヌスには、゚ッゞ ケヌス、砎損した列、䞍正なマッピング、たたはその他の恐ろしい事態が含たれおいる可胜性がありたす。悪倢。 最善のアプロヌチは、スキヌマの匷制を䜿甚しお、これらの敵を門前で阻止し、埌で本番コヌドの暗い深さに朜み始めたずきに察凊するのではなく、明るいうちに察凊するこずです。

スキヌマを匷制するず、倉曎を承認しない限りテヌブルのスキヌマが倉曎されないこずが保蚌されたす。 これにより、新しい列が頻繁に远加され、デヌタの氟濫によっお以前は貎重で圧瞮されたテヌブルの意味や有甚性が倱われる堎合に発生する可胜性のあるデヌタの垌薄化が防止されたす。 意図的に行動し、高い基準を蚭定し、高品質を期埅するこずを奚励するこずで、スキヌマの適甚は蚭蚈どおりに機胜し、誠実さを保ち、スプレッドシヌトをクリヌンに保぀のに圹立ちたす。

さらに怜蚎した結果、本圓にそう刀断した堎合は、 必芁 新しい列を远加したす。問題ありたせん。以䞋は XNUMX 行の修正です。 解決策は回路の進化

スキヌマ進化ずは䜕ですか?

スキヌマ進化は、時間の経過ずずもに倉化するデヌタに応じお珟圚のテヌブル スキヌマを簡単に倉曎できる機胜です。 これは、远加たたは曞き換え操䜜を実行しお XNUMX ぀以䞊の新しい列を含むようにスキヌマを自動的に調敎するずきに最もよく䜿甚されたす。

スキヌマ進化はどのように機胜するのでしょうか?

前のセクションの䟋に埓うず、開発者はスキヌマの進化を䜿甚しお、スキヌマの䞍敎合のために以前に拒吊された新しい列を簡単に远加できたす。 远加するこずで回路進化が発動したす .option('mergeSchema', 'true') Spark チヌムぞ .write ОлО .writeStream.

# ДПбавьте параЌетр mergeSchema
loans.write.format("delta") 
           .option("mergeSchema", "true") 
           .mode("append") 
           .save(DELTALAKE_SILVER_PATH)

グラフを衚瀺するには、次の Spark SQL ク゚リを実行したす。

# СПзЎайте графОк с МПвыЌ стПлбцПЌ, чтПбы пПЎтверЎОть, чтП запОсь прПшла успешМП
%sql
SELECT addr_state, sum(`amount`) AS amount
FROM loan_by_state_delta
GROUP BY addr_state
ORDER BY sum(`amount`)
DESC LIMIT 10

Delta Lake の詳现: スキヌマの適甚ず進化
あるいは、远加するこずで、Spark セッション党䜓に察しおこのオプションを蚭定できたす。 spark.databricks.delta.schema.autoMerge = True Spark 構成に远加したす。 ただし、スキヌマの匷制により、意図しないスキヌマの䞍䞀臎が譊告されなくなるため、これは泚意しお䜿甚しおください。

リク゚ストにパラメヌタを含めるこずにより、 mergeSchema、デヌタフレヌムには存圚するがタヌゲットテヌブルには存圚しないすべおの列は、曞き蟌みトランザクションの䞀郚ずしおスキヌマの最埌に自動的に远加されたす。 ネストされたフィヌルドを远加するこずもでき、これらも察応する構造列の末尟に远加されたす。

デヌタ ゚ンゞニアずデヌタ サむ゚ンティストは、このオプションを䜿甚しお、叀い列に基づく既存のモデルを壊すこずなく、既存の機械孊習実皌働テヌブルに新しい列 (おそらく、最近远跡された指暙たたは今月の販売実瞟列) を远加できたす。

次のタむプのスキヌマ倉曎は、テヌブルの远加たたは曞き換え䞭のスキヌマ進化の䞀環ずしお蚱可されたす。

  • 新しい列の远加 (これが最も䞀般的なシナリオ)
  • デヌタ型を NullType -> 他の型に倉曎するか、ByteType -> ShortType -> IntegerType に昇栌したす。

スキヌマの進化内で蚱可されおいないその他の倉曎では、スキヌマずデヌタを远加しお曞き盎す必芁がありたす。 .option("overwriteSchema", "true")。 たずえば、列「Foo」が元々敎数で、新しいスキヌマが文字列デヌタ型だった堎合、すべおの Parquet(data) ファむルを曞き盎す必芁がありたす。 このような倉曎には次のものが含たれたす。

  • 列の削陀
  • 既存の列のデヌタ型を倉曎する (むンプレヌス)
  • 倧文字ず小文字のみが異なる列の名前を倉曎する (たずえば、「Foo」ず「foo」)

最埌に、Spark 3.0 の次のリリヌスでは、明瀺的な DDL が (ALTER TABLE を䜿甚しお) 完党にサポヌトされ、ナヌザヌがテヌブル スキヌマに察しお次のアクションを実行できるようになりたす。

  • 列の远加
  • 列のコメントを倉曎する
  • トランザクション ログの保存期間の蚭定など、テヌブルの動䜜を制埡するテヌブル プロパティを蚭定したす。

回路の進化の利点は䜕ですか?

スキヌマの進化はい぀でも䜿甚できたす。 意図する テヌブルのスキヌマを倉曎したす (存圚すべきではない列を誀っお DataFrame に远加した堎合ずは異なりたす)。 これは、明瀺的に宣蚀しなくおも正しい列名ずデヌタ型が自動的に远加されるため、スキヌマを移行する最も簡単な方法です。

たずめ

スキヌマの匷制は、テヌブルず互換性のない新しい列やその他のスキヌマの倉曎を拒吊したす。 これらの高い基準を蚭定しお維持するこずで、アナリストや゚ンゞニアはデヌタが最高レベルの敎合性を持っおいるこずを信頌し、デヌタを明瞭か぀明確に䌝え、より適切なビゞネス䞊の意思決定を行うこずができたす。

䞀方、スキヌマの進化は、スキヌマを簡玠化するこずで斜行を補完したす。 想定された 自動スキヌマ倉曎。 結局のずころ、列を远加するのは難しくないはずです。

スキヌムの匷制適甚は陜であり、スキヌムの進化は陰です。 これらの機胜を䜵甚するず、ノむズ抑制ず信号調敎がこれたでより簡単になりたす。

この蚘事ぞの貢献に぀いおは、Mukul Murthy 氏ず Pranav Anand 氏にも感謝いたしたす。

このシリヌズの他の蚘事:

Delta Lake の詳现: トランザクション ログの開梱

関連蚘事

Delta Lake を䜿甚した本番グレヌドの機械孊習

デヌタレむクずは䜕ですか?

コヌスに぀いお詳しく芋る

出所 habr.com

コメントを远加したす