TableStoreがさまざまなシナリオで地域間の災害耐性を実装する方法

この記事では、**Table Store**がインクリメンタルなデータ同期を介して、さまざまなシナリオで地域をまたいだ災害耐性を実装する方法について説明します。

著者：宜勝

前回は、Alibaba Cloud [Table Store]()が高い信頼性と可用性をどのように実装しているかを見てみました。今回の記事では、Table Storeがどのようにして地域をまたいだ災害耐性を実装するのかを説明します。

ディザスタートレランスと高可用性の概念は多少重複していますが、それらのアプリケーションシナリオや関連する技術体系には多くの違いがあります。そのため、この記事では、災害耐性について別途記述します。ディザスタートレランスを実装することで、クラスタの高可用性をベースにセキュリティを強化し、稀ではあるがクリティカルな障害を防ぐことができます。Table Storeがどのようにして高い信頼性と高可用性を確保しているかを理解するために、まず高可用性についての前回の記事をお読みになることをお勧めします。



まず、背景知識と関連するシナリオ、そしてデータベースの災害耐性を実装するための2つの重要な機能であるデータ同期とスイッチングについて説明します。次に、Table Storeがこれらの機能をどのように実装しているか、また、これらの機能を使用してどのようにサービス化を実装しているかを説明し、ユーザーが簡単かつ柔軟に災害耐性シナリオを設定したり、より高い可用性を提供したり、リモートマルチアクティブメカニズムを使用して異なる地域のエンドユーザーのためにレイテンシを最適化したりすることができるようにします。

#Table Storeとは
Table Storeは、アリババ社が開発した分散型NoSQLデータベースで、アリババ社で長年使用されています。多くの耐災害性シナリオや関連する経験が組み込まれています。この記事では、分散型 NoSQL システムを使用してディザスター トレランスを実装する方法と、それに沿った私たちの教訓や経験についての見解も紹介しています。

#災害耐性の実装方法とシナリオ
災害耐性と高可用性は異なる問題に対処しますが、災害耐性はシステムの可用性を向上させます。災害耐性は通常、IDC の電源/ネットワーク停止、地震、火災、人為的なソフトウェアやハードウェアの使用不能など、まれではありますが深刻な障害に対処します。これらの障害は、実際には多くの高可用性設計の能力範囲を超えています。

災害耐性には2つの重要な指標があります。RTOとRPOです。RTOは、災害後にビジネスプロセスが復旧しなければならない時間の目標期間です。RPOは、大規模な障害によってデータが失われる可能性のある最大の目標期間です。今日、多くの企業は非常に高い可用性の要件を持っています。RTO は通常 1～2 分未満で、RPO は可能な限り小さく（通常は秒単位、金融シナリオでは RPO はゼロ）する必要があります。RTO と RPO の両方の要件が保証できない場合は、データの一貫性と可用性の間で合理的なトレードオフを見つけることをお勧めします。

災害耐性は耐障害性と似ています。つまり、自然災害や人為的な故障によるサービスの中断を防ぐために、1 つまたは 2 つのコピーのスタンバイデータとコンピューティングリソースを異なる地域に分散させておくことです。従来の災害耐性の方法のほとんどはコールドバックアップを使用しています。しかし、コールドバックアップはRPOやRTOを提供しますが、もはや現在のビジネス要件を満たしておらず、信頼性に欠けています。

そのため、今日の災害耐性設計では、ホットバックアップとホットスイッチングを採用しており、2つの方法で実装することができます。

1、分散システムを使用し、複数のデータコピーを異なる地域に分散させて、災害耐性を実装します。分散システムは一般的に、データコピー間の整合性を維持するためにpaxosのような整合性アルゴリズムを適用します。したがって、この方法ではRPOがゼロになる可能性があります。特定のデータセンターや地域で障害が発生した場合、クラスタの大部分がまだ機能していれば、影響を受けたサービスは障害から自動的に回復することができます。これはフェイルオーバーのように動作します。

