複製とは?
データは、同じ IBM® Cloudant® for IBM Cloud® アカウント内のあるデータベースから別のデータベースへコピーしたり、あるアカウントから別のアカウントにコピーしたり、あるデータ・センターから別のデータ・センターにコピーしたりすることができます。
同期(IBM Cloudant Sync) または PouchDBを使用して、 IBM Cloudant アカウントとモバイル・デバイスとの間でデータを複製することもできます。 複製は、「単発」操作または継続的操作として、1 方向または両方向で実行でき、パラメーターを使用して細かく調整することができます。
IBM Cloudant の複製プロトコルは、他のさまざまなデータベースやライブラリーと互換性があるため、Internet of Things (IoT) アプリケーションおよびモバイル・アプリケーションに最適です。
IBM Cloudant は、HTTP API を使用する分散型 JSON データ・ストアです。 IBM Cloudant は、複数のクラウド上、またはユーザーのサーバー・ラック内でサービスとして実行することができます。 文書はデータベースに保管されており、IBM Cloudant が多くのノードにわたってそのデータを入れるためのシャードを作成するサイズだけ増加できます。 複製は、ソース・データベースからターゲット・データベースへのデータのコピーです。 ソース・データベースとターゲット・データベースは、同じ IBM Cloudant アカウント上にある必要はなく、同じデータ・センター内にある必要すらありません。
複製は、ソース内の各文書の最新バージョンが宛先データベースに転送されると完了します。 転送には、新しい文書、既存の文書の更新、および削除が含まれます。 複製後は、文書の最新バージョンのみが残ります。 古いバージョンは省略されます。
ソース・データベースは、最後の既知の位置から部分複製を再開できるようにするために書き込まれるチェックポイント・データ以外は未変更のままになります。 宛先データベース内の既存のデータはすべて残されます。
ダッシュボードを使用した複製の開始方法
IBM Cloudant ダッシュボードには、複製をトリガーするための便利なユーザー・インターフェースが提供されています。 IBM Cloudant ダッシュボードでReplicationをクリックし、Start Replicationをクリックします。 次の複製フォームに入力します。
セキュリティー上の目的で、IBM Cloudant チームは、複製ジョブのためにアカウント・レベルの資格情報ではなく、IAM API キーまたは IBM Cloudant レガシー認証 API キー を使用することをお勧めしています。 詳しくは、アクセスの管理または従来の 認証および許可の資料を参照してください。
このフォームを使用して、 ソース・データベースとターゲット・データベースを定義し、
Start Replicationをクリックします。
各複製タスクの状況は、Replicationをクリックすることで確認できます。 各ジョブは、進行するにしたがって
RunningからCompletedに状態が変化します。 次の画面キャプチャは「Completed 状態を示している。
複数の異なる IBM Cloudant アカウントにわたる複製の実行方法
以下の例に示すように、複製のソースとターゲットは IBM Cloudant データベースの URL です。
複製のソース URL とターゲット URL を定義する以下の例を参照してください。
{
"source": {
"url": "https://myfirstaccount.cloudant.com/a",
"auth": {
"basic": {
"username": "$USERNAME",
"password": "$PASSWORD"
}
}
},
"target": {
"url": "https://mysecondaccount.cloudant.com/b",
"auth": {
"basic": {
"username": "$USERNAME",
"password": "$PASSWORD"
}
}
}
}
ソースとターゲットは同じアカウント上にある必要はありません。 ソース・データベースとターゲット・データベースの名前は一致する必要はありません。 ユーザーは、ソースとターゲットの両方へのアクセスを許可されている必要があり、ターゲットへの書き込み権限を持っている必要があります。
複製はソースで実行されるのか、それとも宛先で実行されるのか?
複製は、ソース側からも宛先側からも開始できます。 この選択は、アカウント A がアカウント B にデータをプッシュしているのか、それともアカウント B がアカウント A からデータをプルしているのかをユーザーが決められることを意味します。 場合によっては、いずれの構成でも複製を実行できない可能性があります。例えば、あるアカウントがファイアウォールによって保護されている場合などです。 レプリケーションはHTTPSで行われるため、標準以外のポートを開く必要はない。 どちらのデバイスで複製を開始するかの決定は、ユーザーが行うことになります。
複製は変更リストにどのような影響を与えるか?
_changes エンドポイントを使用して、文書に対して行われた変更のリストを取得することができます。 しかし、IBM Cloudant データベースの分散の性質は、_changes のフィードによって提供される応答を、特定の日時後に発生した単純な変更リストにできないことを意味します。
CAP 定理 の説明では、以下のことが明確になっています。 IBM Cloudant は、「結果整合性」モデルを使用します。 このモデルは、ある文書について、データベースの 2 つの異なるレプリカに同時に要求を行うと、異なる結果になる可能性があることを意味します。 これは、データベース・コピーのいずれかがまだ複製の完了を待っている場合に発生することがあります。
最終的な 結果として、データベース・コピーはそれぞれの複製を完了するため、 文書に対するすべての変更はそれぞれのコピー内に存在します。
この「結果整合性」モデルには、変更リストに影響を与える以下の 2 つの特性があります。
- 文書に影響を与える変更は、ほぼ確実に、データベースの別々のコピーで、別々の時間に行われる。
- 変更が文書に影響を与える順序は、複製がいつ、どこから行われるかによって、データベースの別々のコピー間で異なる可能性がある。
最初の特性の結果、変更リストを要求する際、ある特定のポイント・イン・タイム後の変更のリストを要求することは無意味ということになります。 この理由は、変更リストが、異なる時間の文書更新によって作成された、異なるデータベース・コピーによって提供される可能性があるからです。 ただし、シーケンス ID を使用して指定される特定の変更後の変更リストを要求することは意味があります。
最初の特性の追加の結果として、変更リストの一致を得るために、以前の変更を「振り返る」必要がある場合があるというものがあります。 言い換えると、変更のリストを取得するには、複数のデータベース・コピーが一致する最新の変更から開始します。 データベース・コピー間の合意点は、以下の範囲内で識別されます。 IBM Cloudant 。データベース・コピー間の複製を同期化できるようにする チェックポイント メカニズムを使用します。
最後に、変更リストを表示する場合、後続の要求では異なる順序で表示されることがあります。 さまざまなデータベース・コピー間で文書がどのように変更されたかによって順序は異なります。 言い換えると、変更の初期リストは変更を報告する可能性があります A。
B の場合は、この順序で C となります。 しかし、それ以降の変更リストでは、 C 変更が報告される可能性があります。
A の場合は、この順序で B となります。 すべての変更はリストされますが、順序は異なります。 この違いが発生する理由は、複製中に受け取った変更のシーケンスが、2 つのデータベース・コピーで異なる場合があるためです。
変更リストにとって「結果整合性」は何を意味するか?
変更リストを要求すると、どのデータベース・コピーがリストを提供するかによって、受け取る応答が異なる場合があります。
since オプションによって、特定の更新シーケンス ID の後の変更のリストが取得されます。 リストには常にその更新後の変更が含まれますが、その更新より前の変更も含まれる場合があります。 この理由は、リスト要求に応答するデータベース・コピーが、すべてのレプリカと整合している変更をリストしていることを確実にする必要があるからです。 その整合性を実現するために、そのデータベース・コピーは、すべてのコピーが一致する時点から変更リストを開始する必要がある場合があります。
この時点は、チェックポイントを使用して識別されます。
したがって
_changes フィードを使用するアプリケーションは、「idempotent」でなければならない。
べきである。 べき等性とは、アプリケーションが同じデータを何度でも安全に受信できることを意味する、 そして、繰り返されるリクエストに対して、異なる順序で受け取ることができなければならない。
チェックポイント
複製プロセスは内部で、ソース・データベースと宛先データベースの両方に保管される「チェックポイント」文書に状態を書き込みます。 チェックポイントにより、複製タスクを最初から開始するのではなく、停止した場所から再開することが可能になります。 チェックポイントの作成は、以下を指定することによって防止できます。
"use_checkpoints": false オプション (複製を要求する場合)。 複製を最後の既知の位置から効率的に再開するには、機能をオンにしておくと有用です。
権限
文書を _replicator データベースに挿入するには管理アクセスが必要です。 ソース・パラメーターとターゲット・パラメーターに指定するログイン資格情報には、フル管理許可は必要ありません。 資格情報で以下のタスクが実行できれば十分です。
- 宛先の側に文書を書き込む。
- 両方の側にチェックポイント文書を書きこむ。
IBM Cloudant には、特別な _replicator ユーザー許可があります。 この許可は、チェックポイント文書の作成を許可しますが、データベースへの通常文書の作成は許可しません。 一般的に、以下を持つ API キーを作成します。
- ソース側の
_readerおよび_replicatorアクセス。 - 宛先側の
_readerおよび_writerアクセス。
API キーは、データベースごとを基本として IBM Cloudant ダッシュボード内に作成および構成することができます。
それらは、IBM Cloudant API を使用してプログラマチックに作成することもできます。
セキュリティー上の目的で、IBM Cloudant チームは、複製ジョブのためにアカウント・レベルの資格情報ではなく、IAM API キーまたは IBM Cloudant レガシー認証 API キー を使用することをお勧めしています。 詳しくは、アクセスの管理または従来の 認証および許可の資料を参照してください。
両方向の複製
データは、両方向複製または同期と呼ばれるプロセスで両方向にコピーすることができます。 この同期は、2 つの別々の複製プロセス (A から B にデータをコピーするプロセスと、B から A にデータをコピーするプロセス) をセットアップすることによって使用可能にします。 両方の複製プロセスは独立して実行され、データは両方行にシームレスに移動されます。
継続的複製について
これまでは、すべてのソース・データがターゲット・データベースに書き込まれると終了する単発複製のみを扱っています。 継続的複製では、データは継続的にフローします。 ソース・データベースに対するすべての後続変更が、リアルタイムでターゲット・データベースに転送されます。
連続レプリケーションは、IBM Cloudantでレプリケーションタスクを定義するときに「Make this replication continuous チェックボックスをクリックすることでトリガされます。ダッシュボード またはIBM CloudantAPIで'continuousフラグを設定することで起動します。APIで'code2'フラグを設定します。
両方向複製は、continuous フラグを設定することにより、1 方向または両方向で継続させることができます。
HTTP を使用して継続的複製を開始する例を以下に示します。
POST /_replicator HTTP/1.1
Content-Type: application/json
Host: $SERVICE_URL
Authorization: ...
連続レプリケーションを開始する例を以下に示す:
curl -X POST \
-H "Content-type: application/json" \
"$SERVICE_URL/_replicator" \
-d '{ "_id": "repldoc-example",
"continuous": true,
"create_target": true,
"source": { "url": "'"$SOURCE_SERVICE_URL/source"'" },
"target": {
"auth": { "iam": { "api_key": "'"$API_KEY"'" } },
"url": "'"$TARGET_SERVICE_URL/target"'"
}
}'
import com.ibm.cloud.cloudant.v1.Cloudant;
import com.ibm.cloud.cloudant.v1.model.DocumentResult;
import com.ibm.cloud.cloudant.v1.model.PutReplicationDocumentOptions;
import com.ibm.cloud.cloudant.v1.model.ReplicationDatabase;
import com.ibm.cloud.cloudant.v1.model.ReplicationDatabaseAuth;
import com.ibm.cloud.cloudant.v1.model.ReplicationDatabaseAuthIam;
import com.ibm.cloud.cloudant.v1.model.ReplicationDocument;
Cloudant service = Cloudant.newInstance();
ReplicationDatabase sourceDb = new ReplicationDatabase.Builder()
.url("<your-source-service-url>/source")
.build();
ReplicationDatabaseAuthIam targetAuthIam =
new ReplicationDatabaseAuthIam.Builder()
.apiKey("<your-iam-api-key>")
.build();
ReplicationDatabaseAuth targetAuth = new ReplicationDatabaseAuth.Builder()
.iam(targetAuthIam)
.build();
ReplicationDatabase targetDb = new ReplicationDatabase.Builder()
.auth(targetAuth)
.url("<your-target-service-url>/target")
.build();
ReplicationDocument replDocument = new ReplicationDocument();
replDocument.setSource(sourceDb);
replDocument.setTarget(targetDb);
replDocument.setContinuous(true);
PutReplicationDocumentOptions replicationDocumentOptions =
new PutReplicationDocumentOptions.Builder()
.docId("repldoc-example")
.replicationDocument(replDocument)
.build();
DocumentResult response =
service.putReplicationDocument(replicationDocumentOptions).execute()
.getResult();
System.out.println(response);
const { CloudantV1 } = require('@ibm-cloud/cloudant');
const service = CloudantV1.newInstance({});
const sourceDb: CloudantV1.ReplicationDatabase = {
url: '<your-source-service-url>/source'
};
const targetDb: CloudantV1.ReplicationDatabase = {
auth: {
iam: {
'api_key': '<your-iam-api-key>'
}
},
url: '<your-target-service-url>/target'
};
const replDocument: CloudantV1.ReplicationDocument = {
id: 'repldoc-example',
continuous: true,
create_target: true,
source: sourceDb,
target: targetDb
}
service.putReplicationDocument({
docId: 'repldoc-example',
replicationDocument: replDocument
}).then(response => {
console.log(response.result);
});
from ibmcloudant.cloudant_v1 import CloudantV1, ReplicationDocument, ReplicationDatabase, ReplicationDatabaseAuthIam, ReplicationDatabaseAuth
service = CloudantV1.new_instance()
source_db = ReplicationDatabase(
url='<your-source-service-url>/source'
)
target_auth_iam = ReplicationDatabaseAuthIam(
api_key='<your-iam-api-key>'
)
target_auth = ReplicationDatabaseAuth(
iam=target_auth_iam
)
target_db = ReplicationDatabase(
auth=target_auth,
url='<your-target-service-url>/target'
)
replication_document = ReplicationDocument(
id='repldoc-example',
continuous=True,
create_target=True,
source=source_db,
target=target_db
)
response = service.put_replication_document(
doc_id='repldoc-example',
replication_document=replication_document
).get_result()
print(response)
source, err := service.NewReplicationDatabase(
"<your-source-service-url>/source",
)
if err != nil {
panic(err)
}
target, err := service.NewReplicationDatabase(
"<your-target-service-url>/target",
)
if err != nil {
panic(err)
}
auth, err := service.NewReplicationDatabaseAuthIam(
"<your-iam-api-key>",
)
if err != nil {
panic(err)
}
target.Auth = &cloudantv1.ReplicationDatabaseAuth{Iam: auth}
replicationDoc, err := service.NewReplicationDocument(
source,
target,
)
if err != nil {
panic(err)
}
replicationDoc.Continuous = core.BoolPtr(true)
replicationDoc.CreateTarget = core.BoolPtr(true)
putReplicationDocumentOptions := service.NewPutReplicationDocumentOptions(
"repldoc-example",
replicationDoc,
)
documentResult, response, err := service.PutReplicationDocument(putReplicationDocumentOptions)
if err != nil {
panic(err)
}
b, _ := json.MarshalIndent(documentResult, "", " ")
fmt.Println(string(b))
前の Go の例では、以下のインポート・ブロックが必要です。
import (
"encoding/json"
"fmt"
"github.com/IBM/cloudant-go-sdk/cloudantv1"
)
すべての Go の例では、serviceオブジェクトを初期化する必要があります。 詳しくは、API 資料の認証セクションで例を参照してください。
継続的複製を定義する JSON 文書の例を以下に示します。
{
"_id": "weekly_continuous_backup",
"source": {
"url": "https://$SOURCE_SERVICE_DOMAIN/source",
"auth": {
"basic": {
"username": "$USERNAME",
"password": "$PASSWORD"
}
}
},
"target": {
"url": "https://$TARGET_SERVICE_DOMAIN/target",
"auth": {
"basic": {
"username": "$USERNAME",
"password": "$PASSWORD"
}
}
},
"continuous": true
}
その他の複製のユースケース
IBM Cloudant の複製プロトコルは、その他の、さまざまな実世界のアプリケーション用のデータベースおよびライブラリーとも互換性があります。
Apache CouchDB
Apache CouchDBは、オープンソースのデータベースです。 IBM Cloudantと通信することができます、 と通信することができ、最小限のセットアップを必要とします。 以下のアプリケーションが含まれています。
- バックアップ - IBM Cloudant から独自の CouchDB データベースにデータを複製し、アーカイブの目的で夜間にデータのスナップショットを取ります。 データを Amazon Glacierなどのバックアップ・サービスにデータを送る。
- ローカル・ファースト・データ収集 - ローカル Apache CouchDB に最初にデータに書き込み、次にそのデータを長期保管、集約、および分析のために IBM Cloudant に複製します。
PouchDB
PouchDBはオープンソースです、 ブラウザとIBM Cloudantの間で双方向にデータを複製できるブラウザ内データベースです。 クライアント・サイドの Web ブラウザーにデータを保管すると、Web アプリケーションはインターネット接続がなくても機能します。 PouchDB は、インターネット接続がある場合、変更されたすべてのデータを IBM Cloudant との間で同期化することができます。 クライアント・サイドからの複製のセットアップには、数行の JavaScript が必要です。
PouchDB を使用して複製を有効にする以下の JavaScript 例を参照してください。
var db = new PouchDB("myfirstdatabase");
var URL = "https://$USERNAME:$PASSWORD@$SERVICE_DOMAIN/my_database");
db.sync(URL, { live: true });
フィルターされた複製
あるデータベースから別のデータベースに複製する場合に、一部のデータを複製プロセス中に削除できると便利です。以下に例を示します。
- 削除された文書のすべてのトレースを削除して、ターゲット・データベースをソース・データベースより小さくする。
- 英国のデータをあるデータベースに、米国のデータを別のデータベースに格納するなど、データをより小さな塊に分ける。
複製のフィルター関数
IBM Cloudant のフィルター処理された複製により、戻り値を使用してデータベース内の各文書をフィルター処理するかどうかを決定する JavaScript 関数の定義が可能になります。 フィルター関数は、設計文書内に保管されます。
削除されない文書を複製するためのフィルター関数の例を以下に示します。
function(doc, req) {
if (doc._deleted) {
return false;
}
return true;
}
複製ジョブが開始されると、フィルター関数の名前が、保管されている設計文書と、フィルター関数の名前を組み合わせて指定されます。 また、
query_params 値も指定できます。 この値は、2 番目の (query) 引数の req フィールドでフィルター関数に渡されるプロパティーを含むオブジェクトです。
HTTP を使用してフィルターされた複製を開始する例を以下に示します。
POST /_replicator HTTP/1.1
Content-Type: application/json
Host: $SERVICE_URL
Authorization: ...
コマンド・ラインを使用してフィルターされた複製を開始する例を以下に示します。
curl -X POST \
-H "Content-type: application/json" \
"$SERVICE_URL/_replicator" \
-d @filtered-replication.json
import com.ibm.cloud.cloudant.v1.Cloudant;
import com.ibm.cloud.cloudant.v1.model.DocumentResult;
import com.ibm.cloud.cloudant.v1.model.PutReplicationDocumentOptions;
import com.ibm.cloud.cloudant.v1.model.ReplicationDatabase;
import com.ibm.cloud.cloudant.v1.model.ReplicationDatabaseAuth;
import com.ibm.cloud.cloudant.v1.model.ReplicationDatabaseAuthIam;
import com.ibm.cloud.cloudant.v1.model.ReplicationDocument;
Cloudant service = Cloudant.newInstance();
ReplicationDatabase sourceDb = new ReplicationDatabase.Builder()
.url("<your-source-service-url>/source")
.build();
ReplicationDatabaseAuthIam targetAuthIam =
new ReplicationDatabaseAuthIam.Builder()
.apiKey("<your-iam-api-key>")
.build();
ReplicationDatabaseAuth targetAuth = new ReplicationDatabaseAuth.Builder()
.iam(targetAuthIam)
.build();
ReplicationDatabase targetDb = new ReplicationDatabase.Builder()
.auth(targetAuth)
.url("<your-target-service-url>/target"))
.build();
ReplicationDocument replDocument = new ReplicationDocument();
replDocument.setSource(sourceDb);
replDocument.setTarget(targetDb);
replDocument.setFilter("mydesigndoc/myfilter");
Map queryParams = new HashMap<>();
queryParams.put("foo", "bar");
queryParams.put("baz", 5);
replDocument.setQueryParams(queryParams);
PutReplicationDocumentOptions replicationDocumentOptions =
new PutReplicationDocumentOptions.Builder()
.docId("repldoc-example")
.replicationDocument(replDocument)
.build();
DocumentResult response =
service.putReplicationDocument(replicationDocumentOptions).execute()
.getResult();
System.out.println(response);
const { CloudantV1 } = require('@ibm-cloud/cloudant');
const service = CloudantV1.newInstance({});
const sourceDb: CloudantV1.ReplicationDatabase = {
url: '<your-source-service-url>/source'
};
const targetDb: CloudantV1.ReplicationDatabase = {
auth: {
iam: {
'api_key': '<your-iam-api-key>'
}
},
url: '<your-target-service-url>/target'
};
const replDocument: CloudantV1.ReplicationDocument = {
id: 'repldoc-example',
filter: 'mydesigndoc/myfilter',
query_params: {'foo': 'bar', 'baz': 5},
source: sourceDb,
target: targetDb
}
service.putReplicationDocument({
docId: 'repldoc-example',
replicationDocument: replDocument
}).then(response => {
console.log(response.result);
});
from ibmcloudant.cloudant_v1 import CloudantV1, ReplicationDocument, ReplicationDatabase, ReplicationDatabaseAuthIam, ReplicationDatabaseAuth
service = CloudantV1.new_instance()
source_db = ReplicationDatabase(
url='<your-source-service-url>/source'
)
target_auth_iam = ReplicationDatabaseAuthIam(
api_key='<your-iam-api-key>'
)
target_auth = ReplicationDatabaseAuth(
iam=target_auth_iam
)
target_db = ReplicationDatabase(
auth=target_auth,
url='<your-target-service-url>/target'
)
replication_document = ReplicationDocument(
id='repldoc-example',
filter='mydesigndoc/myfilter',
query_params={'foo': 'bar', 'baz': 5},
source=source_db,
target=target_db
)
response = service.put_replication_document(
doc_id='repldoc-example',
replication_document=replication_document
).get_result()
print(response)
source, err := service.NewReplicationDatabase(
"<your-source-service-url>/source",
)
if err != nil {
panic(err)
}
target, err := service.NewReplicationDatabase(
"<your-target-service-url>/target",
)
if err != nil {
panic(err)
}
auth, err := service.NewReplicationDatabaseAuthIam(
"<your-iam-api-key>",
)
if err != nil {
panic(err)
}
target.Auth = &cloudantv1.ReplicationDatabaseAuth{Iam: auth}
replicationDoc, err := service.NewReplicationDocument(
source,
target,
)
if err != nil {
panic(err)
}
replicationDoc.Filter := "mydesigndoc/myfilter"
replicationDoc.QueryParams := map[string]interface{}{"foo": "bar", "baz": 5}
putReplicationDocumentOptions := service.NewPutReplicationDocumentOptions(
"repldoc-example",
replicationDoc,
)
documentResult, response, err := service.PutReplicationDocument(putReplicationDocumentOptions)
if err != nil {
panic(err)
}
b, _ := json.MarshalIndent(documentResult, "", " ")
fmt.Println(string(b))
前の Go の例では、以下のインポート・ブロックが必要です。
import (
"encoding/json"
"fmt"
"github.com/IBM/cloudant-go-sdk/cloudantv1"
"github.com/IBM/go-sdk-core/core"
)
すべての Go の例では、serviceオブジェクトを初期化する必要があります。 詳しくは、API 資料の認証セクションで例を参照してください。
フィルターされた複製を定義する JSON 文書の例を以下に示します。
{
"_id": "weekly_backup",
"source": {
"url": "https://$SOURCE_SERVICE_DOMAIN/source",
"auth": {
"basic": {
"username": "$USERNAME",
"password": "$PASSWORD"
}
}
},
"target": {
"url": "https://$TARGET_SERVICE_DOMAIN/target",
"auth": {
"basic": {
"username": "$USERNAME",
"password": "$PASSWORD"
}
}
},
"filter": "mydesigndoc/myfilter",
"query_params": {
"foo": "bar",
"baz": 5
}
}
変更フィード
IBM Cloudant は、_changes エンドポイントからの単一 HTTP フィードを使用してデータベースに影響を与える追加、編集、および削除を発行します。 このフィードは、アプリケーションがイベントをトリガーするために使用できます。 このフィードには、例に示すように、HTTP または curl を使用してアクセスできます。
feed=continuous オプションの使用は、ストリームが、データベース内のすべての文書の最新バージョンを取得するために必要なすべての変更を提供することを意味します。
詳しくは、 IBM Cloudant 変更フィードの FAQ の使用を参照してください。
HTTP を使用して変更フィードを照会する例を以下に示します。
GET /$DATABASE/_changes?feed=continuous HTTP/1.1
Host: $SERVICE_URL
Authorization: ...
コマンド・ラインを使用して変更フィードを照会する例を以下に示します。
curl "$SERVICE_URL/$DATABASE/_changes?feed=continuous"
変更は、1 つの変更につき 1 行を使用して記述されます。 各変更は、以下で構成されます。
- シーケンス番号 (
seq) を含むストリング。 - 変更された文書の ID を含むストリング。
- 変更の配列。
文書の本文自体を表示するには、curl コマンドに &include_docs=true を付加します。
各変更は、以下の (簡略) 例に示されたフォーマットを使用して記述されます。
以下の _changes フィードの例を参照してください。
{
"seq":"11-g1A...c1Q",
"id":"6f8ab9fa52c117eb76240daa1a55827f",
"changes":[
{
"rev":"1-619d7981d7027274a4b88810d318a7b1"
}
]
}
既知の位置からの変更フィードを結合するには、since 引数 を、開始したいシーケンス番号と共に渡します。
HTTP を使用し、since オプションを指定して、既知の位置の _changes フィードを結合する例 (簡略) を以下に示します。
GET /$DATABASE/_changes?feed=continuous&include_docs=true&since=11-g1A...c1Q HTTP/1.1
HOST: $SERVICE_URL
Authorization: ...
コマンド・ラインを使用し、since オプションを指定して、既知の位置の _changes フィードを結合する例 (簡略) を以下に示します。
curl "$SERVICE_URL/$DATABASE/_changes?feed=continuous&include_docs=true&since=11-g1A...c1Q"
現時点の変更フィードを再結合するには、since=now を設定します。
HTTP を使用し、since=now を指定して、現時点の _changes フィードを結合する例を以下に示します。
GET /$DATABASE/_changes?feed=continuous&include_docs=true&since=now HTTP/1.1
Host: $SERVICE_URL
Authorization: ...
コマンド・ラインを使用し、since=now を指定して、現時点の _changes フィードを結合する例を以下に示します。
curl "$SERVICE_URL/$DATABASE/_changes?feed=continuous&include_docs=true&since=now"
プログラマチックに _changes データにアクセスすることは簡単です。 例えば、変更を数行のコードでフォローするには、 IBM Cloudant API 資料 で SDK の例を参照してください。
ユース・ケースの例を以下にいくつか示します。
- アプリケーション内でアクションをトリガーするためにメッセージ・キューに項目を追加する。例えば、顧客 E メールの送信など。
- アクティビティーのリアルタイムのカウントを記録するためにメモリー内データベースを更新する。
- SQL データベースにデータをプッシュするためにテキスト・ファイルにデータを書きこむ。
変更フィードは、複製中のフィルター処理に似た手法を使用して、フィルター関数によりフィルター処理することができます。
HTTP を使用して変更フィードをフィルター操作する例を以下に示します。
GET /$DATABASE/_changes?feed=continuous&include_docs=true&since=now&filter=mydesigndoc/myfilter HTTP/1.1
Host: $SERVICE_URL
Authorization: ...
コマンド・ラインを使用して変更フィードをフィルター操作する例を以下に示します。
curl "$SERVICE_URL/$DATABASE/_changes?feed=continuous&include_docs=true&since=now&filter=mydesigndoc/myfilter"
_changes フィード内の文書の順序は常に同じではありません。 つまり、変更は、厳密な時間順序で現れない可能性があります。 この理由は、複数の IBM Cloudant ノードからデータが返され、結果整合性のルールが適用されるからです。
複製の落とし穴
正常に複製するには、文書のサイズとすべての添付ファイルのサイズの合計がターゲット・クラスターの最大要求サイズ未満でなければなりません。 例えば、最大 HTTP 要求サイズが 11 MB の場合、以下のシナリオが適用されます。
| 文書サイズ | 添付ファイルのサイズ | 合計サイズ | 複製するかどうか |
|---|---|---|---|
| 1MB | 2 MB の添付ファイル 5 個 | 11 MB | ある |
| 1MB | 10 MB の添付ファイル 1 個 | 11 MB | ある |
| 1MB | 1 MB の添付ファイル 100 個 | 101 MB | いいえ |
複製を使用する際は、いくつかの考慮事項が適用されます。
誤ったユーザー許可
データベース「a」からデータベース「b」に複製する際に複製を適切に進めるには、提供されている資格情報が以下の権限を持っている必要があります。
- データベース「a」の
_reader許可と_replicator許可。 - データベース「b」の
_writer許可。
APIキーはIBM Cloudantで生成されます。ダッシュボードまたは APIを通じて生成されます。 各キーには、特定の IBM Cloudant データベースに関連する個別の許可が与えられます。 IBM Cloudant は、複製の「読み取り」側にチェックポイント文書を書き込める必要があります。さもないと、状態は保存されず、複製を停止したところから再開できません。 状態が保存されないと、大規模なデータ・セットの複製を再開する時にパフォーマンス上の問題が発生する可能性があります。 この理由は、チェックポイントがないと、複製プロセスは毎回再開するたびに最初から再始動されるからです。
複製文書の競合
ユーザー許可を誤って設定した場合のもう 1 つの結果は、_replicator 文書が競合するというものです。
_replicator 文書は、複製プロセスの現行状態を記録します。 極端なケースでは、多くの未解決の競合を含んでいるために文書が巨大になることがあります。 そのような大きい文書は、使用可能なスペースの多くを使用し、余分なサーバー負荷の原因となります。
_replicator データベースのサイズは、以下のように GET 要求を /_replicator エンドポイントに送信して確認できます。
curl "$SERVICE_URL/_replicator"
import com.ibm.cloud.cloudant.v1.Cloudant;
import com.ibm.cloud.cloudant.v1.model.DatabaseInformation;
import com.ibm.cloud.cloudant.v1.model.GetDatabaseInformationOptions;
Cloudant service = Cloudant.newInstance();
GetDatabaseInformationOptions databaseInfoOptions =
new GetDatabaseInformationOptions.Builder()
.db("_replicator")
.build();
DatabaseInformation response =
service.getDatabaseInformation(databaseInfoOptions).execute()
.getResult();
System.out.println(response);
const { CloudantV1 } = require('@ibm-cloud/cloudant');
const service = CloudantV1.newInstance({});
service.getDatabaseInformation({db: '_replicator'}).then(response => {
console.log(response.result);
});
from ibmcloudant.cloudant_v1 import CloudantV1
service = CloudantV1.new_instance()
response = service.get_database_information(db='_replicator').get_result()
print(response)
getDatabaseInformationOptions := service.NewGetDatabaseInformationOptions(
"_replicator",
)
databaseInformation, response, err := service.GetDatabaseInformation(getDatabaseInformationOptions)
if err != nil {
panic(err)
}
b, _ := json.MarshalIndent(databaseInformation, "", " ")
fmt.Println(string(b))
前の Go の例では、以下のインポート・ブロックが必要です。
import (
"encoding/json"
"fmt"
"github.com/IBM/cloudant-go-sdk/cloudantv1"
)
すべての Go の例では、serviceオブジェクトを初期化する必要があります。 詳しくは、API 資料の認証セクションで例を参照してください。
複製文書から競合を取得
返された JSON で、disk_size 値を検索します。 値が 1 GB を超えるサイズを示している場合は、 IBM Cloud サポート・ポータル に進み、さらにアドバイスを受けてください。
以下の例に示すように、競合がないか個別の _replicator 文書を確認することができます。
curl "$SERVICE_URL/_replicator/$DOCID?conflicts=true"
import com.ibm.cloud.cloudant.v1.Cloudant;
import com.ibm.cloud.cloudant.v1.model.GetReplicationDocumentOptions;
import com.ibm.cloud.cloudant.v1.model.ReplicationDocument;
Cloudant service = Cloudant.newInstance();
GetReplicationDocumentOptions replicationDocOptions =
new GetReplicationDocumentOptions.Builder()
.conflicts(true)
.docId("$DOCID")
.build();
ReplicationDocument response =
service.getReplicationDocument(replicationDocOptions).execute()
.getResult();
System.out.println(response);
const { CloudantV1 } = require('@ibm-cloud/cloudant');
const service = CloudantV1.newInstance({});
service.getReplicationDocument({
conflicts: true,
docId: '$DOCID'
}).then(response => {
console.log(response.result);
});
from ibmcloudant.cloudant_v1 import CloudantV1
service = CloudantV1.new_instance()
response = service.get_replication_document(
conflicts=True,
doc_id='$DOCID'
).get_result()
print(response)
getReplicationDocumentOptions := service.NewGetReplicationDocumentOptions(
"$DOCID",
)
replicationDocument, response, err := service.GetReplicationDocument(getReplicationDocumentOptions)
if err != nil {
panic(err)
}
replicationDocument.Conflicts = core.BoolPtr(true)
b, _ := json.MarshalIndent(replicationDocument, "", " ")
fmt.Println(string(b))
前の Go の例では、以下のインポート・ブロックが必要です。
import (
"encoding/json"
"fmt"
"github.com/IBM/cloudant-go-sdk/cloudantv1"
"github.com/IBM/go-sdk-core/core"
)
すべての Go の例では、serviceオブジェクトを初期化する必要があります。 詳しくは、API 資料の認証セクションで例を参照してください。
すべての複製をキャンセル
すべての複製をキャンセルして、新しくてクリーンな _replicator データベースから開始したい場合は、replicator データベースを削除してから再作成してください。
_replicator データベースを削除して再作成するには、以下のHTTPを参照のこと:
DELETE /_replicator HTTP/1.1
HOST: $SERVICE_URL
Authorization: ...
PUT /_replicator HTTP/1.1
HOST: $SERVICE_URL
Authorization: ...
レプリケーター・データベースの削除
_replicator データベースを削除するには、以下の例を参照してください。
curl -X DELETE "$SERVICE_URL/_replicator"
import com.ibm.cloud.cloudant.v1.Cloudant;
import com.ibm.cloud.cloudant.v1.model.DeleteDatabaseOptions;
import com.ibm.cloud.cloudant.v1.model.Ok;
Cloudant service = Cloudant.newInstance();
DeleteDatabaseOptions deleteDatabaseOptions = new DeleteDatabaseOptions.Builder()
.db("_replicator")
.build();
Ok response = service.deleteDatabase(deleteDatabaseOptions).execute()
.getResult();
System.out.println(response);
const { CloudantV1 } = require('@ibm-cloud/cloudant');
const service = CloudantV1.newInstance({});
service.deleteDatabase({db: '_replicator'}).then(response => {
console.log(response.result);
});
from ibmcloudant.cloudant_v1 import CloudantV1
service = CloudantV1.new_instance()
response = service.delete_database(db='_replicator').get_result()
print(response)
deleteDatabaseOptions := service.NewDeleteDatabaseOptions(
"_replicator",
)
ok, response, err := service.DeleteDatabase(deleteDatabaseOptions)
if err != nil {
panic(err)
}
b, _ := json.MarshalIndent(ok, "", " ")
fmt.Println(string(b))
前の Go の例では、以下のインポート・ブロックが必要です。
import (
"encoding/json"
"fmt"
"github.com/IBM/cloudant-go-sdk/cloudantv1"
)
すべての Go の例では、serviceオブジェクトを初期化する必要があります。 詳しくは、API 資料の認証セクションで例を参照してください。
レプリケーター・データベースを再作成します。
_replicator データベースを再作成するには、以下の例を参照してください。
curl -X PUT "$SERVICE_URL/_replicator"
import com.ibm.cloud.cloudant.v1.Cloudant;
import com.ibm.cloud.cloudant.v1.model.Ok;
import com.ibm.cloud.cloudant.v1.model.PutDatabaseOptions;
Cloudant service = Cloudant.newInstance();
PutDatabaseOptions databaseOptions = new PutDatabaseOptions.Builder()
.db("_replicator")
.build();
Ok response =
service.putDatabase(databaseOptions).execute()
.getResult();
System.out.println(response);
const { CloudantV1 } = require('@ibm-cloud/cloudant');
const service = CloudantV1.newInstance({});
service.putDatabase({
db: '_replicator'
}).then(response => {
console.log(response.result);
});
from ibmcloudant.cloudant_v1 import CloudantV1
service = CloudantV1.new_instance()
response = service.put_database(db='_replicator').get_result()
print(response)
putDatabaseOptions := service.NewPutDatabaseOptions(
"_replicator",
)
ok, response, err := service.PutDatabase(putDatabaseOptions)
if err != nil {
panic(err)
}
b, _ := json.MarshalIndent(ok, "", " ")
fmt.Println(string(b))
前の Go の例では、以下のインポート・ブロックが必要です。
import (
"encoding/json"
"fmt"
"github.com/IBM/cloudant-go-sdk/cloudantv1"
)
すべての Go の例では、serviceオブジェクトを初期化する必要があります。 詳しくは、API 資料の認証セクションで例を参照してください。
多くの同時複製
2 つのデータベース間の複製を以前セットアップしたことを忘れて、 追加の複製プロセスを作成してエラーになることがよくあります。 それぞれの複製ジョブは他のジョブからは独立しているため、IBM Cloudant は、ユーザーが追加の複製プロセスの作成を行うのを止めません。 しかし、各複製タスクはシステム・リソースを使用します。
IBM Cloudant ダッシュボードで「アクティブ複製」をチェックして、不要な複製タスクが進行中でないことを確認できます。 もう必要ない _replicator 文書は削除してください。
複製速度の調整
By default, IBM Cloudant レプリケーションは、パフォーマンスに悪影響を与えることなく、ソースからターゲットにデータを取得するために適切な速度で実行されます。 複製速度と、他のタスクでのクラスター・パフォーマンスとの間の選択はトレードオフです。 ユースケースによっては、他の IBM Cloudant サービスを犠牲にして複製速度を上げる必要がある場合があります。 あるいは、複製をバックグラウンド・プロセスとして処理し、クラスター・パフォーマンスを優先させる必要がある場合もあります。
拡張複製 API オプションが使用可能です。 これらのオプションを使用すると、複製中に使用されるコンピューティング能力の増減が可能になります。以下に例を示します。
- 文書に添付ファイルが含まれている場合は、小さいバッチに大きい文書を入れるために、batch_size の削減と、worker_processes の増加を検討することをお勧めします。
- 多くの小さい文書がある場合は、
worker_processおよびhttp_connectionsの値を増加することを検討できます。 - インパクトを最小にして複製を実行する場合は、
worker_processesおよびhttp_connectionsを 1 に設定すると適切な可能性があります。 - 詳しくは、 複製による読み取り操作と書き込み操作の使用 を参照してください。
ユース・ケースに最適な構成についてさらに支援が必要な場合は、 IBM Cloud サポート・ポータルにアクセスしてください。
"use_bulk_get": true" 複製オプションを有効にすると、複製のパフォーマンスを向上させることができます。 その場合、レプリケーターは、個別にではなく、バッチでソースから文書を取り出します。
{
"_id": "rep_doc_id",
"source": "https://account1.cloudant.com/db1",
"target": "https://account2.cloudant.com/db2",
"use_bulk_get": true
}
複製速度の増加により、ソース・エンドポイント・アカウントおよびターゲット・エンドポイント・アカウントで使用可能な読み取り速度または書き込み速度の容量が消費される可能性があります。
複製による競合する文書リビジョンの削除
複製を介して競合する文書リビジョンを削除する 1 つの方法は、 "winning_revs_only": true オプションを有効にすることです。 このオプションは、 勝利 文書リビジョンのみを複製します。 これは、 GET $SERVICE_URL/$DATABASE/$DOCID 要求によってデフォルトで返されるリビジョンです。 このオプションは、競合する文書リビジョンを破棄するため、拡張オプションです。
このオプションは注意して使用すること。