注: 以下の翻訳の正確性は検証されていません。AIPを利用して英語版の原文から機械的に翻訳されたものです。
このガイドは、変換を開発しているパイプライン開発者向けのガイドラインを提供することを目的としています。 一般的な 推奨事項は、プロジェクトマネージャーやプラットフォーム管理者にも興味深いもので、一般的なクリーンなパイプラインの高次原則に焦点を当てています。
パイプライン開発はソフトウェア開発です
一般的なソフトウェア開発からの多くのベストプラクティスは、ユーザーのデータパイプラインを構成する変換を定義するのと同様に適用されます。以下に、このアプローチを示すいくつかの一般的な実践を挙げます:
snake_case
で書かれています - この規約に従うことで、他の人がユーザーの素晴らしいデータセットを参照したい場合、それが awesome_dataset
であることを知ることができます。AwesomeDataset
や Awesome_Dataset
ではありません。SNAPSHOT
トランザクションを作成して前のものを上書きします。データセットを削除しようとすると、新しいデータセットを同じ場所に作成するよりも多くの問題が発生する可能性があります。Foundryは開発中のブランチで循環依存関係をチェックしますが、コードを書く際にすべてのブランチでチェックを実行するわけではありません。たとえば、マスターブランチ上にのみ存在するオントロジーの書き戻しデータセットがある場合などです。他のブランチで循環依存関係が検出された場合、Foundryはフィーチャーブランチを循環依存関係を含むブランチとマージしようとするときにチェックに失敗します。
複数のプロジェクトを通じてデータの全流れを組織化する包括的なモデルの説明については、Recommended Project structure を参照してください。
/Documentation
フォルダーと /Output
フォルダーを持つべきです。異なるユースケースやワークフロープロジェクトでは、より具体的な名前が必要になる場合がありますが、ユーザーのプロジェクト構造と命名スキームが訪問者のための道しるべであることを常に考慮してください。/scratch
フォルダーを作成することを検討してください。dataset1
、 dataset2
など)や、単一の文字の名前を選ぶと、コードの読みやすさが低下し、新しい開発者がユーザーの作業に取り組むことがはるかに困難になります。/raw/my_important_dataset
とその後の /clean/my_important_dataset
がある場合ですが、多くの場合、この命名パターンはデータセット名自体が目立つビューで混乱を生む可能性があります。覚えておいてください、系譜は追跡され、容易に見えるので、ユーザーはこのような「状態」をデータセットの名前に埋め込む必要はありません。明示的に列の型をキャストする: Datasource Project で作業している場合、データ接続からのスキーマ推論が正しい値を選択していたとしても、 raw
→ clean
変換で列の型を明示的にキャストします。これにより、列の型が変更された場合や無効な値が同期中に誤った推論を作成した場合に、ソースシステムからの破壊的な変更を検出するのに役立ちます。
「Time Only」データ型のタイムスタンプを使用する: Sparkには、「10:59:00」のような値を持つフィールドのための時間のみのデータ型がありません。Sparkのタイムスタンプ型に付属する時間関数を利用するためには、値を秒にキャストしてから -2208988800
を加え、それをタイムスタンプにキャストして年0にすることで対応します。もしくは、それを文字列として残し、ユーザーが必要に応じて解析することも可能です。
すべての数値フィールドを数値データ型にキャストする: 例えば、航空機IDの列、545
、972
、314
のようなものを考えてみてください。それらは整数に見え、ソースシステムでは実際に整数である可能性もあるので、これらを整数列にキャストすることは誘惑的です。しかし、これには大きな欠点があります:
545.0
、1,234
、右寄せなど)。異なるタイムゾーンでタイムスタンプを格納する: — Sparkのタイムスタンプはタイムゾーンに依存しません。それらは内部的にUTC(別名 Zulu、GMT)で格納されています。タイムゾーンの表示はフロントエンドで行うことが期待されています。
from_unixtime()
関数を使用して、適切なタイムゾーンの文字列を格納します。to_utc_timestamp()
関数を使用してそれらをUTCに正規化します。コミットでコードをコメントアウトする: 変更を行う際、古いコードをコメントアウトして参照用に残すか、後で元に戻す必要がある場合などになることがあります。反復処理中にコメントを使用することはできますが、コメントアウトしたステートメントを持つコードをコミットしないでください。そうすると、クラフトが増えて可読性が低下します。古いコードは、以前のコミットで簡単に見つけることができます。
作成者の詳細と日付のコメント: これらはコミット/ gitリポジトリで自動的に追跡されます。手動でコメントをすると、更新されない可能性があり、クラフトを作り出します。
過度に冗長なコメント: コメントは意思決定の背後にある理由を共有すべきであり、ロジック自体を説明すべきではありません。「自己文書化」コードを書くことを目指し、一連のステートメントが理解しにくい場合は、それがリファクタリングと単純化の明確なサインであると努力します。
master
ブランチを保護する: チームで開発している場合や、長期間継続する個人プロジェクトであっても、masterブランチを保護し、GitFlowやお好みの開発ワークフローを実践してください。コードがmasterに移動する際に、レビューとテストが行われていることを確認することが重要です。
コミットメッセージを書く: コミットメッセージは、リポジトリのすべてのアクティビティのログです。変更の有用な説明を記述するために時間をかけてください:
ブランチを整理する: 長期間維持されるリポジトリでは、ブランチが蓄積されることがあります。ブランチの開発が放棄された場合、特にブランチが別のブランチにマージされた場合は、ブランチを削除することで整理し、どのブランチがアクティブに開発されているかが分かりやすくなります。
リポジトリをアップグレードする: プロンプトに従って、リポジトリ内の言語バンドルをアップグレードする手順に従ってください。このプロセスでは、アップグレードを含むプルリクエストがアクティブブランチに開かれます。バージョンアップがコードに影響を与えないことを確認するために、アップグレードブランチでパイプラインのビルドを実行しても構いません。ただし、これらのアップグレードに常に最新の状態を保つことで、他の場所で見られるエッジケースに遭遇しないようにすることができます。これらのケースは、アップグレードされたバージョンでパッチされます。
コードレビューを実践する: トランスフォーメーションを開発するためにチームメイトと協力して、プルリクエストプロセス中にコードレビューの実践を導入してください。コードレビューのベストプラクティスについての私たちの考え方を共有していますが、データ変換コードのレビューにも多くの概念が等しく適用されます。
リポジトリ間でコードを共有する: Foundryのリポジトリは、さまざまな理由でプロジェクトレベルで動作しますが、パイプライン間で再利用できるロジックがしばしば存在します。これにはいくつかの利点があります:
DRYに従った一般的なコードの再利用。
データ基盤の異なる領域でフォーク/矛盾したロジックを回避する。
基盤パイプラインを使用するのが理想的なパイプラインがあるかもしれませんが、SLAやパフォーマンス要件がはるかに厳しい場合があります。このような場合、解決策は、ロジックを共有することですが、トランスフォーム/データセットは共有しないことで、重要なパイプラインが事前にフィルター処理されたデータセットに依存したり、トランスフォームが少なくなったり、ビルドスケジュールが異なったりすることができます。
コードリポジトリは、これを実現するための優れた方法です。例えば、Pythonトランスフォームを使用する場合、ライブラリは自分自身をCondaチャンネルに公開し、他のリポジトリがそれらを利用できるようにすることができます。Pythonライブラリの共有に関するドキュメントを参照してください。
共有リポジトリのさらなる利点はセマンティックバージョン管理です。共有リポジトリは、コミットにバージョンをタグ付けすることができます(例:1.0.0, 1.0.1, 2.0.0)、消費者ライブラリは、新しいバージョンをどのように取得するかを選択することができます。例えば、リポジトリは、最新バージョン(上記の2.0.0)を取得するか、特定のバージョン(例えば、1.0.1)のみを取得し、新しいバージョンの取得を手動で決定するまで保留することができます。後者のケースは、パイプラインが重要で、パイプラインのオーナーが共有リポジトリの変更を承認/選択する機会を得たい場合に特に有益です。
リリース: 同じように、チームがパイプラインの明確なリリーススケジュールを持ちたい場合、ステージングインスタンスや長期間維持される開発ブランチを避けるための1つのオプションは、ロジックを共有リポジトリ内の関数に分割し、セマンティックバージョンを使って消費リポジトリをメジャーリリース(1.0.0、2.0.0、または.0.0)に保持することです。これにより、開発者はロジックを継続的に反復処理し、中間リリースをタグ付けすることができます。ただし、master上でライブにならないようにします。さらに、消費リポジトリのブランチでは、開発者は常に中間バージョンを取得することができます。ただし、リリース日前にマスターにマージしない限り、中間バージョンを取得することができます。
ユニットテストは、コード品質の向上と維持に役立つ人気のある方法です。ユニットテストでは、ソフトウェアの小さくて個別なコンポーネント(「ユニット」)が、個別に、独立して、自動化された方法でテストされます。
Pythonユニットテスト: PythonトランスフォームリポジトリのCIチェックの一部としてpytest
ユニットテストを有効にするには、Pythonユニットテストの手順に従ってください。
Javaユニットテスト: Javaトランスフォーム用のユニットテストを設定する手順は、Javaユニットテストのドキュメントに記載されています。
ユニットテストは、次の条件を満たす必要があります:
データの健康状態をチェックする: パイプラインの一部が完了した後、スケジュールを設定し、気にかけなくなることがよくあります。しかし、ロジックが正しい場合でも、入力データがビルドに影響を与える方法で変更される可能性があります。これにより、パフォーマンスが低下したり、データ規模が増加したり、ビルドが完全に失敗したりする可能性があります。データセットのサイズやビルド時間に基本的なチェックを設定し、アラートを設定しなくても、これらの主要な指標の時間経過による状況を確認できます。たとえば、データセットのサイズがどれだけ増加しているかや、データセットの平均ビルド時間を確認することができます。利用可能なヘルスチェックとそれらの設定方法について詳しく読んでください。
ヘルスチェックを拡張する: ほとんどの場合、デフォルトのヘルスチェック設定で十分なはずです。ただし、さらなる柔軟性が必要な場合は、パイプラインに1つ以上の派生したヘルスチェック
データセットを追加してください。このデータセットのトランスフォームは、入力データセット(検証するデータセット)の妥当性を判断するために任意のロジックを実行し、その後、シンプルなヘルスチェック(Allowed Value
など)がデータセットが有効かどうかを報告できるように、データを出力形式に合わせます。
このデータセットのスケジュールを、入力データセットが更新されるたびにビルドされるように設定すると、包括的なヘルスチェックの追加セットが得られます。
スケジューリングのベストプラクティスを確認してください。