まだプログラマーですが何か?

プログラマーネタとアスリートネタ中心。たまに作成したウェブサービス関連の話も http://twitter.com/dotnsf

タグ:cloudant

(この記事は IBM Cloud アドベントカレンダー 2018 に参加しています。3日目の記事です)

IBM Cloudant (Apache CouchDB) にあまり詳しくない人が他のデータベースと同じ感覚でデータを扱っている時に、特に既存データを更新している時にふと気づくことがあります。例えば以下のような現象を目の当たりにした時、何が起こっているのか正しく理解できるでしょうか?


IBM Cloudant のダッシュボード画面にアクセスし、今回は "testdb" という名称のデータベースを IBM Cloudant 上に新規に作成しました。以下の手順はすべてこのデータベースを対象に行います(CouchDB でも同様の結果になります)。作成したばかりなのでまだドキュメント数はゼロです:
2018100201


testdb データベースを選択した画面です。普通はここで testdb 内のドキュメント一覧が表示されますが、まだ1つも存在していないので "No Documents Found" と表示されています。ここでドキュメントを新規に作成するため "Create Document" ボタンをクリックします:
2018100202


新規に JSON ドキュメントを作成する画面に切り替わります。Cloudant(CouchDB) のドキュメントは "_id" というユニーク ID を含める必要があります(API 経由で _id を含めずに作ると自動的に割り振られます)。自動的に設定された "_id" 以外に "name" というキーを作り、適当な値(下図では "kkimura")を設定して "Create Document" ボタンをクリックします(JSON ドキュメントなので "_id" キーの最後にカンマをつけることを忘れずに):
2018100203


先程のドキュメントが作成され、ドキュメント一覧に1つのドキュメントが表示されるようになりました:
2018100204


ちなみに、この段階でデータベース一覧に戻ると testdb データベースのドキュメント数もゼロから 1 に変わっていることが確認できます:
2018100205


またドキュメント一覧からこのドキュメントを選択するとドキュメントの確認/編集画面になります。"_rev" という先ほど指定しなかったキーと値が追加されていますが、こちらは後で説明します:
2018100206


ここまでは特別におかしな所はないと思います。この文書を編集するあたりから Cloudant 特有のクセというか、「あれ?」と感じる所が出てくるようになってきます。

この画面から JSON ドキュメントを編集してみます。試しに "name" の値を(下図では "Kei Kimura" に)変更し、"Save Changes" ボタンをクリックします:
2018100207


変更内容が保存されて、ドキュメント一覧に戻ります。既存文書を編集して保存したので文書数は変わらずに1つのままです。ではこの文書を選択して開いてみます:
2018100208


"name" の値が "Kei Kimura" になった文書が開きました。が、よく見ると "_rev" の値が先程と異なっています。最初に作った直後は "1-" で始まる値だったのが、 "2-" で始まる値になっています。ここは変更しなかったはずなんですが・・・:
2018100209


また、このタイミングでデータベース一覧の画面に戻ると、testdb の文書数は1のままなんですが、データベースサイズが微妙に増えています。これほどの差がでるような変更をしたつもりはないのですが・・・:
2018100210


更にこの文書を開いて、再度 "name" 値を "kkimura" に変更して(元に戻して)みます。値を変更して "Save Changes" ボタンをクリックします:
2018100211


すると(中を開いて確認してもいいのですが)また "_rev" の値が変わっていることが一覧からもわかります。今度は "3-" で始まる値になっていました:
2018100212


この辺りから「???」と感じることが増えてきました。では最後にこの文書を削除してみます。一覧からチェックをつけてゴミ箱ボタンをクリックします:
2018100213


削除すると一覧からは文書は消えて、元通りの "No Documents Found" が表示されます:
2018100214


しかしデータベース一覧に戻って testdb を見ると、文書数は "0" ですが、横に!マークが付いています。また文書を削除した割にはデータベースサイズがあまり減っていないように見えます:
2018100215


この!マーク部分にマウスカーソルをあわせると、"This database has just 0 docs and 1 deleted docs" と表示されます。このメッセージの意味はいったい・・・:
2018100216


