sqlまで使える高機能nosqlであるcouchbase serverの勉強会資料
TRANSCRIPT
Couchbase Server を半年使ってみた( 株 ) ゆめみ 仲川樽八
本スライドの目的本スライドは ( 株 ) ゆめみ社内で CouchbaseServer に興味を持ってもらうための勉強会で使用した資料の公開版となります。
社内で、システムのメンテナーを増やすことで自分が楽をしたいという個人的な狙いが主目的となりますが、こういった形で情報共有することにより、国内での利用がもっと盛り上がってもらえればそれに越したことはありません。
What is Couchbase Server
Couchbase Server の特徴(その 1 )
Couchabe 3.x 系• NoSQL• 他の NoSQL 製品と比べても速いよ• ノード追加でどこまでもスケールするよ
• データ量• CPU 資源・メモリー資源
• データ冗長度を高く設定できるよ。 (AZ 間で持てるので Zone 障害でデータロストしない )• XDCR という機能があって、リージョン感で双方向レプリケーションできるよ。 ( 海外に待
機系システムを構築すれば東京リージョン全滅でも大丈夫 )• elasticsearch 連携すれば横断検索も出来る• SDK の完成度が高くて信頼性があるよ。• WebConsole の出来が異様にいいよ。
Couchbase 4.x 系2015 年 10 月頃に正式リリース
• NoSQL なのに、 N1QL という SQL が使える !!まさに Not Only SQLNoSQL なのに、ドキュメントを横断検索した結果で Update なんてことも出来る。いろいろ妄想が広がる
• Couchbase3.x 系→ 4.x 系のバージョンアップも XDCR 機能などを使えばダウンタイムゼロで可能 !!
良いことだらけじゃないか !!
Why Japanese People は もっと Couchbase Server 使わないの?
と切れる前に、
それ、 RDB で出来ない?
ソリューション選定の鉄則
候補ソリューションのメリットに目を奪われてははならない。
必須要件の中に出来ないことが一つでもあるのであれば、そのソリューションは選んではならない。それを忘れたものは地獄の業火に焼かれるであろう。
Taruhachi (1975~)
Couchbase Server の特徴(その 2 )
特徴(地雷)• 大事なデータを扱おうとするとライセンス版がほぼ必須。• 冗長化すると最小構成でもかなりリッチな構成になる。• Couchbase 社、日本法人撤退しちゃった。• トランザクションレス(多くの場合致命的)• データの中身の検索が弱い。 Unique 制約等が貼れない。• elasticsearch 連携できるが、、、。• N1QL で SQL が使えるが、、、。• データの外部連携が面倒。
結論から先に言うと、
どうしても NoSQL でないといけない案件の時には積極的に検討したい。
ただし、 RDB が使えるのであれば、悪いことは言わないので使っておこう。
それでも茨の道を歩みたい人、歩まなければならない運命を持った人は続きのスライドをどうぞ。
各地雷は・アプリケーションの実装で踏み抜く・運用でカバーする
のいずれかで対応する必要があります
大事なデータを扱おうとするとライセンス版がほぼ必須。
特徴(地雷)
以下の機能はノード単位でライセンス費用が必要となる。※ Oracle よりはかなり安いですが、、、 small start な案件には厳しいかも。
• XDCR 機能 複数の CouchbaseCluster 間でデータのレプリケーションを行う機能 リージョンをまたいで双方向のレプリケーションも可能 ダウンタイム無しでのバージョンアップや、 CouchbaseCluster の切り替えなどにも便利
• クラスタ中のノードのグループ化する機能 ノードをグループ化することにより、該当ノードのデータの複製先を必ず別のグループのノードに割り当てるという指定が可能。 AZ( データセンターに相当 ) を指定することで AZ 障害においてもデータが欠損しなくなる。
冗長化すると最小構成でもかなりリッチな構成になる
特徴(地雷)
各 AZ に 2台のノードを配置、それを複数 AZ に展開することで初めて十分な冗長化とオートフェールオーバー機能が利用できる。※Split Brain状態を防ぐため、オートフェールオーバーが機能するのは最初の 1台のダウンだけ。
Availability Zone Availability Zone
最小構成で 4 ノード、 4 ライセンス※ただし、バケット数の制限はないので複数の案件でクラスタを共有することは可能
Couchbase 社日本法人撤退しちゃった
特徴(地雷)
日本における先行きは不透明な感じ。特に Community 版の将来は日本語ドキュメント量にかかってきそう。
ただし、英語ドキュメントならそれなりにあるので頑張れば日本でのコミュニティーも存続できるかも!!
トランザクションレス
特徴(地雷)
Foundation DB という、NoSQL but ACID を標榜していた製品があったのですが、、、。
トランザクションレス• (NoSQL 製品では当たり前ですが、 ) トランザクション使えません。
• 複数のデータオブジェクト間のデータ整合性は取れません。※CAS は使える、 AtomicCounter も使える
• お客様にもいろいろ諦めて頂く必要がある。• 何を諦めて頂く必要があるかは具体的に全て洗い出して、個別で了承をとって頂く。• 、、、こうすれば NoSQL でもデータ整合性を担保できる系の記事は全部眉に唾つけて読んでいます。
• 全ての更新をキューに入れて、成功するまで更新操作を繰り返すという実装は不採用。※この方法でも新たに別の問題が発生するのでその問題を踏み抜くメリットとの相談。
トランザクションレスデータの更新順序などを厳密に定義して、それぞれの不整合状態を洗い出し、不整合発生後も自動的に修復を図れるようにアプリケーション側で全て実装する。※これを全てのデータ操作に関して定義、確認した上で実装も正しくされていることを担保する必要がある。
Doc A
Doc B
Doc C
Doc D
Doc A
更新中ステータスにする 更新 新規追加 削除 更新完了状態にする
この間で発生したデータ不整合は失敗とみなし、アプリケーションには失敗ステータスを返すこの間で発生したデータ不整合は成功とみなし、アプリケーションには成功ステータスを返す次回のアクセスで自動修復する
例
トランザクションレス構築されたシステム内のデータの整合性を基本的に信用出来ない。
• 外部システム側で発生したエラーも全て内部のデータ調査が必要となるが、 KVS なので都度調査スクリプトを作成する必要がある。
• 身の潔白を証明する責任が非常に大きい。(だいたい緊急調査)
• 最後のデータの突き合わせ調査が終わるまでは自分自身が疑心暗鬼。
• 実際に不整合データが発生していたら、場合によっては完全に終わる。→ データ不整合修正プログラムを作って頑張る。
データの中身の検索が弱い。Unique 制約等が貼れない。
特徴(地雷)
• データは JSON ドキュメントとして保存しますが、 JSON ドキュメント中の特定のvalue を利用しての検索ができません。( View という機能はあるけど非同期であり使いどころが難しい)
• また、 Value に対するユニークキーなども貼れないため、ユニークであることを担保するためには別に逆引きの Index ドキュメントを作成しなければなりません。(テーブル間のリレーション毎に逆引きのためのカラムを別途設ける)
• 上記の理由により、本来同一で良いドキュメントが複数に分割されますので、更新しなければならないドキュメント数は増えるのですが、ここで先程述べたトランザクションレスの呪いが降りかかります。
elasticsearch との連携ができるが、、、
特徴(地雷)
XDCR 機能で、 Couchbase の更新を全て elasticsearch にレプリケーションする事が可能だが、
実データ Index dataXDCRデータ更新
横断検索なんて出来ねぇよ!! 横断検索は任された!!
XDCR該当ドキュメントの更新さえすれば良い 該当ドキュメントを展開して各 value を Ngram でインデックス化古いインデックスも全て整理Couchbase の仕事量 << elasticserach の仕事量
検索要件を絞り込んでおかないと、全てに Index を張る必要が出てくるため、、、
• Couchbase の高い更新能力に elasticsearch の Index更新能力が全くついてこれない。• 当然大きなレプリケーション遅延が発生する。• ElasticSearch側の Index と Couchbase 上の実データの乖離が大きくなりすぎるのを
アプリケーションで担保しなければならなくなる。
→ 使えねぇ!!!!!ということで使いませんでした。→ じゃぁ、どうやって検索要件を満たしたかは後述
N1QL でクエリが使えるが、、、
特徴(地雷)
• N1QL を使うなら、 1 テーブル = 1 バケットの考え方で実装しておきたい。• JOIN が面倒、コストが高い( JOIN 先は必ず別のドキュメントのキーである必要がある)• 検索要件に合わせて Index を増やすと、物理メモリを大量に消費するので高コストとなる。• Select される結果セットが数万件以上になると異様に遅くなり実用に耐えない。
• すぐにタイムアウトする• Index更新が非同期で Select条件と得られる結果がズレたりする• 大量データの Export には向かない。
(巨大な JSON ドキュメントとして結果が得られる。落ちる、ページングしてる間にデータが更新される。)
• N1QL のご利用は計画的に
データの外部連携が面倒
特徴(地雷)
VIEW機能も使いにくいし、N1QL使っても大量データ出力には向かない。
→RDB(MySQL)にデータ連携しちゃえ
RDB なら• トランザクションが使える !!• 比較的安価• 柔軟な SQL があとからいくらでも書ける• 大量データ出力に強い (行フェッチが可能 )• 開発者多い• N1QL とは比較にならないくらい高速• レプリケーションも楽• 調査が楽• データの断面が取れる• ぶっちゃけ何やるにも楽
Couchbase のデータをRDB にレプリケーションしよう
RDBへのデータ連携が出来ると後が楽
外部システム A
外部システム B
S3
Embulk 等Semi RealtimeReplication
Couchbase 利用システム
横断検索Search API
FTPMySQL Replication
データ外部連携システム
外部システム C
※この API も外出しは可能
※更新差分データ提供
問題はここの部分だけ
Semi RealtimeReplication
Couchbase 利用システム
基本的な考え方1. Couchbase 上のドキュメントを更新する際にレプリケーション対象としたいドキュメント(※)には全て
_microtime という更新時刻を残すようにアプリケーションを構築する。※逆引き用 Index などはレプリケーション対象とする必要がないので不要。
2. 既に RDB に存在する最新の _microtime より新しい更新時刻を持つドキュメントを、 _microtime のより古い方から N 件取得する。( N1QL を利用する)
3. 上記のドキュメントを RDB 上の対応するテーブルに同一トランザクション内で Replace をかける。※失敗時にはロールバックさせて次のプロセスの処理対象とする。→ 2. へ戻る
レプリケーションをもう少し詳しく言うと、
N1QL で更新差分データのみを N 件抽出 例 :1000 件毎
Data Service
Index Service
非同期で Index更新
同一トランザクションで N 件全部 Replace
Couchbase 利用システム
Query Service
ところが、
N1QL で更新差分データのみを N 件抽出
Data Service
Index Service
非同期で Index更新
同一トランザクションで N 件全部 Replace
Index更新遅延
Couchbase 利用システム
Query Service
川
レプリケーションされないデータが出てきた。Couchbase 上の更新は N1QL の Index更新キューに積まれ、その後実際に Index が更新されるが、アプリケーション側から入れた _microtime は実際にキューに入った順番とは異なる可能性がある。 ※アプリケーションサーバが複数台あるため
この時、既にレプリケーションされたデータより古いデータが後から届くことがあるが、それは次回の検索対象とはならない。
Index更新の最終行付近のデータが信用出来ないので、 N1QL の Index更新が実際にはどこまで終わっているかを正確に知る必要がある。 → 更新チェック用のドキュメントを作成、それをバッチで毎秒更新した上で N1QL の Index 上の時刻を調査することで対応。した。
N1QL Index 上のデータ参照方法USE INDEX を利用したクエリを発行し、 SELECT の中身に INDEX 中で指定したカラムのみを指定することで、実データへのアクセスをせずに、 Index 上のデータを取得することが可能。( Explain で確かめる)
Explain SELECT max(_microtime)FROM `【バケット名】 ` USE INDEX (`idx_doctype_microtime`) WHERE doctype='N1QL_INDEX_CHECKER’;
→ “expr”: “cover((`accountpf-ph1`.`_microtime`))” となっている場合は、 Index 上のデータをそのまま利用している。そうなっていない場合は実データへのアクセスが発生している。
それでも、やっぱり RDBへの投入って遅れるよね
N1QL で更新差分データのみを N 件抽出
Data Service
Index Service
非同期で Index更新
同一トランザクションで N 件全部 Replaceデータ更新遅延
高負荷時においても5 分以内に更新完了
Couchbase 利用システム
Query Service
リソース使用状況(RDSレプリケーション用WRITEスループット)
予め couchbase バケットに対して各テーブル 1000万件程度のデータを投入していた状態のレプリケーション状況。RDS for MySQL を利用した場合、レプリケーション開始から暫くの間は数千records/sec でのレプリケーションがされるが、途中から Write Operation に上限が観測され、 300records/sec程度でのレプリケーションしか行えなくなっている。これをインスタンスタイプをスケールダウンし、 1000PIOPS を確保すると、スループットの向上が見受けられ、 2000req/sec程度のレプリケーションが可能となった。
MySQL r3.2xlarge MySQL m4.xlarge1000PIOPS
Write operation に上限が観測される
暫くは速い安いインスタンスのほうが速い
RDS for MySQL は高負荷状態が続くとWriteOperation 速度に制限がかかってしまう。※短期間の場合は OK であることに注意
→インスタンスタイプを下げてでも PIOPS を購入することでこの状態の解消が可能だが、この状態ではまだ遅い。
ついでに RDS for Aurora も試してやれ
リソース使用状況( RDS レプリケーション用ネットワークスループット)予め Couchbase バケットに対して各テーブル 1000万件程度のデータを投入していた状態のレプリケーション状況。※Aurora の方が安いインスタンス全体的に Aurora の方がスループットが高く、先にレプリケーションが完了していることがわかる。Aurora5 時間、 MySQL 9 時間
Aurora r3.xlarge
MySQL m4.xlarge
レプリケーション完了
リソース使用状況(レプリケーション用RDS空きメモリ)
Aurora の方が空きメモリに余裕がある状態であるため、検索用index がオンメモリとなることが多い。※どちらもメモリから落ちた時は検索にかなりの時間が必要となる。
Aurora r3.xlarge
MySQL m4.xlarge
Aurora なら安いインスタンスでもレプリケーション遅延がほとんど発生しない !!※フロントの API に対して数万 req/secの負荷試験を行っている状態。 (更新は数千 req/sec)
ベストソリューションの選定はやってみないとわからないので簡単なものならまずやってみよう。※試験段階なら、 RDS for MySQL と AURORA の変更はすぐ
ただし更新データの検知をレプリケーションするというこの方法では、物理削除されたデータがレプリケーション対象とならないことに注意する。
→ どうせ Couchbase 上でリレーションデータは相互に握っているのでそちらもレプリケーションさせて後から突き合わせる等の対策が必要。
結論重要なデータを NoSQL に格納するという使い方は、必要に迫られないかぎり敢えて手を出さないのが無難。でも、どうしても使いたい場合に CouchbaseServer は非常に良い選択肢となりうる。なぜならば、 Couchbase→MySQLへのレプリケーションをするというソリューションを手に入れたから。
素材は
http://www.irasutoya.com/さんのものを利用させて頂きました。