Databricksにおけるディザスターリカバリーの概要と戦略及び評価

[Disaster Recovery on Databricks \- The Databricks Blog](https://databricks.com/blog/2022/04/25/disaster-recovery-overview-strategies-and-assessment.html)の翻訳です。

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

# Databricksにおけるディザスターリカバリー パート1

多くのアプリケーションとシステムに対する全体的な医療チームとして動作する[ディザスターリカバリー(DR)](https://en.wikipedia.org/wiki/Disaster_recovery)戦略を作成する際、優先度、機能、制限、コストに対する評価が必要となります。

この種の議論のスコープをさまざまなテクノロジー、ベンダー、クラウドプロバイダー、オンプレミスのシステムなどに拡大したい誘惑がありますが、ここでは[Databricksワークスペース](https://qiita.com/taka_yayoi/items/f2aedc25516c43767f7f)に関わるDRにのみフォーカスします。 [AWS](https://docs.aws.amazon.com/whitepapers/latest/disaster-recovery-workloads-on-aws/disaster-recovery-workloads-on-aws.html)、[Azure](https://azure.microsoft.com/en-us/solutions/backup-and-disaster-recovery/#overview)、[GCP](https://cloud.google.com/architecture/disaster-recovery)のクラウドインフラストラクチャ固有のDRの情報は、すでに他のソースからアクセスできるようになっています。

さらに、どのようにDRが[ビジネス継続性(BC)](https://en.wikipedia.org/wiki/Business_continuity_planning)にフィットするのか、[高可用性(HA)](https://en.wikipedia.org/wiki/High_availability)との関係は本シリーズのスコープ外です。HAサービスのみを活用するだけでは、包括的なDRソリューションとしては不十分であると言うだけで十分です。

これは、Databricksで実行する重要なワークロードとユースケースに対して適切なDR戦略と実装を決定することにフォーカスするシリーズの第一弾です。いくつかの一般的なDRのコンセクトを議論しますが、読者の皆様においては、DRの用語、ワークフロー、ソリューションを実装するためのハイレベルのステップに関して、最初に見る概要としてDatabricksのドキュメント([AWS](https://docs.databricks.com/administration-guide/disaster-recovery.html) | [Azure](https://docs.microsoft.com/en-us/azure/databricks/administration-guide/disaster-recovery) | [GCP](https://docs.gcp.databricks.com/administration-guide/disaster-recovery.html))をご覧になることをお勧めします。

# Databricksワークスペースにおけるディザスターリカバリーの計画

## 損失限界の定義

Databricksで実行するユースケースやワークロードに対するDR戦略を実装するに際して、許容可能な回復ポイント目標(RPO)、回復時間目標(RTO)を決定することが基本的なステップとなります。ここでRPOはデータが失われるであろう最大のターゲットの期間であり、RTOはビジネスプロスを回復しなくてはいけないターゲットの期間とサービスレベルとなります。RTOとRPOは例えばユースケースやワークロードレベルというような特定の文脈に基づいて決定される必要があります。これらは、災害イベントでのデータ損失の限界を定義し、適切なDR戦略につながり、DRの実装がどれだけ迅速に災害イベントから復旧すべきかを決定します。

## DatabricksオブジェクトのRPO

Databricksのオブジェクトは[CI/CD](https://en.wikipedia.org/wiki/CI/CD)やDRサイトへの複製のために用いる[Terraform \(TF\)](https://www.terraform.io/)のような[Infrastructure as Code \(IaC\)](https://en.wikipedia.org/wiki/Infrastructure_as_code)で管理されるべきです。Databricks Repos([AWS](https://docs.databricks.com/repos.html) | [Azure](https://docs.microsoft.com/en-us/azure/databricks/repos) | [GCP](https://docs.gcp.databricks.com/repos.html))は、GitHubのような設定されたgitプロバイダーから一つ以上のワークスペースにソースコードをプルすることを促進する[git](https://en.wikipedia.org/wiki/Git)連携を提供します。

CI/CDパイプラインの最後でバージョン管理されたオブジェクトをDRサイトに公開するために、Databricks REST API([AWS](https://docs.databricks.com/dev-tools/api/index.html) | [Azure](https://docs.microsoft.com/en-us/azure/databricks/dev-tools/api/) | [GCP](https://docs.gcp.databricks.com/dev-tools/api/index.html))を利用できますが、このアプローチには2つの制限があります。第一に、REST APIではターゲットの状態を追跡できず、全てのオペレーションが安全かつ効率的であるようにするためには追加の工数が必要となります。第二に、必要な全てのAPI呼び出しをオーケストレートし、実行するには追加のフレームワークが必要となります。

Terraformを用いることで、バージョン管理とターゲットのワークスペースに必要な変更を適用によって、手動の状態追跡の必要がなくなり、宣言型の方法でユーザーの代わりに必要な変更を加えることができるようになります。TFの更なるメリットとして、DRソリューションに必要となるほぼ全てのDatabricksとクラウドリソースとやり取りできる[Databricks Terraform Provider](https://registry.terraform.io/providers/databrickslabs/databricks/latest/docs)があります。最後になりますが、DatabricksはHashicorpの[公式なパートナー](https://www.hashicorp.com/partners/tech/databricks#all)であり、Terraformでマルチクラウドのデプロイメントをサポートすることができます。このシリーズの一部として、DR実装をデモンストレーションするためにDatabricks Terraform Providerを使用します。[DB\-Sync](https://github.com/databrickslabs/databricks-sync)は、非TFユーザーでも複製管理を容易に行えるようにするDatabricks Terraform Provider向けのコマンドラインツールです。

DatabricksオブジェクトのRPOは、オブジェクトの状態の最新スナップショットと災害イベントの間の時間差となります。システムのRPOは全てのオブジェクトのRPOの最大値として決定されます。

## データベースとテーブルのRPO

いかなるワークロードにおいても複数のストレージシステムが求められることがあります。[Apache Spark](https://spark.apache.org/)が[JDBC](https://spark.apache.org/docs/3.2.0/sql-data-sources-jdbc.html#jdbc-to-other-databases)経由でアクセスする[OLAP](https://en.wikipedia.org/wiki/Online_analytical_processing)や[OLTP](https://en.wikipedia.org/wiki/Online_transaction_processing)システムのようなデータソースでは、クラウドプロバイダーによって提供されるDRのためのオプションがあります。これらのシステムは DBRソリューションのスコープ内にあると考えるべきですが、それぞれのクラウドプロバイダーがバックアップと複製に関して異なるアプローチを取っているため、ここでは詳細を議論しません。それよりも、ここでは[オブジェクトストレージ](https://en.wikipedia.org/wiki/Object_storage)のファイルの上で作成される論理的データベースとテーブルにフォーカスします。

それぞれのDatabricksワークスペースはオブジェクトストレージに対する抽象化である[Databricks File System \(DBFS\)](https://qiita.com/taka_yayoi/items/897264c486e179d72247)を使用しています。重要かつプロダクsy本のソースコードやデータ資産をDBFSに格納すると言う使い方は推奨しません。DBFSルートを除き、DBFSにマウントされたオブジェクトストレージには、全てのユーザーが読み書きのアクセス権を持っています。さらに、DBFSルートはクラウドネイティブの複製サービスをサポートしておらず、データのエクスポートには[DeltaのDEEP CLONE](https://databricks.com/blog/2020/09/15/easily-clone-your-delta-lake-for-testing-sharing-and-ml-reproducibility.html)、スケジュールされたSparkジョブ、[DBFS CLI](https://docs.databricks.com/dev-tools/cli/dbfs-cli.html)にのみ頼らざるを得ません。

DBFSにオブジェクトストレージをマウント([AWS](https://qiita.com/taka_yayoi/items/a26a1fb49c0e217ad10b#dbfs%E3%82%92%E9%80%9A%E3%81%98%E3%81%9Fs3%E3%83%90%E3%82%B1%E3%83%83%E3%83%88%E3%81%B8%E3%81%AE%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9) | [Azure](https://docs.microsoft.com/en-us/azure/databricks/data/data-sources/azure/azure-storage#--mount-azure-blob-storage-containers-to-dbfs) | [GCP](https://docs.gcp.databricks.com/data/data-sources/google/gcs.html#access-a-gcs-bucket-through-dbfs))することができ、これによって外部ストレージに対するポインターを作成することができます。マウントはデータがDBFSローカルに同期されることを防ぎますが、マウントポイントはDRサイトにある別のおジェクトストレージに指定される必要があります。マウントは管理が難しく、間違ったストレージを指定しまう可能性があり、DRソリューションの一部として追加の自動化や検証が必要となります。外部テーブルを通じて直接オブジェクトストレージにアクセスすることで、複雑性とDRの障害地点の両方を削減することができます。

Apache Sparkを用いることで、ユーザーは**マネージド**あるいは**アンマネージド**のテーブルを作成することができます([AWS](https://qiita.com/taka_yayoi/items/e7f6982dfbee7fc84894#%E3%83%9E%E3%83%8D%E3%83%BC%E3%82%B8%E3%83%89%E3%82%A2%E3%83%B3%E3%83%9E%E3%83%8D%E3%83%BC%E3%82%B8%E3%83%89%E3%83%86%E3%83%BC%E3%83%96%E3%83%AB) | [Azure](https://docs.microsoft.com/en-us/azure/databricks/data/tables#--managed-and-unmanaged-tables) | [GCP](https://docs.gcp.databricks.com/data/tables.html#managed-and-unmanaged-tables))。メタストアはマネージドテーブルのデータを管理し、マネージドテーブルのデフォルトの格納場所はDBFSの`/user/hive/warehouse`となります。マネージドテーブルがDRを必要とするワークロードで使用されている場合、DBFSからデータは移行されるべきであり、デフォルトの格納場所を避けるために格納場所を指定された[新規データベース](https://spark.apache.org/docs/latest/sql-ref-syntax-ddl-create-database.html)を使うべきです。

アンマネージドテーブルは、[CREATE TABLE](https://spark.apache.org/docs/latest/sql-ref-syntax-ddl-create-table-datasource.html)文で`LOCATION`パラメーターを指定することで作成されます。これによって、テーブルは指定された場所に保存され、メタストアからテーブルが削除されてもデータは削除されません。SparkSQLあるいはSparkSessionの`table`メソッド([Python](https://spark.apache.org/docs/3.2.0/api/python/reference/api/pyspark.sql.SparkSession.table.html?highlight=table) | [Scala](https://spark.apache.org/docs/3.2.0/api/scala/org/apache/spark/sql/DataFrameReader.html#table(tableName:String):org.apache.spark.sql.DataFrame))を用いてメタストアに定義されたテーブルにソースコードがアクセスする場合、アンマネージドテーブルにおいても依然としてメタストアはDRで必要なコンポーネントとなります。

Amazon S3のようなオブジェクトストレージを直接利用することで、必要に応じて地理的に冗長性のあるストレージを活用でき、DBFSに関する懸念を回避することができます。

## データの複製

DRにおける推奨ストレージフォーマットは[Delta Lake](https://delta.io/)です。Parquetは`CONVERT TO DELTA`コマンドを用いて[容易にDeltaフォーマットに変換](https://docs.delta.io/latest/delta-utility.html#convert-a-parquet-table-to-a-delta-table)することができます。Delta LakeのACID保証は事実上、フェイルオーバーおよびDRサイトからのフェイルバックにおけるデータ破損のリスクを排除します。さらに、すべてのDeltaテーブルを服せうするためにディープクローンを用いるべきです。不要なデータ転送コストを避けるインクリメンタルなアップデート機能を提供し、アベイラビリティゾーン、リージョンベースの地理的冗長レプリケーション(GRR)サービスでは利用できない追加のビルトインのデータ一貫性に対する保証を提供します。他のGRRのデメリットは、レプリケーション一方向であり、DRサイトからプライマリーサイトにフェイルバックする際には追加のプロセスが必要となると言うことです。一方、ディープクローンはプライマリーサイト、DRサイトの両方で双方向に動作します。

以下の図では、DeltaテーブルをGRRに用いることで生じる初期の欠点を示しています。
![](https://databricks.com/wp-content/uploads/2022/04/db-132-blog-img-1.png)

GRRとDeltaテーブルを活用するためには、DRサイトにおけるDeltaテーブルのバージョン([AWS](https://qiita.com/taka_yayoi/items/0a109082037246163218) | [Azure](https://docs.microsoft.com/en-us/azure/databricks/delta/versioning) | [GCP](https://docs.gcp.databricks.com/delta/versioning.html))の完全性を保証するために追加のプロセスを作成しなくてはなりません。

上の図と[DRとのレプリケーションをシンプルにするためにDeltaのDEEP CLONE](https://qiita.com/taka_yayoi/items/3222478ef8b0eee49eaf)を用いた場合を比較してみると、ディープクローンは最新のDeltaテーブル全体が複製されることを保証するので、ファイルの順序を保証し、複製を行うタイミングに対して更なるコントロールを行えるようになります。
![](https://databricks.com/wp-content/uploads/2022/04/db-132-blog-img-2.png)

このブログシリーズの中で、プライマリーからセカンダリーサイトにDeltaテーブルを複製するために、DeltaのDEEP CLONEを使用します。

Deltaに変換できないファイルはGRRを頼りにする必要があります。この場合、GRRとDeltaのDEEP CLONEの両方が実行することによる競合を避けるためにDeltaファイルとは別の場所にこれらのファイルを格納すべきです。DRサイトにおけるプロセスは、GRRを使用する際、ビジネスに対してデータセットの完全な可用性を保証するように配備される必要があります。しかし、これはディープクローンを用いる際には不要です。

オブジェクトストアのデータに対するRPOは、Deltaのディープクローンを用いて最後にいつ複製が取られたのか、あるいは、地理的冗長ストレージを用いた際にクラウドプロバイダーによって提供されるSLAに依存します。

## メタストアの複製

Databricksデプロイメントではいくつかのメタストアの選択肢が提供されており、それぞれに関して簡単に検討していきます。

デフォルトのメタストアからスタートします。Databricksのデプロイメントでは、テーブルメタデータを永続化するために全てのクラスターとSQLエンドポイントからアクセスできる内部のUnity Catalog([AWS](https://docs.databricks.com/data-governance/unity-catalog/create-metastore.html) | [Azure](https://docs.microsoft.com/en-us/azure/databricks/data-governance/unity-catalog/create-metastore) | [GCP](https://docs.gcp.databricks.com/data-governance/unity-catalog/create-metastore.html))、あるいはHiveメタストア([AWS](https://docs.databricks.com/data/metastores/external-hive-metastore.html) | [Azure](https://docs.microsoft.com/en-us/azure/databricks/data/metastores/external-hive-metastore) | [GCP](https://docs.gcp.databricks.com/data/metastores/external-hive-metastore.html))を利用できます。内部のHiveメタストアからテーブルとテーブルACLをエクスポートするためにはカスタムスクリプトが必要となります。これはDatabricksワークスペースのRPOと組み合わされ、マネージドテーブルに必要なメタデータのRPOは、これらの内部メタストアのテーブルとテーブルACLが最後にエクスポートされた時間と災害イベントの間の時間差であることを意味します。

クラスターは既存の外部メタストア([AWS](https://docs.databricks.com/data/metastores/external-hive-metastore.html#external-apache-hive-metastore) | [Azure](https://docs.microsoft.com/en-us/azure/databricks/data/metastores/external-hive-metastore) | [GCP](https://docs.gcp.databricks.com/data/metastores/external-hive-metastore.html#external-apache-hive-metastore))に接続することができます。外部メタストアを用いることで、背後のデータベースインスタンス向けのクラウドプロバイダーのサービスを活用することで、追加の複製オプションを手に入れることができます。例えば、メタストアを複製するためにAmazon AuroraのようなクラウドネイティブのデータベースやマルチAZデータベースインスタンスを活用することができます。このオプションは、Databricks on AWS、Azure Databricks、Databricks on GCPで利用することができます。RPOは、手動あるいは自動化されたエクスポートプロセスがない場合には、クラウドプロバイダーサービスによって提供されるSLAに依存します。

メタストアとして[Glueカタログを用いる機能](https://docs.databricks.com/data/metastores/aws-glue-metastore.html#use-aws-glue-data-catalog-as-the-metastore-for-databricks-runtime)は、AWSにおけるDatabricksデプロイメント固有のものです。GlueカタログのRPOはAWSで提供されるSLAあるいは[複製ユーティリティ](https://github.com/aws-samples/aws-glue-data-catalog-replication-utility)に依存します。

## Databricksにおける復旧時間目標(RTO)

プライマリーサイトのDatabricksワークスペースが利用できない時点から、DRサイトのワークスペースがクリティカルなアクティビティをサポートできる(事前に定義された)レベルのオペレーションに到達した時点までの時間でRTOを計測することができます。

一般的には、データは既に複製されていると仮定し、RTOに達する前には、ワークロード/ユースケースに必要なソースコードと依存関係が利用可能な状態となり、ライブなクラスター、SQLエンドポイント、(ファイルに直接アクセスするのではなく)データベースとテーブルのデータにアクセスする際にはメタストアが必要となります。

RTOは、ワークロード、ユースケースに対して選択されたDR戦略と実装に依存します。

# ディザスターリカバリー戦略

ディザスターリカバリー戦略は広く2つのカテゴリーにブレークダウンされます。**アクティブ/パッシブ**と**アクティブ/アクティブ**です。アクティブ/パッシブ実装においては、プライマリーサイトは通常のオペレーションに使用され、アクティブであり続けます。しかし、DR(セカンダリー)サイトには、プライマリーに昇格するために必要な固有の実装に基づき、事前に計画されたステップが必要となります。一方アクティブ/アクティブ戦略では、両方のサイトが常に完全に稼働状態であり続けます。
![](https://databricks.com/wp-content/uploads/2022/04/db-132-blog-img-3.png)

## アクティブ/パッシブ戦略

- **バックアップ&リストア**はRTOの観点では非常に効率的でないと考えられています。プライマリーサイトでバックアップが作成され、DRサイトにコピーされます。地域間のフェイルオーバーにおいては、データパックアップからのリカバリーの実行に加え、インフラストラクチャもリストアされる必要があります。オブジェクトストアの場合、データもまたプライマリーサイトから複製される必要があります。このシナリオにおいては、DRサイトではインフラストラクチャとDatabricksオブジェクトに必要な全ての設定は利用できますが、配備はされません。ファイルベースのテーブルはバックフィルされる必要があり、他のデータソースは最新のバックアップからリストアされる必要があります。ビッグデータの観点では、RTOが遅延する可能性があります。
- **パイロットライト(Pilot Light)** 実装においては、データストアとデータベースは定義されたRTOに基づいて最新に保たれ、サービスのワークロードで利用できるようになっています。その他のインフラストラクチャの要素は、通常は[Infrastructure as Code \(IaC\)](https://en.wikipedia.org/wiki/Infrastructure_as_code)ツールで定義されますが、デプロイはされません。

   パイロットライトとバックアップ&リストアの大きな違いは、読み書きがパスベースではな い場合にはメタストアを含むデータが即時に利用できるかどうかです。一般的にコストがほとんどかからないいくつかのインフラストラクチャは配備されます。Databricksワークスペースにおいては、必要なDatabricksオブジェクト(ソースコード、設定、インスタンスプロファイル、サービスプリンシパルなど)が配備された状態でワークスペースと必要なクラウドインフラストラクチャは配備されますが、クラスターやSQLエンドポイントは作成されないことを意味します。

- **ウォームスタンバイ**は最小構成のライブのデプロイメントに加えて、ライブのデータストアとデータベースを維持します。DRサイトでは全てのプロダクションワークロードをを捌けるようにスケールアップされる必要があります。パイロットライトを構築することに加え、ウォームスタンバイでは追加のオブジェクトがデプロイされます。例えば、後段のアプリケーションにデータを提供する際のRTOを削減するために、特定のクラスターやSQLエンドポイントが作成されますが起動はされません。また、これは、DRソリューションとDRサイトの健康状態における自信の度合いを増加させる継続テストを促進します。削除を回避するため、あるいはテストのため、さらには非常に厳しいRTOがある極端なケースにおいては、クラスターとSQLエンドポイントは定期的に起動されます。

## アクティブ/アクティブ戦略

マルチサイトのDR実装においては、プライマリーとDRサイトの両方が完全にデプロイされ稼働状態となります。災害イベントの際には、新規のリクエストをプライマリーサイトではなく、シンプルにDRサイトにルーティングする必要があるだけです。マルチサイトはもっとも効率的なRTOを提供しますが、非常に高価で複雑となります。

プライマリーワークスペースとDRワークスペース間の、データ(テーブルやビューなど)、ユーザープロファイル、クラスター定義、ジョブ定義、ソースコード、ライブラリ、initスクリプト、その他のアーティファクトの同期によって複雑性が引き起こされます。さらに問題を複雑にしているのは、さまざまなスクリプトやコードに含まれるハードコードされた接続文字列、パーソナルアクセストークン(PATトークン)、APIコールのためのURIです。

## 適切なDR戦略の策定

![](https://databricks.com/wp-content/uploads/2022/04/db-132-blog-img-4.png)

分析システムはさらに重要となっており、障害はビジネスに多大なるインパクトを及ぼし、大きなコストを発生させ、潜在的な障害地点は環境がより複雑になり、互いに薄陽つくことで定常的に増加しています。結果として、DRが必要かどうかを決定するためにユースケースやワークロードに対するインパクト分析の実行や、そのような実装に対してチームの準備が整っていることを確認することは重要なアクティビティとなっています。

ここで列挙した戦略にはトレードオフが存在します。最終的には、RPOとRTOはワークロードやユースケースに対してどちらの戦略を選択すべきかを教えてくれます。そして、いかなる特定のDR戦略を実装、維持するためのコストに対して、災害イベントによる財務的、非財務的なダメージを用いて重みづけを行うべきです。推定した見積もりに基づき、災害が引き起こしたダメージに対してタイムリーな方法でサービス継続を保証するDR戦略を選択し、実装すべきです。

# はじめてみる

Databricksのレイクハウスプラットフォームを用いたアプリケーションにDRソリューションが必要かどうかを判断することで、潜在的な損失を回避し、プラットフォームの利用者の信頼を保つことができます。適切なDR戦略と実装は、災害時において重要なアプリケーションと機能を再開するために必要なサービスを提供しつつも、コストが潜在的な(財務的、非財務的な)損失を上回らないことを確実にします。以下のアセスメントでは、適切なDR戦略と実装を判断するためにインパクト、準備状況の分析を実行するためのスタート地点とガイドを提供しています。

[DRインパクトアセスメントのダウンロード](https://databricks.com/wp-content/uploads/2022/04/disaster-recovery-impact-assesment.pdf)

### Databricks 無料トライアル

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