ゲームで使うクラウド四方山話

著:古庄道明氏

RDBMSの基本とNoSQL その3第06回 17年05月更新

みなさん、こんにちは。エンジニアの古庄道明です。
今回は「RDBでは満たしにくかったニーズを満たすべく作られた」NoSQL(Not only SQL)と呼ばれるものたち、について
書いていきたいと思います。

さて、このNoSQL(Not only SQL)ですが、この単語の意味合いは比較的「広範囲な様々な技術を含む」、言ってしまうと、
些か「荒っぽい」分類になります。
本稿のその1、その2で書いていましたRDB、というのは、便利さの加減などからも「データを適切にCRUDするならRDBだよね!」
という、選択肢があまりない状態でした。
ただ、そんなRDBも、その1で書いた通り「CAP定理に沿って考えた場合に「分断耐性がない」事、トランザクションや
柔軟なSQL文のために「重かったり遅かったりする」事がRDBの主だった欠点」として出てきて、また、そういった問題点が、
ニーズや背景、システムによっては「無視できない」レベルになってくるケースも出てきました。
そういった背景から「RDB以外のDBがあってもいいんじゃないだろうか?」といった感じの流れで、色々と出てきています。
そんな経緯で出てきたものが「NoSQL(Not only SQL)」になります。

なお。
厳密には「NoSQ(Not only SQL)であって、NoRDB(Not only RDB)ではない」のですが。
現状出ているほとんどの製品が「RDBのデータベース言語としてSQLを使っている」という実情があるので、
「SQL≒RDB」という理解で、とりあえず差し障りないか、と思います。

話を戻しまして。

「RDBが得手としている」部分はもちろんRDBにこれまで通りお願いする、という方針でよいか、と思うのですが。
特に規模が大きくなってくると「RDBに適さない情報」については、場合によっては「学習/検証/作成/修正コストをかけてでも、
RDB以外にデータを保存していたほうが、トータルとしてメリットが高い」可能性、というものが出てきます。
そんな経緯から出てきたNoSQLなので、色々な切り口のNoSQLがあるのですが。
比較的メジャーなものを、いくつかかいつまんで説明できれば、と思います。

なお、前提としまして。
これは「RDBがそれを不得手としている」ところからきているのだと思うのですが、ほとんどのNoSQL製品は
「スケールアウトが可能な、分散型に耐えられる」設計をしていますので、
説明にはそのあたりを付加して読んでいただければ、と思います。

ドキュメント型DB、というものがありまして、代表的な製品に「MongoDB」などがあります。
RDBが「あらかじめ決まったフォーマットのテーブルを用意し、そのテーブルにデータを格納していく」のに対して、
MongoDBは「ドキュメント、と呼ばれる(JSON構造の)データの集合を、コレクションという形で格納していく」形式になります。
この「ドキュメント」は、理論上は「全く異なるフォーマット」を「1つのコレクションにまとめて入れる」事も可能になります。
実際に「なんの関係もなく、フォーマットの規則性もない」ようなものを入れると問題が発生するのでやりませんが。
例えば「各サービスのログ情報」といったような、「ログ、という程度には類似性があるが、あちこちのサービスでフォーマットや
記述内容が必ずしも統一されていないもの」をひとまとめにする、といったやり方には、非常に便利なものかと思います。

もう一つ、KVS(Key-Value Store)というものがありまして、おそらく、NoSQLと聞いて一番初めにKVSをイメージされる方も、
少なからずいらっしゃるのではないか、と思います。
KVSで、もっとも有名なのは、memcachedかと思われます。
memcachedは基本的に
・複数(1台以上)のマシン上に分散された巨大な、インメモリのハッシュテーブルを提供する
・データは寿命を指定する事ができ、「寿命を超えたデータ」は適宜、破棄される
・テーブル(割り当てられたメモリ)があふれそうな場合、「使われていない古いデータ」が順次削除される
・クエリは「このkeyに対応するvalueをよこせ」「このkeyに対応するvalueに加算/減算せよ」くらいしかない
という感じになります。「非常に単純な機能しか提供しない」事と引き換えに「ものすごい速度」が出るように作られています。

memcachedは文字通り「memory上に展開されているcache」なので。
マシン(正確には該当プロセス)が落ちてしまえばデータは霧散します。だからこその「cache」なのですが。
このmemcachedを「正式なデータ保存場所」として考えると色々と手痛いのですが。実際のWebアプリケーション、
特にゲームにおいては「該当する(primary)keyと合致する1データをSELECT」というクエリは非常に発行回数が多いので、
こういったSELECTの機構に一枚はさんで「cacheさせる」といった用途で使うと、高い性能アップが見込まれます。

なお、memcachedは「インメモリなので、マシン(該当プロセス)が落ちたらアウト」であったり、
また「データを冗長して持っていない」などの、「高速と引き換えに捨てたもの」も、決して少なくはないので。
「単純なアクセスで高速なものが欲しいんだけど、とはいえ”引き換えに捨てたもの”のいくつかは必要としている」という場合は、
repcached、Redis、Apache Cassandra、TokyoTyrant、MySQL InnoDB Memcached、などのプロダクトもあり、
一部については「データをHDDに書き込んで、データを永続させる機能」があったりもしますので。
「小さなプロダクト」のうちはよいのですが、プロダクトが大きくなってきたら、必要に応じて「RDBとの間にcacheをはさむ」
「ほかのDB製品に情報を格納する」といった事を、検討事項の1項目として入れておく、というのも、重要な技術的知見かと思います。

RDBMSの基本とNoSQLについて筆を重ねてきましたが。
次回からは「RDBのまま、重たい状況をどう打開するか」について書いていきたいと思います。