ドキュメントに勝手に "_rev"(と "_id")が付与されること、編集して保存すると "_rev" の値が勝手に変更されること、文書を削除してもデータベースサイズが減らないこと、文書を削除した時の謎のメッセージ、・・・ と、この辺りが Cloudant(CouchDB) を始めて使うと戸惑う点でしょうか? 前置きが長くなってしまいましたが、以下にこの謎を解くための説明を記載します。


上記の振る舞いを理解するには、まず自動付与される2つの値 "_id" と "_rev" の意味と役割を正しく理解する必要があります。

"_id" はいわゆる「文書 ID」です。この値はデータベース内でユニークな値をなっており、各文書を一意に取得することができるキー値となっています。正しい ID 値が与えられるだけで(他の絞り込み条件がなくても)データベース内から目的の文書を特定して取得することができます。ID 値については普通のデータベースでも扱うものなので、あまり難しくないと思っています。

一方、もうひとつの "_rev" 、こちらは IBM Cloudant(CouchDB) の特徴的な予約語となっており、「文書のリビジョン」を管理する値となっています。「リビジョン」は「バージョン」と読み替えていただいてもいいです。

上記の例だと、最初に "name" = "kkimura" という値で文書を作成しました。この時点ではこの文書のリビジョン(バージョン)は 1 で、"_rev" 値は "1-" で始まる値になっていました:
2018100204


次に同じ文書を "name" = "Kei Kimura" と変更して保存しました。この時点でこの文書のリビジョンは 2 となり、"_rev" 値も "2-" で始まる値に更新されました:
2018100208


更に同じ文書を "name" = "kkimura" に戻して保存しました。この時点でこの文書のリビジョンは 3 となり、"_rev" 値も "3-" で始まる値に更新されました:
2018100212


つまり "_rev" 値は "_id" 値で決まる文書のバージョンを管理する役割を持って自動的に更新されるシステム値ということになります。ただ Cloudant(CouchDB) でドキュメントが更新される際にはもう1つの特徴があります。

実は Cloudant(CouchDB) ではドキュメントが更新されることはほぼなく、「新しいドキュメントが新しい "_rev" 値を持って新規作成」されます。つまり厳密には同じ "_id" 値を持った複数のドキュメントがデータベース内には存在しているが、その中で最も大きな "_rev" 値を持ったドキュメントだけが有効になります。論理的にドキュメントを更新したつもりでいても、物理的には古いドキュメントは消えずに残っていて、新しいドキュメントが同じ "_id" 値&新しい "_rev" 値で作成されるのでした。なお最新でないリビジョンのドキュメントは _id 値を指定してドキュメントを取得する時に { revs_info: true } というオプションを指定することで取得することができます(このオプションをつけない限り、最新 _rev のものだけで取得できます):
http://docs.couchdb.org/en/stable/api/document/common.html


上記で Cloudant(CouchDB) のドキュメントが更新されることは「ほぼ」ないと書いたのですが、厳密にはあります。それが文書削除時です。Cloudant(CouchDB) の文書削除はいわゆる「ソフトデリート(論理削除)」であって、「ハードデリート(物理削除)」ではありません。文書に削除フラグ( { _deleted: true } )をつけて更新し、最新 "_rev" の文書が削除されているようにすることで、論理的に文書が削除されたことにしています。そしてこの論理削除を行う際には _id 値だけではなく、_rev 値と合わせて指定して、「この ID 値の、このリビジョンの文書を削除する」ことを明示的に指定する必要があります。論理的には _id 値だけで削除できそうな感覚を持ってしまいますが、その場合はまずその _id 値を持ったドキュメントの最新リビジョンを取得し、取得したドキュメントから _rev 値を取り出し、改めて _id 値と _rev 値を指定して論理削除する、という流れになります。


これらの部分を理解していると、文書を更新したり、削除した時にデータベースサイズが増える謎が理解できると思います。要は物理的に書き換えたり、物理的に削除しているわけではなく、新リビジョンのドキュメントを追加したり、削除フラグをつけたりしているだけなので、(別途物理削除するまでは)データベースサイズという観点では減ることがないのでした。








 

(この記事は IBM Cloud アドベントカレンダー 2018 に参加しています。2日目の記事です)

先日、以下のブログエントリを公開しました。本エントリはその技術的な補足と、試験的な意味も含めてアプリ URL を一般公開する内容になっています。
お絵かき LIFF アプリを作ってみた

2018112200