2、2つ（またはそれ以上）の別々のシステムを使用し、これらのシステム間の同期を確立し、システム障害が発生した場合には別の機能を持つシステムに切り替えます。このモデルでは、2つのシステムは互いに独立しており、データを同期させるだけで、2つのシステムのいずれかがほぼ一貫したデータを持つことが保証されます。データ同期は通常非同期であるため、実際の障害が発生した場合、RPOは完全にゼロではなく、少量のデータが失われる可能性があることを意味します。また、このアーキテクチャには2つのアクセスモデルがあります。1つは、1つのシステムのみがデイリーアクセスのためにアクティブで、もう1つはスタンバイシステムとして動作するモデルです。もう1つのモデルでは、両方のシステムがトラフィックの一部を共有し、双方向のデータ同期を行います。障害が発生した場合、障害が発生したシステムのトラフィックはもう一方の機能システムに切り替えられます。簡単に言えば、第1のモデルではアクティブスタンバイ方式、第2のモデルではアクティブアクティブアクティブ方式を採用しています。


#分散システムにおける複数のデータコピーに基づく災害耐性の実装
これは、上で説明した最初の方法に対応しています：1つの分散システムを使用し、異なる地域に複数のデータコピーを分散させて災害耐性を実装します。ここでは、Table Storeを例に、この災害耐性を実装する方法と適用可能なシナリオを説明します。

下図はTable Storeのアーキテクチャ図です。Table Storeのサービス層の下にはPanguと呼ばれる分散ストレージシステムがあり、データの信頼性を確保するために複数のコピーと強力な整合性を提供しています。Panguは、異なる可用性ゾーンに複数のコピーを分散させることができます。具体的には、3つの異なるアベイラビリティゾーンに3つのコピーを配布しました。各アベイラビリティゾーンには、Panguのマスターとチャンクサーバ、Table Storeのフロントエンドとバックエンドのロールを配置しています。論理的には、3つのアベイラビリティゾーンにまたがるシステム全体がクラスターであることに変わりはありません。各アベイラビリティゾーンで障害が発生しても、自動フェイルオーバーによりサービスに影響はありません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/b3bbffc5-2e0b-9637-b59a-e6b45024bc40.png)


このモードは、3つのアベイラビリティゾーンを1つの市にまとめてパブリッククラウド上で利用できるようにするというものです。このモードは、3つのアベイラビリティゾーンのうちの1つで発生した障害を許容することができます。しかし、都市全体で発生した障害には対応できません。それは、3 つのコピーが都市をまたいで、またはより大きな地域ではなく、同じ都市に分散されているからです。なぜ 3 つのコピーが同じ都市に分散しているのでしょうか？一つには、3 つのコピーは強力な一貫性を保証するためのものです。あまりにも距離が離れすぎると、データ書き込みのためのネットワーク遅延が増加し、最終的にはパフォーマンスの大幅な低下を引き起こします。これは別の製品形態であり、この記事の範囲外になります。

#複数のシステム間のデータ同期と切り替えによる災害耐性の実装
これは、前に説明したように、2つ（またはそれ以上）の異なるシステムを使用して、データの同期と切り替えによって災害耐性を実装するという2つ目の災害耐性の方法です。この方法は、アクティブ・スタンバイ・モデルとアクティブ・アクティブ／マルチ・アクティブ・モデルに分けることができます。アクティブ・スタンバイ・モデルの例としては、同一都市内のデュアル・クラスターと2つの地域にまたがる3つのデータセンター、アクティブ・アクティブ／マルチ・アクティブ・モデルの例としては、地域をまたがるアクティブ・アクティブ・メカニズムと地域をまたがるマルチ・アクティブ・メカニズム（単位）があります。

###シナリオ 1: アクティブスタンバイモデル
ここでは、テーブルストアのアクティブスタンバイモデルを例にして、全体の処理を説明します。



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/e547ed89-d883-e237-f607-c8f158ee3cc3.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/cb5a1d97-10df-4ad2-3359-cb59a07e8ea1.png)

前述のプロセスで示したように、この災害耐性計画で最も重要な2つのステップは、データ同期とスイッチングです。2つのクラスタを初期設定するプロセスでは、データ同期には完全同期とリアルタイム増分同期が含まれます。切替後、待機クラスタはサービスの提供を開始し、アクティブクラスタが回復するまで同期関係を再確立するのを待ち、最終的にアクティブクラスタに切り替わるようにします。

このステップでのデータ同期は非同期であることに注意してください。データはアクティブなクラスタに書き込まれた直後にクライアントに返されます。この時点では、そのデータは待機クラスタに同期されていません。非同期同期化により、データの整合性に問題が生じる可能性があります。したがって、このデータの不整合によってビジネスに潜在的な影響があるかどうかを特定し、その影響に対する対策を準備しておく必要があります。

