書籍
TL;DR
- NoSQLの全体像を俯瞰したい人に最適な本。(ゴリゴリ利用したいというアプリ開発者向けではない。)
- 3年以上前の本のため、各NoSQLについては自らUpdateが必要。
- ただ、NoSQLを選ぶときのポイントがまとめられており、このポイントを用いて自らUpdateすることができるのでそれだけでも一読の価値がある。
この本を選んだ理由
- NoSQLの利用用途って何だろう?と思っていた時に本屋で見かけた為。
印象に残った点
RDBが適さない理由が書かれている(2-1)
- RDBはデファクトスタンダードであり業務システムを作る上では最適な選択肢であることが多い
- しかしビジネスを拡大するために業務以外のデータを扱おうとすると、高速大量データや半構造データを扱うことが求められる
- これらのデータはRDBではうまく行かない
⇒この問題を解決するにはNoSQL
- 要件を踏まえ適切なDBを使う必要があるということか。最適解を導くためにはRDB以外の選択肢を学ぶ必要があるのか。ふむふむ。
NoSQLは大きく分けて3つに分類される(2-2)
- キーバリューストア(KVS)、ドキュメントDB、グラフDBの3パターン
- KVS
- スケールアウトして大量データに対するクエリを高速に応答できる。
- キーでアクセスするシンプルな使い方がメイン。
- ドキュメントDB
- KVSの特徴に加えてJSONを扱う機能が豊富。
- スキーマレスである特性も相まって開発効率がアップする可能性あり。
- グラフDB
- スケールアウトできないがRDB以上に複雑なデータ処理が可能
- データの複雑度とスケールアウトはトレードオフ
- 複雑度で並べると、KVS(キーバリュー)<KVS(ワイドカラム)<ドキュメントDB<RDB<グラフDB
- RDBに比べ複雑度が右なのか左なのかは覚えておくとよい
- NoSQLでも種類があるのか。適材適所で使い分けできるようにならなければいかんなぁ。
アプリ開発者/DB管理者/経営者目線でのNoSQLに対するメリット/デメリットがまとめらてれいる(2-3)
- アプリ開発者目線
- メリット
1. データにあったデータモデルを選択できる
⇒ JSONやグラフデータを無理してRDBに入れることでの工数増加
⇒ 直感的ではないクエリになってしまう
2. スキーマ定義をせずにデータを格納できる
⇒ スキーマが変わっても取り敢えずデータを貯めておけるのであとからのアプリ修正が可能
3. ドキュメントDBによる高速開発が可能
⇒ スクリプト言語とデータ構造がマッチしており、プロトタイプ時には向いている。
⇒ がっちり作るときはRDBを用いた手法を取ることがある。
- デメリット
1. KVSとドキュメントDBはRDBより機能が乏しい
⇒ スケールアウト性能を高めることで機能が落ちているところがある。
⇒ RDBに比べ何ができないかを理解して選択する必要がある。
2. KVSとドキュメントDBはトランザクションや整合性を保つ機能が使えない
⇒ スケールアウト性能の為の代償。トランザクションが必要であれば採用すべきではない。
⇒ ただ結果結合性という弱い整合性は提供している。
3. スキーマ管理をしないと何が入っているか分からなくなる
⇒ 最近はバリデーション機能があるものもある。
⇒ ただし、本番環境で利用するのであればスキーマ定義は管理したほうが良い。
- DB管理者目線
- メリット
1. KVSとドキュメントDBは性能増強が容易
⇒ メモリやCPUの増強、ストレージやクラスタ構成は不要で一般的なハードウェアを横に並べるだけで良い
2. KVSとドキュメントDBは高可用構成を簡単に構築できる
⇒ 一般的なハードウェアを横に並べてレプリケーションすること前提。
⇒ レプリケーションであれば標準機能でまかなえる。
- デメリット
1. トラブルシューティングが難しい
⇒ ノウハウの充実がRDBに比べて不十分なので有償サポート加入がオススメ。
2. 運用に関する機能が乏しい
⇒ クエリ統計や診断レポートの出力がなかったり、SQL実行計画を出す機能がない場合がある。
⇒ 作り込みする必要になることになる場合があり工数増加の可能性がある。
- 開発者目線
- メリット
1. KVSとドキュメントDBはハードウェア、ライセンスのコスト削減が期待できる
⇒ スケールアウトしやすいので流量が増えた時に買い増しが可能だがRDBであれば難しいし。
⇒ KVSやドキュメントDBであればOSSを使うことも可能
2. ドキュメントDBは開発生産性向上による新製品投入速度向上が期待できる
⇒ RDBに格納することが非効率なケースにおいてはドキュメントDBにすることで開発や保守の効率改善になる
- デメリット
1. 技術者の確保・育成に苦慮
⇒ 一般的なエンジニアがNoSQLを学習し、他人の力を借りずに本番運用をこなせるようになるのはかなり難易度が高い。
⇒ RDB利用するレベルのエンジニアであれば手が出ない。有償サポートを購入し、トレーニングすることがオススメ。
2. 開発の標準化が困難
⇒ スキーマレスなのでいかようにも格納でき、問い合わせ方もばらばら。性能問題のノウハウも蓄積されていない。
- 立場の違いからメリット/デメリット書いてあってとても良い!
- NoSQL学ぶのは敷居高いのか。相当ビビらせる記載になっている。
よくあるNoSQLの勘違いがかかれている(2-4)
- 「バッチが高速になる」は勘違い
⇒ ビッグデータのバッチ処理ができるのはHadoop
- 「トランザクションが高速になる」は勘違い
⇒ RDBのような厳密にACID特性を保証したNoSQLはない。
⇒ ACID特性とスケールアウトによる性能向上がトレードオフのため。
- 「ビッグデータを分析できる」は勘違い
⇒ ビッグデータの分析を得意とするのはHadoop。
- 「非構造データが効率的に扱える」は正解ではない
⇒ 「非構造データ=音声や動画といったマルチメディアデータ」でありNoSQLが扱うのは不得意。
⇒ 得意なのはJSONなど構造を事前に知ることができない「半構造データ」。
- 「RDBから置き換えると速くなる」は正解ではない
⇒ 正しく言うと「速くしたい処理が分散でき、かつその分散処理をできるNoSQLを使えればRDBより速い」。
⇒ NoSQLにも得手不得手があるので適した分散処理のNoSQLを選択して初めて速くできる。
- 「オープンソースしかない」は昔の話
⇒ クラウドサービスや商用製品もある。既存のRDBもJSONを格納できるNoSQLインターフェースがある。
- 「スキーマがない」は昔の話
⇒ スキーマ定義しないといけなかったり、バリデーションがあるNoSQLが出てきている。
⇒ 型のチェックができるようになっている
- 「SQLが使えない」は昔の話
⇒ NoSQLにてSQLライクな問い合わせ言語を提供してきている
- 非構造と半構造の差を知った。使いこなせていなかった。恥ずかしい。
- 既存のRDBもJSONを格納できるインターフェースあるのか!知らなかった。今度調べてみよう。
2つの軸によってDBは4つのエリアに分類できる(3-2)
- 2つの軸
1. ターンアラウンドタイム対スループット
2. スケールアウト性能
- 4つのエリア
スケールアウトできる
┃
4┃3
ターンアラウンドタイム重視 ━━━╋━━━ スループット重視
1┃2
┃
スケールアウトできない
1-1. RDB(OLTP)
⇒ OLTPとはOnline Transaction Processingの略でオンラインのCRUDをトランザクションとして処理する方法。
⇒ 一部を高速に処理できるが、全体に対する集計は苦手。
⇒ OracleやMicrosoft SQL Server、MySQLがこのエリア。
1-2. グラフDB
⇒ RDBでは表現が困難なつながりを表現し、複雑なクエリを高速に実行できる。
⇒ ただデータの結合度が高く、クエリやデータの分散が難しい。
⇒ ドキュメントDBに至る経緯とは全く異なる。Neo4j、OrientDBがこのエリア。
2. RDB(DWH)
⇒ DWHはデータウェアハウスの略。データの使い方がスループット重視。
⇒ Teradata、Oracle Exadata、AWSのRedshift、GCPのBig Queryがこのエリア。
⇒ ハードウェア含めてライセンスとして提供するものもある。
⇒ 列指向の性質を持っており、列ごとにデータを圧縮している。
3. Hadoop(HDFS+MapReduce)
⇒ Hadoopという名のソフトがあるわけではなく、あくまでフレームワーク。
⇒ 分散システムであるHDFS、そのうえで動く分散集計フレームワークMapReduceなどのソフトウェアが連動し、スケールアウトして集計する。
⇒ Apache HadoopやAWS Elastic MapReduce、Oracle Big Data Aplianceなどががこのエリア。
4-1. KVS
⇒ スケールアウトして処理を分散する。
⇒ オンラインでビッグデータに対するランダムなCRUDに対して短いターンアラウンドタイムで応答可能。
⇒ データ間が疎結合であり分散配置しやすい。
⇒ Cassandra、Redis、DynamoDB、Google Datastoreなどがこのエリア。
4-2. ドキュメントDB
⇒ KVSと同様にオンラインでオペレーションを行う点では同じだが、格納がJSONであり、JSONに特化した機能を持つ。
⇒ MongoDBやMicrosoft Azure DocumentDBなどがこのエリア。
RDB(OLTP)とKVS/DocDBの違い(3-3)
- RDB(OLTP)は強い整合性があるが、その整合性を保ったままではスケールアウトできない
- 強い整合性を保つための機能がトランザクションであり、トランザクションはACID特性を持つ
1. 原子性(Atomicity)
⇒ トランザクションに含まれる操作は全て行われるか行われないかのいずれか。
2. 整合性(Consistency)
⇒ トランザクションがDBに課した整合性ルールを満たすことを保証。
⇒ ルールを満たさないトランザクションは失敗させる。
3. 独立性(Isolation)
⇒ トランザクション同士が互いに影響を与えることはない。
4. 永続性(Durability)
⇒ コンピュータがクラッシュしても成功したトランザクションの結果は失われない。
- 強い整合性を保つために「2フェーズコミット」の手法を用いている
⇒ 2つのノードがある場合、両方の準備が整った返答を受けてから一斉にコミットする。
⇒ したがって、台数が多くなるほど応答が遅くなる。
- KVS/DocDBでは3つの工夫で性能をスケールさせている
1. 分散トランザクションを提供しない
⇒ 代わりにクエリを分散する「シャーディング」が可能。
⇒ 複数のノードを更新が必要な場合でもバラバラにクエリを実行できる。
⇒ ACID特性の独立性が守られないため強い整合性は保たれない。
2. 分散しやすいデータ構造とクエリだけを提供する
⇒ データ間に関連がないため分散しやすい構造。
⇒ クエリもキーで問い合わせるだけのシンプルなモノであり、処理は確実に1つのノードで完結する。
3. 強い整合性を犠牲にして、データの複製に対して読み書きする
⇒ データを複製する「レプリケーション」によりアプリケーションの応答とは非同期でデータ同期する。
⇒ そのため、一時的に正しくない答えになることになったり、同時更新によりどちらが正しいか分からなくなったりする。
⇒ ただ、最終的には整合性が取れる「結果整合性」にはなる。
- KVS/DocDBの思想はACID特性になぞらえはBASE特性と呼ばれる
1. どんな時でも動く(Basically Availability)
2. 常に整合性を保っている必要はない(Soft-state)
3. 結果として整合性が取れる状態に至る(Eventual Consistency)
- CAPの定理
- Consistency(整合性)、Availability(可用性)、tolerance to network Partitions(分断耐性)の3つのうち最大2つまでしか満たすことができないという定理
1. C(整合性):全てのノードで同時に同じデータが見える。「強い整合性」と同義。
2. A(可用性):単一障害など一部のノードの障害が起きても処理の継続性が失われない
3. P(分断耐性):ノード群までネットワークが分断されても正しく動作する
- CA特性を持つシステムの特徴
⇒ シンプルなActive-Standbyのクラスタ構成DB。RDB(OLTP)が該当。
- CP特性を持つシステムの特徴
⇒ 奇数台のクラスタで構成する
⇒ ネットワークが切れた時にクラスタの過半数より多くのノードと通信できる集団を生きているクラスタとして動作させ続ける
⇒ しかし、残ったクラスタは利用できなくなるため可用性が下がる。
⇒ Redis、MongoDB、HBaseがこの特性を備える。
- AP特性を持つシステムの特徴
⇒ ネットワークが切れてもクラスタを構成する全てのノードで読み書きが可能。イメージとしてはGit。
⇒ 同じデータに対して複数のクライアントで書き込みをするため、古いデータがみえたり、書き込みが競合する可能がある。
⇒ 整合性は保たれないが、競合が発生することを前提として設計されているため、動作を停止させるような事態にならない。
⇒ Cassandra、CouchDB、DynamoDBがこの特性を備える。
- ACID特性の細部まで理解していなかったので良い勉強になった。
- 結果整合性か。結果整合性が正しければ許されるのであればKVSやDocDBを使っても良いのだろう。要件次第ですなぁ。
- BASE特性か。KVSやDocDBの強みを説明する上で重要な言葉だなぁ。覚えておこう。
- CAP定理言わんとすることは分かるが、新たな製品をみてどこに分類されるか分かる自身がない。
HadoopとKVS/DocDBの違い(3-4)
- Hadoopの動作
1. データを分散ファイルシステムに書き込む
2. 分散ファイルシステムは各ノードにファイルを分割する
3. 分散処理フレームワークにプログラムを提出する
4. コーディネータが各ノードにプログラムを各ノードにばら撒く
5. プログラムを各ノードで実行
6. 各ノードで順次計算が終わるとコーディネータが結果を集める
7. 最終的な計算結果を分散ファイルシステムに格納する
⇒ 書き込みは1回、読み込みは多数。実行してから答えが出るまで時間がかかるバッチ処理。
- KVS/DocDBの動作
1. データを分散して格納する(シャードノード)
2. CRUDオペレーションの為にクエリルータにクエリを投げる
3. アプリケーションは同期処理のためクエリ応答を待つ
4. クエリルータはデータのキー値によって適切なシャードを選出し、シャードにてクエリを実行
⇒ ターンアラウンドタイムは数ミリ秒。クエリ実行中にシャードがダウンするとエラーになるものもある。
- 全データを舐める処理は確かにKVS/DocDBのやりたいことからはズレますなぁ。何をやりたいNoSQLなのか?理解して採用しないとアカン。
各NoSQLの説明が機能/非機能の観点からまとめられている(6〜13)
- 概要、機能(データモデル/API)、非機構(性能拡張/高可用/運用/セキュリティ/できないこと/主なバージョンと特徴/国内のサポート体制/ライセンス体系/効果的な学習方法)として決められた観点からまとめている
- 対象プロダクトは下記8つ
- Redis
- Cassandra
- HBase
- Amazon DynamoDB
- MongoDB
- Couchbase
- Microsoft Azure DocumentDB
- Neo4j
- 決まった観点から複数のではプロダクトを説明しておりメリット/デメリットが分かりやすい
- ただ、発行から3年半ほど経っているで色々と変わってそう。この本で概略を掴んでから更に詳しい本を読むのが良さそう。
- Cassandraすげー。有償のものもあるが運用面だけみれば何でも出来る。RDBにあるトランザクション、ロールバック、ロック、SQL関数、結合、外部キー、ストアドプロシージャはないが、そういう用途で使うものではないので問題ないのだろう。悪い事書かれてないなぁ。
- HBaseの設計思想はテーブル定義は列ファミリのみ定義し、列名はアプリケーションの実装段階(データの格納時)に決めるのか。面白い考え。
- DynamoDBは13個のAPI、複数行更新のためにBatch API用意しているのか。自分でFaaS作る時の名前の付け方参考にもなるなぁ。
- MongoDBはJSONスキーマの事前チェックが可能なのか。決まった構造だけを対象にできることはメリットがあるだろうなぁ。
- インデックスの種類や属性も色々用意されてるなぁ。地理空間のインデックスなんてあるんだ。
- Couchbaseはクラウド、オンプレ、更にモバイルまでカバーするものが特徴。
- SQLライクなクエリ(N1QL)でJSONのフレキシブルなモデルの問い合わせが出来ることが大きなメリットだと感じた。
- Microsoft Azure DocumentDBは昔REST APIアクセスする際のURLに内部で自動生成されるリソースID使っていたらしい。途中でユーザ設定可能なIDを使えるようになったらしいが、最初の仕組みはどう考えても辛い。
- デフォルトだと全てのドキュメントプロパティに同期的にインデックスを貼るとのこと。デフォルト運用はしないんだろなぁ。
- DocumentDB SQL、ストアドプロシージャ、トリガなどを見てもRDBと遜色なく触れそう。しかもストアドプロシージャやトリガなどはJavaScriptで書くのか。書きやすそう。
- CosmosDBに名前変わってるのか。DB-Enginsのランキングに載ってないわけだ。
- 整合性が強い整合性から結果整合性まで4種類提供している。ほぇー、選べるなんてすごい。
- わ
- と思い調べてみたら、いくつものグラフDBではクエリ言語としてGermlinがサポートされているらしい。
NoSQLを利用するユースケースが多数紹介されている(14)
- Redisのユースケース
- Webアプリケーションキャッシュとして利用する
- WebアプリケーションとRDBが直接やり取りするとRDB部分がボトルネックになる。
- Redisにキャッシュを格納しておき、Webアプリケーションはまず最初にRedisに問い合わせる。
- キャッシュになければRDBに問い合わせし、その結果をキャッシュする。同様なクエリを何度も発行する場合に効果的。
- RDBのスケールアウトしづらさをRediusによってレプリケーションによる容易なスケールアウトが可能となる。
- Casandraのユースケース
- 時系列データを横持ち(列追加)にして扱う
- IoTの場合、毎秒データを挿入するケースがあり、センサーが増えると爆発的に増える。
- RDBだとレコードを挿入する形になり、パフォーマンスを維持することが難しい。
- Casandraであれば20億カラムまで1行に持たせられ、毎秒更新、毎分更新なども1行にあ納められる。
- MongoDBのユースケース
- ログ格納システムに利用する
- RDBだとフォーマットがバラバラなログを集約しようとするとテーブル定義が大変、スケールアウトが大変、トランザクション、結合、ストアドプロシージャなど高度な機能はオーバースペック。
- Hadoopだと即応性が低い。その要件がなければHadoopでもよい。
- 他のNoSQLでも良いがFluentdとの組み合わせを考えると最も適切。
- ECサイトのカタログ管理に利用する
- ECサイトはアイテムをDBに格納するが属性が異なることが多い。RDBを利用して格納すると属性変更になり重いクエリを発行しないといけないだけではなく、アイテムが増えた際の応答速度向上のスケールアップが大変。
- MongoDBによりアイテムをJSONで入れれば属性変更が容易でかつ、アイテム増加もシャーディングで対応できる。
- JSONにすることでIT知識が少ない人でも生データからレビューが可能となり、開発の生産性向上にもつながる。
- Couchbaseのユースケース
- モバイルとサーバのデータ同期に利用する
- 従来型だとサーバサイドでDBにアクセスするためのAPIサーバが必要だったり、電波が不安定や届かない場所だとアプリが全く使えない問題がある。
- Couchbase Liteを使うことでローカルデータベースをモバイルアプリに組み込み、ネットワークの接続状況に依存せず稼働できる。サーバとの同期も用意されているため自作不要。
- Neo4jのユースケース
- リアルタイム詐欺検出に利用する
- IP、クレジットカード、ID、クッキーの関連性をグラフ化することで、取引パターンが違いを検出できる。
- RDBでは結合のコストが高く、SQLクエリだけで記述が困難。
- 適材人材の検索システムに利用する
- 人材データ(経験年数、スキルセットなど)をグラフデータベースに入れ、適合度を計算する。
- RDBだとテーブル設計の煩雑さに加え、結合、入れ子など複雑なSQLになり、性能が出ないという問題になる。
- なるほどー、最初にRedisのキャッシュにアクセスさせるのか。
- 時系列データを横持ちにするのか。これはRDBではできない。
- ログ格納システムにてRDBを使うとツラミが多く、NoSQLのウマミがよく出せる。Fluentdとの相性を考えると他のNoSQLより沢山の実績があり、公式にも接続方法の記載があるためMongoDBになるのか。
- ECサイトの例はRDBとNoSQLのメリットが分かる良い例だなぁ。ハイブリットにしアプリケーション側からは意識しないで使える仕組みにするのか。
- FirebaseとCouchbaseのモバイル対応は似てるなぁ。この考えがモバイル対応の王道なのかも知れない。
- グラフDBは経路検索などのグラフの問題を解く為だけではなく、異常系パターンの検知、パターンの適合度などに使えるのか。
RDB(OLTP)⇒NoSQLにより解決できない/できるかわからない/できるの3つの観点からまとめられている(15-1)
- 大前提として現状のデータ処理に課題があるかないかにフォーカスし、課題がなければ検討しなくて良い。
- 解決できない
1. バッチ処理性能向上
⇒ シャーディングにより性能向上はするかもしれないが、HadoopやRDB(DWH)を利用すべき。
2. データローディング処理性能向上
⇒ 分析のためのデータローディングであればRDB(DWH)が得意。用途が違う。
- 解決できるかわからない
1. トランザクション処理性能向上
⇒ 厳密なACID特性が必要であれば解決できない。
⇒ ただし、1つのJSONとして管理できるのであればACID特性に対応したNoSQLを採用して解決できる。
2. パフォーマンスチューニング簡素化
⇒ NoSQLはそもそも複雑なクエリは実行できないのでチューニング問題が発生しづらい。
⇒ またスケールアウトも簡単なので割り切った考えができる。
3. 非構造データの処理のしやすさ
⇒ JSONやXMLのような半構造データが得意
⇒ 少容量のデータの出し入れに向いているをマルチメディアデータは外に置き、メタデータを格納するのが一般的。
4. 運用管理コストの削減
⇒ クラウドであれば初期構築、運用のコスト削減は期待できる。
⇒ ただ、NoSQLは知見が少なくトラブルシューティングのコストは増加する。
⇒ スケールアウト前提に作られているため性能拡張によるコストは削減できる。
- 解決できる
1. クエリ検索の性能向上&データレイテンシ改善
⇒ ボトルネックをシャーディングにより分散できるなら効果がある。
⇒ RDB(OLTP)の性能改善余地があるのにNoSQLを前提とするのは間違い。
2. 初期導入コストの削減
⇒ スケールアウト前提なのでスモールスタート可能
⇒ システム規模に応じて後からサーバ台数の増加でカバーできる。
- 現状のデータ処理に課題がなければNoSQLの採用を検討する必要がないと断言されている。会社なので利益にならないことするな的なのとも書いてあり刺さるわぁー。
- まずはRDB(OLTP)で出来ることをやる。を念頭にしていきたい。
処理性能や半構造データの処理のしやすさによる選び方などがまとめられている(15-1〜15-4)
NoSQLを選ぶときのポイントがまとめられている(15-5)
- 下記の差別化になる特徴に着目すると良い
- データモデル
- データモデルは何か?
- データ型は何に対応しているか?
- データ構造の事前定義は必要か?
- API
- クエリはどのような言語か?SQLライクか?
- トランザクションがあるか?
- ACID特性をどこまで保証しているか?
- セカンダリインデックスがあるか?
- EXPLAIN句やHINT句があるか?
- 条件検索、ソート、LIMIT、集計、結合、データの部分更新があるか?
- クエリの整合性は調整できるか?
- 性能拡張
- どのようにデータを分散するのか?ハッシュかレンジか?
- どうやってクエリを分散するのか?
- データの再配置が自動でできるのか?
- 複製に対する書き込みができるか?
- 高可用
- レプリケーションはマスタースレーブか?マルチマスターか?
- 原子性をもった更新はどの単位か?
- 運用
- ツールはCUIベースか?GUIベースか?
- 監視やバックアップは自動でできるか?
- デプロイメントの自動化ができるか?
- クエリのプロファイラはあるか?
- セキュリティ
- 細かいアクセスコントロール、監査ができるか?
- その他
- 国内サポートを受けられるか?
- どれくらい使われているか?事例はあるか?
- この観点表だけでも十分な価値がある。関係者へNoSQL導入を説明するために最適だ。
今後
- NoSQLにて解決したいことは何なのか?そこが不明確なのであればNoSQLを導入することに意味がないことをこの本より学んだ。
- まずは業務で利用するRDBについて深く学ぶことが必要だと感じた。