技術的な説明の前に、まずは一度使ってみていただきたく、このアプリを(一時的に?)公開することにしました。少し面倒ではありますが、以下の手順で実行できるようにしたので、まずは一度使ってみてください。

①スマホに LINE アプリをインストール(お絵かきアプリは PC 版 LINE からは使えません)

②LINE を開いて誰かとのメッセージ画面(グループ LINE 可)の中に以下の文字を入力してリンクメッセージとして送信する(この作業だけは PC の LINE アプリから行ってもよい)
line://app/1624220123-mbERyVgb

2018120101


③スマホの LINE 画面内から②で送信したリンクメッセージをタップ
2018120102


④LINE 内でお絵かきアプリが起動します。ペンの色と太さを変えながら指でお絵かきします。
2018120103


⑤間違えたら reset か、一度終了してから再度リンクメッセージをタップしてやり直し。
2018120104



⑥描き終わったら post でお絵かきが画像として LINE にメッセージ送信されます(右上の×を押してアプリを終了する)
2018120105


・・・というものです。LINE はスタンプ文化が有名ですが、スタンプを持っていなくてもその場でお絵かきして送るとか、他には地図を書いて送るとか、いろいろな使い方が考えられると思っています。現状、上記のリンクを LINE のメッセージとして一度送っておく必要があり、そのリンクをタップした時に起動する、という使い方になってしまいます。技術的に興味がある人もない人も是非お試しいただきたいと思っています。


以下、このアプリの技術的な解説になります。

このアプリは LINE の新しい開発フレームワークである LIFF(LIne Front-end Framework) を使って開発しています:
https://developers.line.biz/ja/docs/liff/overview/


LIFF は LINE 内で動作するウェブアプリケーションのプラットフォームです。「LINE 内で動作する」という点と「ウェブアプリケーション」であることがキーワードです。上記のように LINE 内で特定リンクをタップすることで起動し、その中身は HTML5 と JavaScript で記述されたウェブアプリケーションです。LIFF の詳しい仕様等は上記の開発者向けページを参照いただきたいのですが、要するにパブリックインターネット上に HTML5 ベースのウェブアプリを作って、そこを参照するような LINE リンクを作っておくことで LINE アプリ内でその HTML5 ページを起動することができます。また LIFF SDK の JavaScript API を使うことで、その HTML5 アプリの情報を起動元である LINE 側に(メッセージとして)送信することも可能です。

今回作ったアプリの場合は HTML5 の Canvas を使ってお絵かきアプリを作成し、その中に描かれた絵を動的に画像に変換して、画像を貼り付ける形でメッセージを送ったことにしています。その結果、HTML5 Canvas 内に描かれた絵を LINE 上で画像添付したかのように送信させることを実現しています。

この仕組の HTML5 ウェブアプリケーション部分と、画像添付部分を IBM Cloud 上の Node.js ランタイムと IBM Cloudant を使って実現しています。HTML5 Canvas 内に描いた画像を動的に PNG 画像へ変換し、Node.js ランタイム上の REST API を使って取得し、(LIFF の場合、画像はオリジナル以外にサムネイルが必要なので)サムネイル画像を生成して IBM Cloudant データベース内に添付ファイルとして保存します:

2018120106


画像が添付できたら、今度はその画像を外部から参照できる URL を用意します。具体的には Node.js ランタイム内に Cloudant 内に格納した画像ファイルを参照できるような URL(REST API) を用意します。そして HTML5 内の LIFF SDK を使って、画像ファイルの URL をメッセージとして送信して、添付画像を付与したメッセージ送信と同じ処理を行います。これでお絵かきで作成した画像が添付されたかのような振る舞いを実現できます:
2018120107


という形で現在は実現しています。 つまり現在はこのアプリを使って作成した画像は IBM Cloudant 内に保存されるように実装されています。現在の運用環境では、このデータベースの容量にも制約があるので、しばらくはデータベースをリセットしながら運用することになります。もしうまく送信できない場合は僕がデータベースのメンテナンスを忘れていて、容量オーバーになっている可能性があることをお伝えしておきます(気付いたタイミングでリセットするようにします)。

また、この公開アプリのソースコードはこちらで(MIT ライセンスで)公開しています。IBM Cloud を使う前提で記述されたコードですが、自分なりに改良したい人がいればうまく活用してください:
https://github.com/dotnsf/line_liff_doodle


