[翻訳] 上級開発者が犯してしまう15の重大なDatabricksの間違い: セキュリティ、ワークフロー、環境

[15 Critical Databricks Mistakes Advanced Developers Make: Security, Workflows, Environment \| by Maksim Pachkovskiy \| Apr, 2025 \| Dev Genius](https://blog.devgenius.io/14-critical-databricks-mistakes-advanced-developers-make-security-workflows-environment-7da269c46795)の翻訳です。すごく頷くことばかりでした。

:::note warn
本書は著者が手動で翻訳したものであり内容の正確性を保証するものではありません。正確な内容に関しては原文を参照ください。
:::

上級開発者がよく遭遇する15の重大なDatabricksの間違いを明らかにします。ワークフローの最適化、セキュリティのベストプラクティス、Git連携、環境管理、効果的なクラスター戦略、コスト節約のヒントなど重要なヒントを学びましょう。

![](https://miro.medium.com/v2/resize:fit:720/format:webp/1*E-k2BRn-IGPKvVGIjt9kSQ.jpeg)

私は、Databricksにおけるよくある間違いと修正方法に関する実践的な情報を共有し続けます。最初のパートである[11 Common Databricks Mistakes Beginners Make: Best Practices for Data Management and Coding](https://medium.com/@protmaks/11-common-databricks-mistakes-beginners-make-best-practices-for-data-management-and-coding-e3c843bad2b0)([翻訳](https://qiita.com/taka_yayoi/items/ab94f2ec1409beb4a125))を読むことをお勧めします。

# 1. 日付を計算する際にUTCゾーンを無視する

**間違い:** 多くの開発者は、DatabricksクラスターがUTCゾーンで稼働していることを考えずに、現在の日を使用します。これは、あなたのローカルタイムゾーンで深夜遅くや朝早くにスクリプトが実行される際、間違った日付の計算につながり、間違った日にデータが処理されてしまうことがあります。

```sql
-- Problematic approach (uses UTC) if you are using Spark SQL
% sql 
SELECT  *  FROM  TABLE 
WHERE FILE_DATE >=  current_date ()
```

```py
# Problematic approach (uses UTC) if you are using Spark
 today = datetime.now().date()
```

**修正方法:** 

最初の方法は、クラスターでデフォルトタイムゾーンを設定するというものです:

```py
# Set the default time zone for a Spark session
spark.conf. set ( "spark.sql.session.timeZone" , "America/New_York" )
```

こちらは、Sparkでタイムゾーンを設定する方法です:

```py
from datetime import datetime 
import pytz 

local_tz = pytz.timezone( 'America/New_York' )   # or your local time zone
today = datetime.now(pytz.UTC).astimezone(local_tz).date()
```

こちらは、Spark SQLでタイムゾーンを設定する方法です:

```sql
% sql 
SELECT  *  FROM  TABLE 
WHERE FILE_DATE >=  date (from_utc_timestamp(current_timestamp (), 'EST' ))
```

# 2. 開発や本番環境の適切な分離なしに単一の環境で作業する

**間違い:** 開発、運用の間の明確な分離なしに、単一のDatabricks環境で作業してしまうことはよくある間違いであり、データの損失につながる場合があります。理想的には、(Dev、QA、Prodなど)異なる環境に分離されたDatabricksワークスペースを作成すべきです。また、経験が少ないことから、開発者がリクエストごとにDEVやPRODのテーブルを手動で切り替えるということをも起こります。

**修正方法:** しかし、予算の制約やその他の制限によって、複数の環境を作成することが常に可能とは限りません。複数の個別の環境をセットアップできない場合には、実践的な妥協策は単一の環境で論理的な分離を行うことです。便利なアプローチの一つは、ノートブックでスキーマとテーブルのプレフィックスを用いるものです。

ノートブックにおいて、ワークスペースを2つのフォルダDEVとPRODに分割する必要があります。あるいは、個人フォルダで開発を行い、スケジュールが設定されるすべてのノートブックは、共通のPROFフォルダに移動されるべきです。

`schema_prefix`変数のように、環境のパラメータを明示的に定義することでそれぞれのノートブックをスタートします。この例では、ノートブックへのパスを定義し、単語(**PROD**)が名前に含まれていることをチェックします:

```py
# defining DEV or PROD environment
notebook_path = (dbutils.notebook.entry_point.getDbutils().notebook().getContext().notebookPath().getOrElse(None))
if "(PROD)" in notebook_path.upper():
    schema_prefix = "catalog.prod_schema"
else:
    schema_prefix = "catalog.dev_schema"
```

そして、クエリーを使用する際にノートブックが(PROD)という名前のフォルダーに位置していない場合には、実際のテーブルに損害を与えません:

```py
spark.sql(f"""
  DELETE FROM {schema_prefix}.clients
  WHERE
    DATE = current_date()
""")
```

# 3. 適切なワークフローオーケストレーションではなく、ノートブックでの`%run`コマンドを用いて長いプロセスのチェーンを構築する

**間違い:** ノートブックを取り扱う多くの開発者は、外部のスクリプトやノートブックを実行するために、多くの場合で過度に`%run`マジックコマンドに依存しています。`%run`は、ノートブックにおけるクイックな変数やライブラリのロードには便利で適していますが、何人かの開発者はこのアプローチを、複雑で長い処理チェーンの構築に適用しています。この慣習は、主に特化されたオーケストレーションツールに気づいていないことによって起こります。

```py
%run .variables
```

初めはこれが実践的に見えるかもしれませんが、`%run`チェーンに過度に依存すると、すぐに非生産的になってしまうことがあります。このような戦略は、処理のデバッグ、追跡、スケールを困難なものにしてしまいます。また、長い`%run`のカスケードは脆弱なものになります: 一つのステップが失敗すると、予期せずにすべてのプロセスが停止してしまうかもしれません。

**修正方法:** `%run`コマンドを過度に使用するのではなく、シームレスなパイプライン管理のために、Databricksノートブックに直接連携する堅牢なオーケストレーションソリューションであるDatabricksワークフローを導入することをお勧めします。Databricksワークフローは以下のような様々なメリットを提供します:

- 統合された環境: 統合されたDatabricksワークスペースで、簡単にノートブック、ジョブ、タスクをオーケストレーションすることができます。
- 明確なタスクの依存関係: ビジュアル的に依存関係を定義、管理し、複雑な処理フローをシンプルにします。
- 耐障害性: リトライ、条件ロジック、アラートを設定することで、容易にエラーに対応でき、堅牢性を改善します。
- 強化されたモニタリングとロギング: ワークフローの問題をクイックに特定し、対応するために、Databricksプラットフォームで、詳細なログ、メトリクス、パフォーマンス追跡にアクセスします。
- 柔軟なスケジュールのオプション: 時間間隔やトリーガー条件に基づくワークフローのスケジュールによって、ビジネス要件に応じて実行を自動化します。
- スケールがシンプル: 過度なリファクタリングなしに、進化する要件に対応するために、簡単にワークフローをスケール、修正できます。

Databricksワークフローを活用することで、チームは`%run`によるノートブック実行のチェーンにおける制約を排除し、柔軟性、透明性、安定性を強化します。

![](https://miro.medium.com/v2/resize:fit:1400/format:webp/1*j7HYgInuK94lx5vZ7BSVFA.gif)

# 4. 他のチームメンバー/グループにワークフローの権限を許可し損ねる

**間違い:** 他のチームメンバーやグループにワークフローの権限を許可し損ないます。デフォルトではワークフローは作成者のみが参照できます。

**修正方法:** ワークフローを作成した後に、権限やワークフローの設定に移動します。アクセスを必要とするチームメンバーやグループを明示的に追加します。適切なアクセス権レベルを定義します: 責任範囲に応じて**Can Manageや**Can View**を設定します。

# 5. Databricksワークフローの閾値アラートやモニタリングを設定し忘れる

**間違い:** Databricksワークフローで閾値のアラートやモニタリングのパラメータを設定し忘れます。

適切なアラートの閾値なしには、ワークフローの失敗や予期しないパフォーマンス劣化は、数日間気付かれないことになり、非効率的なリソース使用や不必要な予算消費につながります。

**修正方法:** 典型的なオペレーション条件における、ノートブックやワークフローの過去の実行時間を確認します。通常の実行時間を決定し、この典型的な期間の約2倍に閾値を設定します。

効果的な閾値監視は、異常や停止したワークフローに関してチームに即座に警告を行い、クイックな問題解決や、長期化する不必要なリソース使用を削減することで大幅なコスト削減につながります。

# 6. あなたのチームがDatabricksワークフローのエラー通知を受け取るようにしましょう

**間違い:** Databricksワークフローでは、デフォルトでエラー通知はワークフローの作成者のみに送信されます。しかし、時にはワークフロー開発者は、このデフォルトの変更と担当のグループへの割り当てを忘れ、さらに悪い場合には通知設定から自身のコンタクトを削除してしまうことがあります。この結果、ワークフローが失敗した際に、誰もすぐに気付かず、重要な問題が気づかれないままとなってしまいます。

**修正方法:** 

- ワークフローのエラー通知の受信者として、個人の開発者ではなく、常に担当のグループに割り当てるようにしましょう。
- アラートの受信者が設定されていないワークフローが存在しないように、定期的にDatabricksワークフローの通知設定を監査しましょう。

# 7. ワークフローでジョブクラスターを使わない(代わりに間違ってインタラクティブクラスターを使ってしまう)

**間違い:** 自動化、スケジュールタスクで、専用のジョブクラスターではなくインタラクティブクラスターを使ってしまう。

Databricksでは2つの主要タイプのクラスターを提供しています:

- **インタラクティブクラスター** - プロジェクト初期やスクリプト開発で使用されます。クイックな修正や手動での実行が必要となるインタラクティブ、探索的なタスクで理想的です。通常、これらのクラスターは手動で利用されている限り実行し続けます。
- **ジョブクラスター** - スケジュールされたワークフローや自動化されたスクリプト実行に特化されて設計されています。これらは、スケジュールされたタスクがスタートした際に自動で起動し、処理の完了とともに即座にシャットダウンし、不必要なリソースや予算の無駄を回避します。

**修正方法:** 

- スケジュールされたスクリプトやワークフローでは常にジョブクラスターを選択しましょう。
- お使いのスクリプトのリソース要件に合わせてジョブクラスターを設定しましょう。
- 既存のワークフローが、インタラクティブクラスターではなくジョブクラスターを使っていることを定期的にレビューしましょう。

インタラクティブクラスターではなくジョブクラスターを用いることで、効率的なリソース管理、コストの削減を可能にし、スケジュールされたプロセスのよりスムーズなオペレーションを実現し、潜在的な競合を避けることができます。

# 8. 自動停止を有効にしないでインタラクティブDatabricksクラスターをセットアップしてしまう

**間違い:** 自動停止を有効化せずにインタラクティブDatabricksクラスターをセットアップしてしまい、誰もアクティブに使用していない場合でもクラスターが稼働を継続してしまう。この見過ごしは、すぐに不必要なDatabricks予算の消費につながってしまいます。

**修正方法:** インタラクティブクラスターを作成する際は、常にクラスター設定で自動停止機能を有効化しましょう。推奨の未使用期間(通常は30-60分)に設定し、指定されたタイムフレームでアイドル状態だった後に自動でクラスターをシャットダウンするようにしましょう。

# 9. Deltaテーブルに対する定期的なVACUUMを実行し忘れる

**間違い:** Deltaテーブルでの定期的なVACUUMの実行を忘れると、使用されないデータファイルが積み上がることになります。これはストレージ空間を浪費し、全体的なパフォーマンスにネガティブな影響を与えます。

**修正方法:** 古くて使用されていないデータファイルをクリーンアップするために、定期的にVACUUMオペレーションを実行します。あるいは、それぞれのテーブルのデータ更新頻度に合わせたスケジュールDatabricksジョブを作成することで、VACUUMを自動化します:

```sql
VACUUM table_name RETAIN 168 HOURS; -- retain 7 days
```

```sql
VACUUM table_name RETAIN 1440 HOURS; -- retain 60 days
```

定期的なVACUUMはストレージコストを削減し、クエリーの効率性を改善し、Deltaテーブルが整理、最適化され続けることを確実にします。

# 10. (Databricksシークレットを使わずに)コードに直接パスワードやシークレットを格納してしまう

**間違い:** あなたのコードに直接パスワードや機微な鍵を含めてしまうことは、よくあるセキュリティの問題です。

```py
my_password = "SecretPassword123"
```

**修正方法:** Microsoft Azureでのソリューションを提案します。Key Vault Secretsはパスワード、APIキーやその他の機微情報を格納するための、セキュアなクラウドサービスです。シークレットへのアクセスの集中管理、保護、コントロールの助けとなります。

通常、あなたのクラウド管理者がAzure Key Vaultにシークレット(データベースのパスワードなど)を作成し、あなたはAzure Databricksノートブックからセキュアにそのシークレットにアクセスすることができます。このアプローチによって、セキュリティのベストプラクティスに従うことを確実とし、機微情報が
決してコードに直接格納されることがなくなります。

***クラウド管理者:*** Azure Key Vault(`my-keyvault`)にシークレット(`my-db-password`)を作成。

***あなた(Databricksノートブックで):*** ノートブックからシークレットスコープを用いてAzure Key VaultからDatabricksにリンクし、シークレットにアクセス:

```py
my_password = dbutils.secrets.get(scope="my-keyvault-scope", key="my-db-password")
```

# 11. クラウドノートブックからオンプレミスのデータベースに直接接続してしまう

**間違い:** あるケースにおいては、企業はクラウドノートブックから自身のオンプレミスのデータベースやファイルシステムへのアクセスをオープンにしたままにしてしまいます。そして、接続の詳細(ホスト、ポート、資格情報)を知っている従業員は直接接続します。上述したように、従業員は間違ってパスワードをノートブックに直接格納してしまうかもしれません(ポイント9でカバーしました)。

***関連するリスク:***

- セキュリティの脆弱性: 不正アクセスやパスワード漏洩。
- 監査証跡やコントロールの欠如: みんなが個別に接続すると、誰が機微なリソースに出アクセスしたのかを追跡することが困難となります。
- パフォーマンス問題: 直接のクエリーがオンプレミスのデータベースを過負荷にし、他のユーザーにとっての害となります。
- コンプライアンス問題: 直接の外部接続は、データ規制やポリシーに違反するかもしれません。

**修正方法:** 代わりに、企業では集中管理されたデータローディングフレームワークやソリューションを導入すべきです。適切でセキュア、堅牢な方法は、定期的かつ安全にオンプレミスのデータをクラウドストレージやデータベースに同期するために、特化されたツールやフレームワーク(Azure Data Factoryパイプラインや、セキュアに管理されたETLプロセスなど)を用いるというものです。そして、従業員はノートブックや分析アプリケーションを、クラウドにセキュアに保持された集中管理、事前準備されたデータセットにのみ接続します。

# 12. Gitバージョン管理連携を活用しない

**間違い:** あなたのチームでは、スクリプトの変更を追跡するためにGitを使っていません。これによって、誰が何を変更したのかを確認することが困難となり、スクリプトのバックアップにおける課題を引き起こし、特定のコードの特定が非常に困難になります。

**修正方法:** 

- **Gitを使い始める:** あなたのすべてのスクリプトをGitリポジトリに保管しましょう。
- **定期的に変更を保存しましょう:** 時間経過に伴う変更を明確に追跡できるように、変更を頻繁に追加、コミットしましょう。
- **ブランチを使いましょう:** 新機能やテストに取り組む際には個別のブランチを作成し、メインバージョンが安定性を保つようにしましょう。
- **あなたのチームを訓練しましょう:** チームメンバーに基本的なGitコマンドを教え、なぜ有用なのかを説明しましょう。
- **簡単なスクリプト検索:** 必要なスクリプトは変更をクイックに特定するために、Git組み込みのツールを使いましょう。

# 13. オンプレミスからクラウド環境に移行した際に機微な情報を暗号化しない

**間違い:** オンプレミスからDatabricksクラウド環境に移行する際、開発者は多くの場合において、適切な暗号化を実装せずに機微なデータを含むテーブルを転送してしまいます。クラウドに格納するデータにはより強力な保護を必要とすることから、重大なセキュリティの脆弱性を引き起こすことになります。一般的な問題には以下のようなものがあります:

- 平文で顧客のPII、財務データ、健康情報を移動する。
- 暗号化なしに、機微なカラム(SNN、クレジットカード番号、住所)を保存する。
- どのテーブルカラムが暗号化を必要とするのかを特定できない。
- 開発、テスト環境で実際のPIIデータを使う。
- 機微データに対する会社のセキュリティポリシーを無視する。

**修正方法:** 

1. 強力な暗号化標準を実装しましょう:
    AES-256のように確立された暗号化標準を用いて、機微なカラムの格納時と通信時に暗号化しましょう。Databricksとクラウドプロバイダー(AWS KMSやAzure Key Vault)は、鍵の主柱管理のためのインテグレーションを提供しています。

    ```py
    from pyspark.sql.functions import col, sha2

    encrypted_df = customer_df.withColumn("SSN_encrypted", sha2(col("SSN"),256))
    ```

    ```sql
    %sql
    SELECT
      *,
      sha2(SSN, 256) AS SSN_encrypted
    FROM customer
    ```

1. 非プロダクション環境ではデータのマスキングや匿名化を活用しましょう:

    テスト、開発、分析環境においては、漏えいのリスクを最小化するために機微なデータをマスクあるいは匿名化しましょう。

    ```sql
    %sql
    SELECT 
      CONCAT('user', FLOOR(RAND()*10000), '@example.com') AS masked_email,
      CONCAT('**** **** **** ', RIGHT(credit_card_number,4)) AS masked_credit_card
    FROM customer_transactions
    ```

# 14. データ転送の際にPIIデータを露出させたままにしてしまう

**間違い:** 多くの場合、開発者はデータベースのテーブルの暗号化にフォーカスしますが、Databricksに転送されるファイル(CSV、JSON、Parquet、Excelなど)にも存在する機微なPIIデータを見逃してしまうことがあります。一般的な見逃しには以下のようなものがあります:

- 顧客情報を含む暗号化されていないファイルをDBFSやクラウドストレージにアップロードする。
- セキュアではないプロトコル(SFTPやHTTPSではなくFTPやHTTP)で機微なファイルを転送する。
- 機微なファイルを処理した後に削除しない。
- PIIを含むファイルに対して適切なアクセス制御を施さない。
- 非常にセキュアでなく、ほとんどのデータ保護ポリシーに違反するメールでPIIデータを送信する。

**修正方法:** ファイル転送の過程での不正アクセスやPIIデータの露出を防ぐには、以下のベストプラクティスを実装すべきです:

- ファイルの暗号化(GPGなど): CSV、JSON、Excel、Parquetのような機微ファイルは転送する前に常に、GPG(GNU Privacy Guard)のように確立された暗号化標準で暗号化しましょう。これによって、許可されたユーザーや適切な複合化キーを持つプロセスのみがデータにアクセスできるようにし、不慮の公開のリスクを劇的に削減できます。
- セキュアなプロトコル: セキュアでないFTPやHTTPではなく、HTTPS、SFTP、SCPのようなセキュアな転送プロトコルを使いましょう。これらのプロトコルは、転送時におけるビルトインのデータ暗号化を提供するので、盗聴や不正アクセスを防ぎます。
- 適切なアクセスコントロール: ファイルシステム、クラウドストレージ、DBFSにおける機微ファイルに対する厳密なロールベースの権限とアクセスコントロールを実装しましょう。アクセスを必要とするユーザーのみがデータセットの読み込み、ダウンロード、処理をできるようにしましょう。
- 自動クリーンアップ: 処理の後に機微なファイルをセキュアに削除、アーカイブする自動プロセスをセットアップしましょう。ストレージロケーション(クラウドストレージ、DBFSなど)に不必要なファイルコピーを残さないようにしましょう。
- メールでデータを送らないようにしましょう: 機微なPIIを送信するためにメールの使用を禁じている厳密なポリシーでコミュニケーションしましょう。明確な指示と、セキュアな代替手段(制限されたクラウドストレージへのリンクやセキュアなデータ転送ポータルなど)を提供しましょう。

# 15. スクリプトで処理するためにメールで受け取ったファイルを手動で保存する

**間違い:** 何人かの従業員は、メールで受け取ったファイルをダウンロードし、Databricksノートブックやスクリプトで処理するために個別にストレージロケーション(共有フォルダーやクラウドストレージ)にアップロードしています。この手動のプロセスは遅れや間違い、データの紛失を引き起こし、ワークフローの効率性を低下させます。

**修正方法:** Power AutomateとDatabricksボリュームを組み合わせて自動化しましょう:

- 添付ファイルを持つ受信メールを自動で検知するためにPower Automateをセットアップします。
- 自動で添付ファイルを直接Databricksのボリューム(Databricksにおける新たなビルトインのファイルストレージ)に保存します。
- Databricksノートブックは効率的かつ直接的にボリュームのファイルにアクセスでき、シンプルかつセキュアな処理を確実にします。
- ボリュームのストレージに対するDatabricksワークグループの適切な権限を設定するようにします。

# これらの間違いのいずれかをご自身で認識しましたか？

これらの高度なDatabricksの間違いのいずれかを犯していることに気付いたのであれば、基本に立ち返ることには異議がると言えます。基本に対する理解に自信を持てるかを確認するために、以前の記事[11 Common Databricks Mistakes Beginners Make: Best Practices for Data Management and Coding](https://medium.com/@protmaks/11-common-databricks-mistakes-beginners-make-best-practices-for-data-management-and-coding-e3c843bad2b0)([翻訳](https://qiita.com/taka_yayoi/items/ab94f2ec1409beb4a125))をチェックしてみてください。

[Mediumにおける私のブログ記事](https://medium.com/@protmaks)をサブスクライブして、これらの高等な洞察や最先端のプラクティスを見逃さないでください！

### はじめてのDatabricks

[はじめてのDatabricks](https://qiita.com/taka_yayoi/items/8dc72d083edb879a5e5d)

### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)