具体的には、障害発生時にスイッチングが発生した際に、データの一部がまだ待機クラスタに同期されていないと仮定します。

1、(以前の)アクティブクラスタには、切り替え前に書き込まれたすべてのデータと、切り替え前にスタンバイクラスタに同期されていなかったデータが保持されています。
2、スイッチ前に同期化されなかったデータに加えて、新しいアクティブ クラスタ（スタンバイ クラスタ）には、そこに書き込まれたすべてのデータが保持されます。

元のアクティブ クラスタが回復すると、以下のオプションが利用可能になります。

1、待機クラスタ内のデータを使用して、アクティブクラスタをベースに待機クラスタを再構築する。つまり、待機クラスタ内のデータを元にフルデータを再度同期してから、リアルタイムのインクリメンタル同期を行うということです。この場合、同期化されていないアクティブクラスタ内のデータは消去されて見えなくなります。
2、一般的に、アクティブクラスタの障害が発生しても、テーブルデータが失われることはありません。そのため、アクティブクラスタにスイッチバックした後に、スタンバイクラスタに書き込まれたデータをインクリメンタルに同期させるしかありません。この場合、同期する必要があるのはインクリメンタルなデータ（サイズが比較的小さい）だけなので、迅速にアクティブ-スタンバイ関係を再確立することができます。アクティブなクラスタがスイッチバックされると、スタンバイクラスタに同期されていなかったデータが再び表示されるようになるか、スタンバイクラスタ内の更新されたデータで上書きされます（同じ行にある場合）。

3、同期していないデータをアクティブクラスタから待機クラスタに取得し、待機クラスタに追加したり、サービス関連の処理を行ったりして、インクリメンタル同期を行います。これは第2の選択肢の最適化であり、矛盾問題を解決することができます。

次に、スイッチングについて簡単に説明します。スイッチングの目的は、アプリケーション層が故障したシステムにアクセスし続けるのではなく、待機システムにアクセスするようにすることです。そのため、アプリケーション層とサーバ側の間には、別のシステムが利用されるように、切り替えに気づくポイントが必要です。以下のような方法が考えられます（参考までに）。

1、ユーザはインスタンスドメインを利用してTable Storeサービスにアクセスするため、サーバ側でインスタンスドメインのcnameレコードを変更して待機クラスタを指すようにすることができます。この方法は、「同一都市内のデュアルクラスタ」プランにのみ適しています。アクティブ・インスタンスとスタンバイ・インスタンスの名前は同じですが、バックエンド・クラスタはアクティブ・スタンバイ・メカニズムを使用します。
2、アプリケーション層は、独自のコードでプロキシ層を追加します。このプロキシレイヤーは内部に「スイッチ」を持ち、アクティブシステムとスタンバイシステムの両方への接続をサポートします。「スイッチ」がオンになると、もう一方のシステムに自動的にアクセスします。この場合、アクティブなインスタンスとスタンバイのインスタンスは別のものでも大丈夫です。アプリケーション層は、アクティブインスタンスとスタンバイインスタンスにそれぞれ設定を用意します。
3、2番目の方法と同様に、アクセス設定を動的に変更するために、いくつかの設定プッシュミドルウェアを使用することができます。

###シナリオ2: アクティブ/マルチアクティブモデル
次の図は、アクティブ/アクティブ/マルチアクティブのシナリオでの手順を示しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/dec656c3-694e-59bb-8772-09e7b1a75292.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/17c8744e-f5d9-e87f-664f-a423ee7220ac.png)


では、アクティブ・アクティブ・モデルの例を見て、アクティブ・スタンバイ・モデルとの違いを説明します。

1、アクティブ・アクティブ・モデルでは、両方のサービスがアクセスを受け付けます。具体的には、上図の華北2と華東1のTable Storeインスタンスはどちらも読み書きアクセスを許可していますが、アクティブ・スタンバイ・モデルではスタンバイ・インスタンスへのアクセスは許可されていません。
2、アクティブアクティブモデルではデータ同期は双方向ですが、アクティブスタンバイモデルではデータ同期は一方向です。