これまで LINE の API といえば Messaging API で、bot のようなバックエンド側を操作するアプリを作るには有用だったのですが、やっとフロントエンド側を操作できる API(というかフレームワーク)が出てきてくれました。公開ページ上で HTML5 アプリを置いて運用することになるので、実質的にクラウドを活用する形態が多くなると思います。そんな時に IBM Cloud の上記構成程度であれば無料のライトアカウントでも運用できるので、公開したソースコードを是非色んな人に使ってみたり改良してみてほしいです。

LINE の新しい開発フレームワークである LIFF(LIne Front-end Framework)の存在を教えていただいたので、試しに使ってみました。

この LIFF 最大の特徴はスマホの LINE アプリ内で HTML5 の Web アプリケーションを動かすことができる、という点です。この Web アプリケーション内で LIFF の SDK を併用すると、アプリケーションからLINE にメッセージや画像(やスタンプ)を送ることも可能です。

この LIFF を使って指で画面にお絵かきをするような HTML5 アプリを作り、その絵を LINE アプリに送信する、というアプリケーションを作ってみました。LINE はスタンプを送信する文化がメジャーですが、その延長で自分でその場でお絵かきした画像を送る、という使い方を想定したアプリケーションです。ソースコードは github で公開したので、興味ある方は実際に試してみてください:
2018112200



なお、今回提供しているソースコードでは IBM Cloud の NoSQL マネージド・データベースである Cloudant を使っているので、IBM Cloud のアカウントも必要です。無料のライトアカウントもあるので IBM Cloud のアカウントをお持ちでない場合はあわせて取得してください。


【IBM Cloudant の準備】
今回紹介するアプリケーションでは IBM Cloundant のインスタンスが必要です。IBM Cloud にログインし、インスタンスを1つ作成して、あらかじめ画像格納用のデータベースを用意しておきます。なお無料のライトプランの場合、Cloudant には 1GB までのデータしか格納することができないという点をご了承ください。

まず IBM Cloud にログインし、「リソースの作成」から IBM Cloudant を追加します。IBM Cloudant は「データベース」カテゴリ内に存在しています:
2018112201


作成時のロケーションはどこでも構いません(下図では「シドニー」を使っています)。ただ認証方法は従来の方式が利用できる方("Use both legacy credentials and IAM")を選択しておく必要があります:
2018112202


また価格プランも任意で構いませんが、Lite プランの場合は無料です。ただし 1GB までしかデータを格納することはできません。最後に「作成」をクリックしてインスタンスを作成します:
2018112203


Cloudant インスタンス作成直後の画面です。まずここから目的の(画像格納用の)データベースを作成するため、Cloudant のダッシュボードに移動します。下図の緑のボタンをクリック:
2018112204


Cloudant のダッシュボード画面に移動しました。データベース一覧が表示されていますが、作成直後の場合は何も存在してません。ここで「Create Database」をクリックして、データベースを作成します:
2018112205


作成するデータベースの名前を指定します。デフォルトでは "doodledb" を使います(後述の settings.js 内で指定されている名称と一致している必要があります)ので、とりあえず doodledb と入力して「Create」します:
2018112206


doodledb データベースが作成され、doodledb データベース内の文書一覧画面に移動しました(当然中身はありません)。左上の "<" 印をクリックしてデータベース一覧に戻ります:
2018112207


データベース一覧に戻りました。先程とは変わって、"doodledb" が一覧に含まれているはずです。これでデータベースの準備ができました:
2018112208


次にこのデータベースへ接続するための情報を確認します。IBM Cloud の画面に戻り、「サービス資格情報」タブを選択します。サービス資格情報は(この時点では)存在していないはずなので、「新規資格情報」ボタンをクリックして作成します:
2018112201


設定項目は変更せずに「追加」します:
2018112202


資格情報が追加されると先程の画面内に「資格情報の表示」メニューが追加されているはずです。ここをクリックして内容を確認します:
2018112203


資格情報の内容が JSON テキストで表示されます。今回必要なのは "username" と "password" の値です。これらの情報を後で利用するので、メモしておくか、コピペできるようにしておきます:
2018112204


これで IBM Cloudant の準備はできました。


