Sync Gateway機能解説：同期〜モバイル以外のクライアントとの共存

[Couchbase Mobileアプリケーション開発へのロードマップ](https://qiita.com/yoshiyuki_kono/items/6a5bbad1b02196a25417)もご覧ください。

## はじめに

Couchbase Mobileスタック（Couchbase Lite, Sync Gateway, Couchbase Server）を純粋に、モバイル/エッジデータプラットフォームとして利用するだけでなく、同時に、Couchbase Serverを、WEBアプリケーションや、REST APIのバックエンドデータベースとして利用し、共通のデータ（サービス）を様々な形態でユーザーに対して、提供することが考えられます。

以下にイメージを記します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176567/d8c43dfe-872a-f09e-5c22-b24e320c0e34.png)

この場合、Couchbase Serverに対して直接（SDKなどで）行われたデータ登録・変更を、Sync Gateway/Couchbase Liteと同期するために、考慮しなければならないことがあります。それは、Couchbase Mobileは、Couchbase Serverを単体で利用している場合には必要ない、同期のためのデータをCouchbase Serverで管理するからです。

#### 共有バケットアクセス

Couchbase ServerのSDKアプリケーション、N1QLクエリ、Sync　Gateway、およびCouchbase Liteアプリケーションが同じバケットに対して同時に読み取りと書き込みを行えるようにするメカニズムを**共有バケットアクセス**と呼びます。

Sync Gateway構成ファイルのプロパティ`$dbname.enable_shared_bucket_access`の設定により、有効化します。


#### インポート処理

Sync　GatewayがSync　Gateway以外のデータの変更を認識し、それらの変更を複製するために必要なモバイルメタデータを取得するメカニズムを**インポート処理**(Import Processing)と呼びます。

## 共有バケットアクセス


### ドキュメント
共有バケットアクセスを有効にすると、Couchbase Serverドキュメントを直接（N1QLまたはSDKを使用して）挿入することも、SyncGatewayのパブリックREST　APIを使用して挿入することもできます。

Sync Gatewayは、データをCouchbase Serverバケットに直接読み書きするSDKまたはN1QLアプリケーションからメタデータを抽象化することにより、必要なメタデータを作成します。Couchbase Server XATTRを使用して、そのメタデータを外部ドキュメントフラグメントに保存します。

REST APIには、次の動作変更も含まれます。

- パージ:  `/{db}/_purge`は、ドキュメントとそれに関連する拡張属性を削除します
- 更新:  `put/{db}/{docid}`は、アクティブなリビジョンを破棄します

### ブロブとアタッチメント

Sync GatewayのRESTAPIの`/{db}/{docid}/{attachment}`エンドポイントを使用して、添付ファイルとBLOBデータを管理します。Couchbase Server SDKを使用してこれを直接行うことはできません。

#### Couchbase　Liteアプリ

Couchbase Liteアプリは、BLOBと添付ファイルをシームレスに処理します。

#### REST API
添付ファイルには、Sync GatewayのREST APIの`/{tkn-db}/{doc}/{attachment}`エンドポイントを使用してアクセスできます。

Couchbase　Liteアプリ以外のクライアントにとって標準的な方法は、SDKを使用してドキュメントを作成し、添付ファイルの追加/更新（`/{db}/{docid}/{attachment}`）エンドポイントを使用して添付ファイルを関連付けることです。

下記のブログ投稿で実際的な例を見ることができます。

https://blog.couchbase.com/store-sync-binary-data-attachments-blobs-couchbase-mobile

### トゥームストーンリビジョン

バケット共有を有効にする場合、トゥームストーンリビジョンに注意する必要があります。トゥームストーンリビジョンは、サーバーのメタデータパージ間隔に基づいてパージされます。

トゥームストーンがクライアントと確実に同期されるようにするには、予想されるレプリケーション頻度に基づいてサーバーのメタデータパージ間隔を設定する必要があります。
設定は、プロパティ`$dbname.enable_shared_bucket_access`を通じて実施します。


### メタデータへのアクセス

モバイルメタデータはドキュメントには保持されず、ドキュメントのシステム拡張属性（XATTR）に保持されます。

N1QLクエリ言語は、拡張属性（XATTRS）をクエリする機能をサポートしています。ため、ドキュメントの同期メタデータをサポートしています。例1を参照してください。

