はじめに
この記事では、インメモリDBという技術について検討します。
また、その具体的な実現としてOracle Coherence、Redis、Couchbaseを取り上げます。
とはいえ、これらのいずれに優劣があるか(インメモリDBからいずれを選択すべきか)について結論することを意図しているのではなく、数あるデータベースの1カテゴリーである、インメモリDB「という」選択肢について、認識を深め、(競争力を高めるために、どのようなテクノロジーを採用すべきか、というビジネス的な観点も含め)システム開発にフィードバックできる知見を示せれば、と考えています。
ここで扱うデータベースは、いずれもインメモリ分散KVS(キーバリューストア)というカテゴリーに入ります。
また、全てコミュニティエディションの存在するOSSベースのソフトウェアでもあります。
インメモリ分散KVSについて
「インメモリ」というキーワードで、端的に連想されるのは、あるいはパフォーマンスということになるかもしれませんが、ここではより具体的に、「応答」性能を中心に検討します。
また、「メモリにデータを格納」という特徴の表現では、RDBであっても内部にキャッシュを持ちうることとの差別化が十分でないため、「ディスクへの制約がない」という観点で捉える方が、より適切と言えると思われます。
厄介なのは、「分散」というキーワードで、同じくパフォーマンスという観点で語られる(語られてしまう)こともあるとはいえ、実情は単純ではなく、一旦ここでは置きます。
「KVS(Key-Value Store)」は、字義的には、キーつまり一意のIDでデータにアクセスする(ことができるようにデータを格納している)、ということになりますが、つまりはこれも、応答性能を極限まで高めるための単純化と把握することができます。つまり、システムの性能を上げるためには、ハードウェアやネットワーク含め、(ソフトウェアを変えずに)可能な様々な方法がある一方、ソフトウェア設計でしか実現できないレベル(破れない壁)もあり、それに対する一つの解を表現していると言えます。
最も「分散KVS」を「分散」と「KVS」に切り離すことにも無理があります(実際、分散アーキテクチャーを採用していないKVSを考えるのは難しい)し、「KVS」というターム自体、エンジニア観点からは明確な定義である一方、技術選択上の判断という意味では、喚起するところが少なく思われ、(タイトル及び)以下「インメモリDB」という呼称を用いています。
インメモリDBとデータ永続化
インメモリDBの目的を一旦、データ層の応答性能の最大化と考えた場合(つまり、単にアプリケーション層のキャッシュを実現するだけ「分散キャッシュ」と呼ばれるもの、と区別した場合には)、データの永続化という課題が浮かび上がります。
データ永続化パターン
キャッシュ・アサイド
アプリケーションは、データへの要求を受けた際に、データがキャッシュの中にあるか調べ、なければデータベースからロードし、将来の別の要求のためにキャッシュの中に保存する。
リード・スルー
アプリケーションにとって、キャッシュ層がインターフェイスとして、キャッシュ層が、データへの読み込み要求を受けた際に、データがキャッシュの中にあるか調べ、なければデータベースからロードし、将来の別の要求のためにキャッシュの中に保存する。
これにより、キャッシュ層における最適化(例えばデータのプリフェッチ)が可能になる。
ライト・スルー
アプリケーションにとって、キャッシュ層がインターフェイスとして、キャッシュ層が、データへの書き込み要求を受けた際に、データベースへの書き込みと、キャッシュの更新を同時に行う。
ライト・ビハインド
キャッシュ層がアプリケーションのインターフェイスとなるのは、ライト・スルーと同様だが、キャッシュ層にキュー/スレッドを備え、アプリケーションとキャッシュ層との関係(レスポンスタイム、スケーラビリティ)と、データベースとの関係を非同期とする。このことで、同一エントリへの複数の更新がバッチとしてまとめられる、データベースの障害との直接の影響関係を取り除く、などの利点が生じる。
インメモリDBとデータ復旧
データ永続化の課題を、キャッシュ層の障害の際のデータ復旧のためのバックアップという観点で捉えることもできます。
本稿の全体の趣旨からは傍系的になりますが、基礎的な要素として押さえておきたいと思います。
データ復旧のための機能
スナップショット
定点におけるデータをバックアップファイルとして保存する機能
書き込みログ
RDBにおけるいわゆるWAL/REDOログ。Redisでは、AOF (Append Only File)と呼ばれる。
インメモリDB概観
Oracle Coherence
Oracle Coherenceでは、上記のデータ永続化パターン(リード/ライト・スルー、ライト・ビハインド)を想定した実装手法が確定されている。
Redis
RedisをMongoDBと連携する場合には、cdata社のCData Syncを利用することができる。
Couchbase
上記見てきたように、インメモリDBにとって、今使っているデータがメモリ上にあることを意識することが欠かせず、ディスクへの永続化は、ユーザの選択により実現されます。
ここで、Couchbaseのユニークなところは、メモリ「ファースト」アーキテクチャの採用にあります。
ユーザは、メモリ上のデータへのアクセス、ディスク制約からの開放、による応答性能を享受しながら、データは、あたかもごく一般的なデータベースのように、ディスク上にも保存されている状態が、「シングルプラットフォーム」で実現されています(ここで、「シングルプラットフォーム」といったのは、このようなキャッシュと永続化の両方を満たすための典型的なアーキテクチャーとして、キャッシュレイヤーと永続化レイヤーを二つの異なるテクノロジーによって実現するケースとの対照として)。
この場合、内部的な実装は、いわば「ライト・ビハインド」のパターンに相当しますが、一貫性(Durability)要件に応じ、ディスクおよび複製に対して、同期的に更新するオプションを提供しています(オプションの選択はAPIコール単位であり、システム全体で、ライト・スルーかライト・ビハインドかを選ぶ必要はありません)。
以下に、以上説明したアーキテクチャーのイメージを示します(画像は、Couchbase Under the Hood: An Architectural Overviewより引用)。
キャッシュ・アサイドでの利用
既存システムのデータ層の応答性能向上のために、既存のデータベースを残したまま、アプリケーションにてキャッシュ・アサイドの実装を行い、キャッシュ層としてCouchbaseを利用するというユースケースも多く紹介されています。
永続化要件のないケースでの利用
また、永続化要件のないデータの扱いについても、サポートしています。これは、「バケット」と呼ばれるデータ格納単位の作成時にEphemeral(一時的)バケットとして作成することによって実現されます(Couchbaseは、Memcachedプロジェクトのメンバーにより開発されたMembaseをその前身としており、Memcachedのユースケースへの適応が意識されています)。
最後に
インメモリDBを「データ永続化との関係」という一側面から検討しました。筆者の持つ情報・経験から、内容的には不十分なものであることを自覚しています。各種データベースのテクノロジーへのアプローチの違いについては、ユースケースとの関係から検討されなければならないはずであり、こちらについては、また別の記事として整理できればよいと考えています。