【ランタイム(Web アプリケーション・サーバー)の準備】
次に LIFF が参照する Web アプリケーションサーバーを作成します。このサンプルは Node.js 上で動作するサンプルですが、今回は IBM Cloud 上にアプリケーション・サーバーを作成することにします(これもライトプランの無料枠内で作成することができます)。

Cloudant の時と同様に IBM Cloud にログイン後にリソース作成で「コンピュート」カテゴリの「SDK for Node.js」を選択します:
2018112201


ロケーションは「ダラス」を選択します(するとドメインは "mybluemix.net" となります)。そして「アプリ名」にアプリケーション名称を指定します。下図の例では "linedoodle" というアプリケーション名称としており、この場合のエンドポイント URL は https://linedoodle.mybluemix.net/ となります。なおアプリ名は他で使われていないものを指定する必要があります。自分の名前や日付を指定するなどして、ユニークなアプリケーション名称を指定してください。最後に「作成」をクリックします:
2018112202


しばらく待つとアプリケーションサーバーが起動します。これで LIFF アプリからアクセスできるパブリッククラウド上にアプリケーションサーバーが用意できました:
2018112203


【LINE Developers の準備】
LINE の LIFF アプリを作成するには LINE Developers でのチャネル登録が必要です。LINE Developer において新規にチャネルを作成します:
2018112204


チャネルの種類は「Messaging API」を選択します:
2018112205


アプリ名とプラン(Developer Trial)を選択し、作成します:
2018112206


作成すると、このチャネルにアクセストークンが割り当てられます。「アクセストークン(ロングターム)」と書かれた項目の値をこの後で使うことになるのでメモするか、コピペできるようにしておきます:
2018112207


また、ここで LIFF アプリとしてのアプリ URL を作成しておきましょう。LIFF タブを選んで「追加」ボタンをクリックします:
2018112209


名称、サイズ(Full または Tall のいずれかを選択)、そしてエンドポイント URL(上述の Node.js アプリケーションのエンドポイント URL)を入力して「保存する」をクリックします:
2018112210


すると LIFF アプリが登録され、LIFF URL が確認できるようになります。この LIFF URL は実際に LINE からアプリケーションを起動する際に利用します:
2018112208


これで LIFF アプリの登録も完了しました。あと少し。


【アプリケーションの準備】
上記で作成したアプリケーション・サーバーに HTML5 アプリケーションをデプロイします。まずはソースコードを入手します。github のリポジトリからソースコードをダウンロードまたは git clone して入手します:
https://github.com/dotnsf/line_liff_doodle

ソースコードがダウンロードできたら settings.js ファイルを環境にあわせて編集して保存します:
exports.db_username = '(Cloudant の username)';
exports.db_password = '(Cloudant の password)';
exports.db_name = 'doodledb';
exports.app_port = 0;

exports.base_url = 'https://(アプリケーション名).(ドメイン)/';

exports.line_access_token = '(LINE Developer で取得したロングタームアクセストークン)';

  :
  :

最後にこのアプリを上記で作成したアプリケーションサーバーにデプロイします。IBM Cloud では cf コマンドを使ってデプロイするので、未導入の場合は cf コマンドをダウンロード&インストールしてください:
https://github.com/cloudfoundry/cli/releases


そして cf コマンドを使って IBM Cloud へ IBM ID でログインし、アプリケーションをプッシュ(デプロイ)します:
$ cd (ソースコードのあるフォルダ)
$ cf login -a https://api.ng.bluemix.net/ -u (IBM ID)
$ cf push (アプリケーション名)

ここまでの作業が全て成功すると LIFF アプリが IBM Cloud 上にデプロイされ、LINE のチャット上で LIFF URL をクリックすると、LINE 上で同アプリケーションを呼び出すことができるようになります。


【LINE で動作確認】
では実際に LINE を使って動作確認してみます。上述で取得した LIFF URL ("line://app/" で始める文字列)をコピー&ペーストするなどして LINE のメッセージとして表示させます:
2018112201


この LIFF URL 部分をタップすると画面下部から LIFF アプリである HTML5 の Web アプリケーションの画面が表れます。今回の Web アプリはお絵かきアプリとなっていて、指でキャンバス上をドラッグして絵を描くアプリとなっています。色やフォントの太さを変えたり、失敗したら "reset" ではじめからやり直すこともできます:
2018112202