例1.XATTRS-bsed同期メタデータのクエリ

```SQL
SELECT meta().xattrs._sync FROM `travel-sample` WHERE meta().id = "mydocId"
```

ただし、同期メタデータはSync Gatewayによって内部的に維持され、その構造はいつでも変更され得ます。そのため、これをアプリケーションのビジネスロジックのために使用することは禁じられています。

## 構成ファイル設定

次の例を参照してください。

```JSON
{
    "databases": {
        "db": {
            "bucket": "my-bucket",
            "username": "my-user",
            "password": "my-password",
            "server": "http://localhost:8091",
            "enable_shared_bucket_access": true, 
            "import_docs": true 
        }
    }
}
```

### 共有バケットアクセス有効化

共有バケットアクセスはオプトイン機能です。Sync　Gatewayクラスター全体を停止せずに有効にできます。

`enable_shared_bucket_access`プロパティが、バケット共有を有効にするために使用されます。構成に参加しているすべてのSync Gatewayノードに存在する必要があります。


### インポート処理

`import_docs`プロパティは、Sync Gatewayノードが（排他的に）インポート処理に参加することを指定するために使用されます。

インポートプロセスは、モバイルコンバージェンスの重要な部分です。これは、Sync GatewayがSync Gateway以外のデータの変更を認識し、変更を複製するために必要なモバイルメタデータを取得するための手段です。


Sync Gateway以外の変更は、インポートの対象になります。ドキュメントには最初にSync関数が適用され、読み取りセキュリティとルーティングが計算されますが、次の違いがあります。

- インポートは、Sync Gateway Admin APIを介して行われる書き込みと同様に、同期機能の管理者ユーザーコンテキストで処理されます。これは、同期関数のrequireAccess、requireUserおよびrequireRole呼び出しがノーオペレーションとして扱われることを意味します。

- インポート中oldDocはnil、同期機能が実行されるときです。

- `import_filter`プロパティを使用してフィルター関数を指定できます。これにより、特定のドキュメントのみがインポートされます。

- Import +ログキーを 使用して、ログ内のインポート処理の問題のトラブルシューティングを行います。

`enabled_shared_bucket_access`が`true`に設定されている場合にのみ`import_docs`が有効になることに注意してください。


#### エディションによる違い

エンタープライズエディションでは、`import_docs`のデフォルトは`true`であり、デフォルトでは、クラスタ内のすべてのノードは、インポート処理に参加することを意味します。ノードを除外するには、`"import_docs": false`に設定します。
コミュニティエディションでは、デフォルトは`false`であり、明示的に、`true`に設定する必要があります。
詳細は、以下を参照してください。

https://docs.couchbase.com/sync-gateway/current/sync-with-couchbase-server.html#configuration


#### 高可用性
エンタープライズエディションでは、インポート処理作業は、インポート処理を有効に設定されたすべてのSync Gatewayノードにわたって分散されます。これによって、インポート処理の高可用性が実現されます。

コミュニティエディションでは、インポート処理を関与するノード間で分散する機能が存在しません。高可用性のためにはスタンバイノードを用いて、外部的に制御する必要があります。

#### ワークロードの分離
`import_docs`が`false`に設定されている場合、ノードはインポートプロセスに参加しません。この構成は、ワークロードの分離に寄与します。つまり、インポートノードをクライアントからのリクエストを処理するノードから分離することができます。高い書き込みスループットが想定される場合、ワークロードの分離が望ましい場合があります。

次の図は、クライアント接続を処理する2つの同期ゲートウェイノード（`"import_docs": false`）とインポート処理を共有する2つのノード（`"import_docs": true`）のアーキテクチャの例を示しています。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176567/b188a799-eed5-6f1b-1299-721a2cc02149.png)



#### 構成プロパティリファレンス

- `$dbname.enable_shared_bucket_access`を使用して、特定のデータベースのコンバージェンスを有効にします。

- $`dbname.import_docs`を使用して、特定のSync Gatewayノードにドキュメントをインポートする役割を与えます。

- `$dbname.import_filter`を使用して、モバイルクライアントに通知するドキュメントを選択します。


## 関連情報

https://docs.couchbase.com/sync-gateway/current/sync-using-app.html



https://docs.couchbase.com/sync-gateway/current/sync-with-couchbase-server.html