マルチアクティブモデルは、アクティブアクティブモデルに似ていますが、センターとユニットの概念が含まれています。地域横断的なマルチアクティブ・アーキテクチャは、ユニット化アーキテクチャとも呼ばれます。ユニットに書き込まれたデータはセンターに同期され、センターはそのユニット内のデータを他のユニットに同期させて、すべてのユニットとセンターが統合されたデータを持つようにします。

アクティブアクティブ／マルチアクティブモデルでは、複数のノードが同じデータを書き込むとデータの不整合が発生するため、ビジネス層はレコードを1つのノードでのみ変更できるように制限しなければなりません。ビジネス層の観点からは、これは、あるユーザーやデバイスに関する情報を特定のノードでしか変更できないことを意味する場合があります。サービスがエンドユーザーを対象としている場合、ユニット化されたアーキテクチャは、特に一部のグローバルサービスにおいて、待ち時間を短縮し、エンドユーザーの体験を最適化することができます。

もう一つの考慮点は、周期的なデータ同期を避けることです。そうしないと、データは円を描くように流れ、1つのレコードが各ノードで連続的に同期されることになります。周期的なレプリケーションは、データがどのノードに書き込まれたかを識別する情報をデータに添付することで回避することができます。データが既にノードに書き込まれていると識別された場合、同期は停止します。

アクティブ/アクティブ/マルチアクティブモードは、非常に柔軟なスイッチングをサポートします。例えば、エンドユーザーサービスのセットがあるとします。ビジネス層はエンドユーザーがアクセスできるユニットを制御するので、ビジネス層はルールを変更して、あるノードにアクセスしているユーザーを別のノードに切り替えることができます。なお、サービスについては、非同期データ同期によるデータの不整合の問題を考慮しなければならないことに注意してください。通常、データ同期のRPOは秒単位またはサブ秒単位です。サービスがデータの書き込みを制限したり、スイッチング中にデータ同期を監視したりすれば、非障害シナリオでデータの不整合を回避することができます。また、サービスは、データの不整合の問題を許容できるか、何らかの方法で修正できるかを検討する必要があります。

#Table Storeがインクリメンタルデータ同期をどのように実装するか

上記の災害耐性シナリオから、インクリメンタルデータ同期化が災害耐性計画を構築する上で重要であることがわかります。このセクションでは、Table Store がインクリメンタルデータ同期をどのように実装しているかに焦点を当てます。インクリメンタルデータ同期に加えて、テーブルメタ同期、フルデータ同期、スイッチ関連の機能など、包括的な災害耐性計画を構築するためには他にも多くの機能が必要です。これらの機能は非常に複雑なので、このセクションでは取り上げません。

リアルタイムで増分的なデータベース同期は、通常レプリケーションと呼ばれています。レプリケーションの前提条件は、2つのデータベースのセットが同じ変更を順番に適用した場合、最終的な結果が同じであることです。例えば、MySQLのbinlogは、アクティブなデータベースからスタンバイデータベースに同じ変更を順番に適用する同期を行います。Table Storeでのレプリケーションも同様の方法を採用しています。

まず、Table Storeの書き込みプロセスを見てみましょう。Table Storeでは、下図のようにログ構造化されたマージツリーのレイアウトを採用しています（図はインターネットから入手したものです）。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/6ef33727-bdac-aab4-13eb-c130d1a6238e.png)


図中のWrite-ahead logはcommitlogとも呼ばれています。データの更新は、最初にコミットログに書き込まれて永続化され、次にメモリ内のMemTableに書き込まれ、定期的に新しいデータファイルにフラッシュされます。バックエンドは定期的にデータファイルを大きなデータファイルに圧縮し、ジャンクデータをクリーンアップします。

Table Store の各テーブルシャードには個別のコミットログがあり、書き込まれたデータの永続性を確保するために、変更された内容が順番に追加されます。ノードが障害に遭遇し、MemTable が新しいデータファイルにフラッシュされていない場合、フェイルオーバーが発生し、シャードが別のノードにロードされます。この時点では、コミットログの一部を再生するだけでMemTableを回復することができ、書き込まれたデータの損失を避けることができます。



