CouchbaseにおけるHA/DR対応 (Java SDK注解)

# はじめに

本記事では、CouchbaseにおけるHA/DR対応（の一側面）について記します。

ここでは、HA/DR用に待機クラスターがホットスタンバイされているケースについて解説します。

Couchbaseは、分散システム/クラスターとして、ノード/サーバ障害レベルのHAに対応していますが、ここでは、（いわば、さらに進んだHA要件への対応として）上記のケースを対象とした機能について解説します。

# クロスデータセンターレプリケーション (XDCR)

Couchbaseのクロスデータセンターレプリケーション (XDCR）は、データのレプリケーション（複製）のための機能ですが、名称に則してみれば、そのターゲットは、異なるデータセンター間で、ということを示しているものの、ソフトウェアの実際の機能としては、複数クラスター間でのデータの複製を行うものになります。同一データセンター内の複数クラスター間であっても当然利用できますが、一般に異なるトポロジー間で複製を実現する方がハードルが高いことから、この様な名称が（価値訴求のために）採用されていると考えることができるかと思います。

XDCRは、複製するデータのフィルタリング等、ユーザがカスタマイズすることのできる様々な機能を持っており、必ずしもここで扱うHA/DRの要件に特化したものではありませんが、ここでは、複数のクラスター間のレプリケーションがサポートされていることが理解されれば十分です。

複数のクラスター間のデータが同期されていることは、DR実現の第一歩ですが、それだけではまだシステムのHAは実現されているとはいえません。この時まず考えられるのは、バーチャルIPなどを利用して、（アプリケーションの外部で）クラスター間のスイッチを実現することです。Couchbaseはこの様な外部の機構を用いずに、つまり、そのことが要求するダウンタイムを被らずに、HAを可能にしています。

# マルチクラスターアウェアネス (MCA)

CouchbaseのJava SDKは、マルチクラスターアウェアネス (MCA)と命名された機能を備えています。これは、クライアント（典型的には、アプリケーションサーバー）がCouchbase Serverをバックエンドのデータプラットフォームとして用いる際に、複数のクラスターによるDRを実現しながら、アプリケーションからCouchbaseへの透過的なアクセスを実現します。


# Java SDK注解

ここからは、MCAを活用したJavaプログラミングについて、紹介していきます。これは、完全な実装のためのガイドを意図したものではなく、実際のコードを示すことで、MCAにより何が実現できるかの具体的なイメージを持つことが、（特に開発者の方々にとって）容易となることを期待してのものです。

まず、MCAを利用する場合、下記の様なクラスをインポートすることになります。クラス名をざっと見ただけでも、どの様な範囲がカバーされているか概観を得ることができるのではないかと思います。

```java
import com.couchbase.client.mc.ClusterSpec;
import com.couchbase.client.mc.MultiClusterClient;
import com.couchbase.client.mc.BucketFacade;
import com.couchbase.client.mc.coordination.Coordinator;
import com.couchbase.client.mc.coordination.Coordinators;
import com.couchbase.client.mc.coordination.IsolatedCoordinator;
import com.couchbase.client.mc.coordination.TopologyBehavior;
import com.couchbase.client.mc.detection.FailureDetectorFactory;
import com.couchbase.client.mc.detection.NodeHealthFailureDetector;
import com.couchbase.client.mc.detection.DisjunctionFailureDetectorFactory;
import com.couchbase.client.mc.detection.FailureDetectorFactories;
import com.couchbase.client.mc.detection.TrafficMonitoringFailureDetector;
```

## コーディネーター

はじめに、要件に応じたオプションを指定し、`Coordinator`を構築します。

```java
Coordinator coordinator = Coordinators.isolated(newIsolatedCoordinator.Options()
  .clusterSpecs(specs)
  .activeEntries(specs.size())
  .failoverNumNodes(2)
  .gracePeriod(TIMEOUT)
  .topologyBehavior(TopologyBehavior.WRAP_AT_END)
  .serviceTypes(serviceTypes)
);
```

## 障害検出

次に、`FailureDetector`を構築します（ファクトリーパターンで設計されています）。

```java

TrafficMonitoringFailureDetector.Options trafficOptions = TrafficMonitoringFailureDetector.options()
  .maxFailedOperations(5)
  .failureInterval(60);
 
FailureDetectorFactory<TrafficMonitoringFailureDetector> traffic = FailureDetectorFactories.trafficMonitoring(coordinator,trafficOptions);
 
NodeHealthFailureDetector.Options healthOptions = NodeHealthFailureDetector.options();
 
FailureDetectorFactory<NodeHealthFailureDetector> health = FailureDetectorFactories.nodeHealth(coordinator,healthOptions);
 
DisjunctionFailureDetectorFactory detector = FailureDetectorFactories.disjunction(traffic,health);

```

## データベースの抽象化（ファサード）

`MultiClusterClient`が、複数のクラスター/データベースへのアクセスを抽象化します。
クライアント構築の際に先に構築したコーディネーターとデテクターを利用しているのが見て取れます。
バケット/データベースはファサードパターンで設計されています。

```java
MultiClusterClient client = new MultiClusterClient(coordinator, detector);
client.authenticate(options.stringValueOf("id"), options.stringValueOf("password"));
bucket = new BucketFacade(client.openBucket(bucketName, null), TIMEOUT, TimeUnit.MILLISECONDS);
```

# XDCR + MCA利用時の留意点

XDCRは、一方向（uni-directional)と双方向（bi-directional）の両方のレプリケーションをサポートしています。
XDCRとMCAの組み合わせを利用する際には、レプリケーションの設定は双方向である必要があります。これは、DR環境への切り倒しも、（復旧時についても当然ながら考慮に入れ）双方向である必要があることを考えると当然のことですが、レプリケーション（複製）について、一方向のイメージを持たれている向きもいるかもしれないと考え、注記しておきます。

# 最後に

さて、ここまで読まれて次の様な疑問を持たれた方がいるかもしれません。そもそも、アプリケーションサーバ自体、災害の影響を受けないわけではなく、（典型的には）データベースと同じデータセンターに置かれているとしたら、データベースだけを災害から保護したところで意味をなさないのでは？この疑問自体は、（その想定している状況を前提として）的を得たものです。その様な状況では、ここで紹介した様な複雑な機能を利用して、アプリケーションからCouchbaseへの接続を実現する必要はなく、極めてシンプルな方法でアクセスすれば十分です（当然、それは可能です）。そして、アプリケーションサーバーに対して(F5 BIG-IPなどの)マルチトポロジーで構成されたフロントエンドで、災害時を想定した、トラフィックのコントロールを行うことになるでしょう。この場合も、（ステートフルなデータ層として）CouchbaseのXDCR機能を活用することができます。
一方で、現在のシステムを取り巻く状況においては、クラウドの利用や、クラウドとデータセンターとのハイブリッドでの利用も、珍しくなくなっています。そうしたヘテロジニアスな環境下において、ここで紹介したより進んだ機能（XDCR＋MCA）の有用性は間違いないものと思われます。

## 次のステップ：監視（モニタリング）

システム運用のまた別の側面として、監視（モニタリング）についても、Couchbaseは、（他システム連携含め）様々な機能を提供しています。こちらについては、いずれ別途整理してみたいと考えています。

# 参考情報

[Intro to Couchbase HA/DR: Java Multi-Cluster Aware Client](https://blog.couchbase.com/couchbase-high-availability-disaster-recovery-java-multi-cluster-aware-client/)