たとえばこんな絵を描いてみました。書き終わったら "post" をタップします:
2018112203


描いた絵が LINE の会話内に画像として表れます。その場でステッカーを作って送るような感覚です:
2018112204


・・・というアプリを作ってみたのでした。いかがでしょう? ちなみに iPhone 版の LINE でのみ動作確認しています。Android 版 LINE でうまく動かなかったらごめんなさい。


以前から似たようなアプリを Twitter 向けに作ってみたりしていて、同じようなのを LINE 向けにも作れたらいいなあ、と思っていました。が、LINE にはクライアント側を操作できる API が提供されておらず作ることができずに諦めていました。 が、今回 LIFF の存在を教えていただいて、「これならできるかも・・」と期待してがんばってみたら、なんとか実現できた、という経緯です。アプリ実装の詳細についてはまた別の機会にでも。

ある意味で LINE のステッカービジネスを根底から否定(苦笑)するアプリなので、あまり LINE 受けはよくないかもしれません。(^^; でも教えていただいたおかげで実現することができました。この場をお借りしてお礼申し上げます。


そうそう。繰り返しになりますが、IBM Cloud の(無料の)ライトアカウントを使って作成した場合、データベースには 1GB ぶんの画像しか格納できません。定期的にデータを削除するとか、データベースを消して作り直すとかして対応してください。



(参考)
LIFF API リファレンス


IBM Watson をはじめとした IBM Cloud から提供されているサービスの認証方法に IAM が採用され始めています。以前に IBM Watson サービスで IAM を使う方法についてはこちらのブログエントリでも紹介しました:
IBM Watson のアプリケーションを IAM(API Key) 認証/認可に移行する


今回は IBM Cloudant を IAM で利用する方法を紹介します。なお 2018/11/22 時点で IBM Cloudant が IAM でないと認証できなくなるというアナウンスがされているわけではないことを書き添えておきます(つまり現時点では従来の認証方法と併用されており、すぐに移行作業が必要になるわけではありません)。


まずは IAM に対応した IBM Cloudant のサービスインスタンスを用意する必要があります。現在 IBM Cloudant のサービスインスタンスを作成すると IAM のみで利用するタイプか、従来の認証と IAM の両方が利用できるタイプかを選択して作成することができます。どちらでもいいのですが IAM 対応のインスタンスを用意します。

まず IBM Cloud のダッシュボードからリソースの追加を行い、データベースカテゴリ内の "Cloudant" を選択します:
2018110701


作成時の認証方法において "Use both legacy credentails and IAM(従来の方法と IAM)" を選択して作成します:
2018110702


これでどちらの方法でも認証できるインスタンスが作成できました:
2018110703


クレデンシャル情報を確認するため、サービス資格情報を参照します。資格情報が作成されていない場合はあらたに1つ作成します:
2018110704


作成した資格情報を選択して参照します:
2018110706


JSON テキスト内に "apikey" と書かれたキー文字列が含まれていることを確認します。この値は後ほど利用します:
2018110707


では IAM で IBM Cloudant を使う Node.js アプリケーションを作成してみます。ソースコードはこんな感じになります:
var fs = require( 'fs' );

//. https://www.npmjs.com/package/@cloudant/cloudant
var CloudantLib = require( '@cloudant/cloudant' );

var options = {
  url: "https://xxxxxx-bluemix.cloudant.com",    //. Cloudant URL
  plugins: {
    iamauth: {
      iamApiKey: "(上記 apikey 文字列)"
    }
  }
};
var cloudant = new CloudantLib( options );
var db = cloudant.db.use( "mydb" );

db.list( { include_docs: true }, function( err, body ){
  if( err ){
    console.log( JSON.stringify( err, null, 2 ) );
  }else{
    console.log( JSON.stringify( body, null, 2 ) );
  }
});

Cloudant へのアクセスには @cloudant/cloudant パッケージを利用しています。このパッケージが既に IAM 対応済みで、上記のように URL と apikey 文字列を指定することでデータベースに接続することができ、データベースインスタンス生成後は従来通りの各種関数が利用できるようになります。


IBM CloudantApache CouchDB をベースとしたマネージド NoSQL DB サービスです。IBM Cloud のライトアカウントを利用することで無料枠内で利用することも可能です。

そんな便利な IBM Cloudant ですが、IBM Cloud では(特に無料枠で使った場合)では、どのようなクラスタリング構成で運用されているのか気になりました。もともと NoSQL DB はスケーリングに優れていて、大規模運用向きと言われています。ではこの(特に無料のライトプランで提供されている)IBM Cloudant はどのような運用構成で提供されているのでしょう? 理論上は1サーバーノードで(クラスタリングなしで)提供することも可能だし、無料プランということを加味して、クラスタリング無しだったとしてもまあそうだよね・・とも考えられます。一方で無料プランと有償プランで(わざわざ)差をつけて運用しているのか?という疑問もあります。このあたりをそっと調べてみました。


まず、調べる方法は CouchDB REST API の GET /db を使うことにしました。この REST API を実行すると指定したデータベースの情報を得ることができ、その中には(クラスタリング構成になっていれば)クラスターに関する情報が含まれていることになっています。この方法で自分がローカルで構成した単一構成の CouchDB と、IBM Cloud のライトプランで契約した IBM Cloudant の2つのデータベースに対して実行し、その結果を比較してみることにします。

まず前者の単一構成 CouchDB のデータベースに対してこのコマンドを curl で実行しました(実行結果は青字):
$ curl 'http://localhost:5984/ccdb'

{"db_name":"ccdb","update_seq":"6-

g1AAAAEzeJzLYWBg4MhgTmHgzcvPy09JdcjLz8gvLskBCjMlMiTJ____PyuRAYeCJAUgmWSPX40DSE08WA0TLjUJIDX1eM3JYwGSDA1ACqhsPiF1C

yDq9uO2E6LuAETdfULmPYCoA_khCwCKxmL8","sizes":{"file":58598,"external":615,"active":1730},"purge_seq":0,"other":

{"data_size":615},"doc_del_count":2,"doc_count":2,"disk_size":58598,"disk_format_version":6,"data_size":1730,"com

pact_running":false,"instance_start_time":"0"}

指定したデータベース(上例では ccdb)の現在の状態が表示されています。各項目の意味は上述の GET /db API のリンク先で説明されているのでそちらを参照いただきたいのですが、この実行結果にはクラスタリング情報が含まれていません。実際クラスタリング構成ではなく単一構成で動いているので、この実行結果もその運用状態を正しく表しています。

次に同じコマンドを IBM Cloudant のライトプランで作成したデータベースに対して実行しました。その結果がこちらです:
{"status":true,"info":{"update_seq":"20-

g1AAAAQneJzLYWBgEMhgTmHQTElKzi9KdUhJMtFLytVNTtYtLdYtzi8tydA1NNBLzskvTUnMK9HLSy3JAWphSmRI4v___39WIgNIsxZcs6EhMbqTB

IBkkjzYAGZU24nTrwDSr49NvzlR-g1A-u0RHiDR90kOIP3-

CPtJDoAAkAHx2BxAnP4EkP58bPqJC4ACkP56sgMgjwVIMjQAKaAR_VmJTOQEAsSQCRBD5pMXEBAzFkDMWE9eYEDM2AAxYz_UM2QFyAGIGeezEhnJD

5ALEEPuUxIgDyBmvCcve0DM-AAxA5TEswCIaVtl","db_name":"statedb","sizes":

{"file":11774513,"external":10511286,"active":10543509},"purge_seq":0,"other":

{"data_size":10511286},"doc_del_count":7,"doc_count":2,"disk_size":11774513,"disk_format_version":6,"data_size":1

0543509,"compact_running":false,"cluster":{"q":16,"n":3,"w":2,"r":2},"instance_start_time":"0"}}

↑特に赤字部分に注目してほしいのですが、先程の実行結果には存在しなかったクラスタリングに関する情報が含まれています。そしてこの結果を見ると、このデータベースは
 ・シャード数: 16(!)
 ・1つのドキュメントの分散数: 3
 ・書き込みコマンドを実行した場合、2つ以上に書き込めたら書き込み成功とする
 ・読み取りコマンドを実行した場合、2つ以上から結果が返ってきたら読み取り成功とする

という条件でクラスタリングが構成されていることがわかります。無料のライトプランでも結構な好条件でクラスタリングされていたんですね、へぇ~。


 

このページのトップヘ