コミットログは、シャードへの(特定の)変更を順番に記録するREDOログです。書き込み中の未決定の値（自動インクリメント列の値やカスタマイズされていないタイムスタンプなど）は、コミットログの中で決定論的な値になります。Table Store でのレプリケーションは、コミットログを再生することで実装されます。スタンドアロンのデータベースと比較すると、Table Storeは非常に複雑です。一つには、Table Store のテーブルには多くのシャードがあり、それぞれが個別のコミットログを持っています。また、シャードは分割やマージも可能で、シャードの構造は有向非周期グラフです。さらに、大規模な分散型NoSQLストレージシステムであるTable Storeは、1秒間に数GBのデータが書き込まれる可能性のある多くのテーブルを持つことができます。そのため、データ同期モジュールも分散させる必要があります。

現在、レプリケーションはTableStoreサービス側のテーブルワーカーモジュールとして機能しています。レプリケーションが有効になっている各テーブル・シャードに対して、テーブル・ワーカーのこのモジュールは、コミットログと同じ順番で、新しく書き込まれたシャード・データをターゲット・エンドに送信します。その後、このモジュールはまた、フェイルオーバーを目的としたチェックポイントを記録し、そのシャードが分割およびマージされた後に新しいシャードのレプリケーション構成を生成し、その他のレプリケーション関連のアクションを実行します。このモジュールは、レプリケーショントラフィックの制御、RPOインジケータの監視、その他の操作を行うためにも使用されます。

#Table Storeでのストリーム。インクリメンタルデータ同期のサービス化

上述したように、特定のシナリオでディザスタートレランスを実装するためには、インクリメンタルデータの同期が鍵となります。実際、インクリメンタルデータのリアルタイムETL、分析のためのMaxCompute/Sparkのオフラインインポート、全文検索を提供するElasticSearchのリアルタイムインポートなど、様々なシナリオでインクリメンタルデータの役割が示されています。次の図は、Table Storeがさまざまなコンピューティングエコロジーシステムにどのように接続されているかを示しています。インクリメンタルデータトンネルが重要な役割を果たしています。一方で、インクリメンタルデータの同期を別途利用できるようにするために、Stream機能を開発し、テーブルからインクリメンタルデータを読み込むためのStream APIのセットを提供しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/759de6d6-cf0a-e81c-4d88-15867abecae8.png)

一方で、レプリケーション機能をシステム内部から分離したいという要望もあります。現在、レプリケーションモジュールはテーブルワーカーの内部にあり、テーブルワーカー内の同期チェックポイントの管理や幅広いデータ同期ロジックの処理など、多くの操作を担当しています。このモジュールは他のシステム機能と高度に結合されているため、多くの災害耐性シナリオやカスタマイズされたニーズに対応するのに十分な柔軟性がありません。一方、Stream機能は公開されています。そこで私たちは最終的にStreamに基づいたレプリケーションを実装することを決め、開発を開始しました。

Streamをベースにレプリケーションを実装することで、一方ではレプリケーションモジュールをシステム内部から分離してマイクロサービス化を実現し、他のモジュールから切り離すことができます。他方では、この一連のレプリケーションモジュールは、サービスをベースにして、ユーザーに柔軟なカスタマイズオプションを提供するデータプラットフォームとして機能することができます。この時点では、レプリケーションモジュールは、我々が提供するlibに基づいて、ユーザ自身がレプリケーションを実装したり、Function Computeを使用してサーバレスレプリケーションを開発したりすることを可能にしています。



#まとめ
この記事では、Table Storeの災害耐性シナリオの経験と実践に基づいて、さまざまなシナリオにおける災害耐性の実装方法と、Table Storeの災害耐性シナリオの最も重要な機能であるインクリメンタルデータの同期化について説明しました。また、この記事では、Table StoreのStream機能と、Streamに基づいた災害耐性とインクリメンタルデータ同期のサービス化についても簡単に説明しました。


*本ブログは英語版からの翻訳です。オリジナルは[こちら](https://www.alibabacloud.com/blog/how-table-store-implements-cross-region-disaster-tolerance_594659?spm=a2c65.11461544.0.0.23e753559GvF6A)からご確認いただけます。一部機械翻訳を使用しております。翻訳の間違いがありましたら、ご指摘いただけると幸いです。*

*アリババクラウドは日本に２つのデータセンターを有し、世界で60を超えるアベラビリティーゾーンを有するアジア太平洋地域No.1(2019ガートナー)のクラウドインフラ事業者です。
アリババクラウドの詳細は、こちらからご覧ください。
[アリババクラウドジャパン公式ページ](https://us.alibabacloud.com/)*