今回からは数回にわたり、代表的なNoSQLプロダクトである「Amazon DynamoDB」や「Apache Cassandra」、「Amazon ElastiCache」へアクセスするSpringアプリケーションを開発する方法について、以下のステップに沿ってわかりやすく解説していきます。

1. NoSQLデータベースの特徴とデータ特性
 ・CAP定理を元にしたデータベースの分類とデータ特性
 ・AP型データベースAmazon DynamoDBとApache Cassandraの特徴
2. Amazon DynamoDBへアクセスするSpringアプリケーション
 ・Amazon DynamoDBの概要及び構築と認証情報の作成
 ・Spring Data DynamoDBを用いたアプリケーション(1)
 ・Spring Data DynamoDBを用いたアプリケーション(2)
3. Apache CassandraへアクセスするSpringアプリケーション
 ・Apache Cassandraの概要及びローカル環境構築
 ・Spring Data Cassandraを用いたアプリケーション(1)
 ・Spring Data Cassandraを用いたアプリケーション(2)
4. Amazon ElastiCacheへアクセスするSpringアプリケーション
 ・AmazonElasiCacheの概要及びローカル環境でのRedisServer構築
 ・Spring SessionとSpring Data Redisを用いたアプリケーション(1)
 ・Spring SessionとSpring Data Redisを用いたアプリケーション(2)
 ・Amazon ElastiCacheの設定
 ・セッション共有するECSアプリケーションの構築(1)
 ・セッション共有するECSアプリケーションの構築(2)

なお、解説にあたっては以下の前提知識がある開発者を想定しています。

対象読者 前提知識
エンタープライズ開発者 Java言語及びSpringFrameworkを使った開発に従事したことがある経験者。経験がなければ、こちらのチュートリアルを実施することを推奨します。TERASOLUNAはSpringのベストプラクティスをまとめた開発方法論で、このチュートリアルでは、JavaやSpring Frameworkを使った開発に必要な最低限の知識を得ることができます
GitHubなどのバージョン管理ツールやApache Mavenなどのライブラリ管理ツールを使った開発に従事したことがある経験者
AWS開発経験者 AWSアカウントを持ち、コンソール上で各サービスを実行したことがある経験者
コンテナおよびUNIX/Linux経験者 Dockerなどのコンテナ技術を使用した経験がある、またはPOSIXコマンドによるUNIX、Linux系OSを操作したことがある経験者

また、動作環境は以下のバージョンで実施しています。

動作対象 バージョン
Java 1.8
Spring Boot 2.1.2.RELEASE
Spring Data DynamoDB 5.0.1
Spring Data Cassandra 2.1.2.RELEASE
Spring Session 2.1.4.RELEASE
Spring Data Redis 2.1.5.RELEASE
Docker 18.09.2, build 6247962
CentOS 7.6.1810
Apache Cassandra 3.0.6
Redis(Local) 3.2.12
ElastiCache(Redis) 5.0.3

将来的には、AWSコンソール上の画面イメージや操作、バージョンアップによりJavaのソースコード内で使用するクラスが異なる可能性があります。

NoSQLデータベースの特徴とデータ特性

リレーショナルデータベース(RDB)と対比して、NoSQLデータベースでは、キーバリュー型やドキュメント指向型、カラム指向型、グラフ指向型など、機能や特徴によっていくつかの分類方法があります。そのなかの1つが、分散データベースという観点から分類する方法です。この分類の基礎となる考え方が、「ブリューワのCAP定理」と呼ばれる、広域に分散した環境下におけるデータベース・サービスに関する理論です。後々、保存に適したデータ特性やデータモデルの検討にも関係してくるので、ここで基礎的な内容を押さえておきましょう。

CAP定理は、限定的な条件が前提にはなるのですが、「広域な環境で分散してデータを保存する場合に、以下の3つの特性のうち、2つまでしか同時に満たすことができない」という定理です

※ 3つのうち常に2つが満たされるわけではなく、「原則として2つの特性を重視すると残りの1つが失われる」と捉えたほうがよいでしょう。

特性 概要
一貫性(Consistency) あるデータに対する読み取りは、どのノードにおいても、必ずそのデータの最も新しい書き込みの結果を返すか、エラーを返す
可用性(Availability) システムを構成するノードに障害が発生していたとしても、常に読み込みと書き込みが可能である
ネットワーク分断耐性 (Partition Tolerance) システムを構成するノード間の通信が一時的に分断されても、機能が継続される

この観点からデータベース全体を分類すると、RDBは一貫性(Consistency)と可用性(Availability)を重視したCA型のデータベースということになります。

定理を説明する単純な例としては、広域(複数のアベイラビリティゾーン)を跨いで、都市名データをキーと共に都市テーブルへ保存することを考えるとわかりやすいでしょう。こうした分散された環境下では、RDBは、以下のいずれかの方法でデータベース間の同期をとりながら更新するケースが一般的です。

上記では、単純化のために2つのアベイラビリティゾーンに限定していますが、複数のゾーンにあるデータは、いずれも常に最新のデータを返し(Consistencyが保証される)、「複数同時に壊れる」というまれなケースを除いて、片方のノードで障害が発生しても可用性(Availability)が保証されます。

ただし、この構成はネットワークが分断されると、一貫性/可用性共に崩れてしまいます。実際にはネットワークも二重化などの対策が取られているので障害になることはまれですが、ゾーン間の通信が使用不能になると、CA型データベースとしては機能不全に陥ります。つまり、一貫性/可用性を保ちつつ、同時にネットワーク分断耐性を満たすことはできません。

他方、可用性(Availability)を下げることをトレードオフとして、一貫性(Consistency)とネットワーク分断耐性(Partition Tolerance)を高める手法もあります(CP型)。データを複数のアベイラビリティゾーン(の別ノード)に分けて保存する方式で、一般的にこの方法はシャーディング(Sharding)と呼ばれます。

シャーディングは、どちらかと言えば性能向上を目的とした負荷分散のためにRDBなどでもよく利用される手法です。特定のデータノードが一時的に分断されても一貫性(Consistency)は保持されます。ただし、ノードの数が増えることで故障確率が上昇し、読み込みと書き込みが制限され、可用性(Availability)が損なわれる確率が上がります。このシャーディングを機能として備えるデータベースとして有名なプロダクトとしては、「Apache HBase」や「MongoDB」、「Redis」などが挙げられます。

最後に、一貫性(Consistency)を下げることをトレードオフとして、高い可用性(Availability)とネットワーク分断耐性(Partition Tolerance)を持つAP型のデータベースの代表例が、「Amazon DynamoDB」「Apache Cassandra」です。

AP型データベースでは、以下のイメージのように、複数のアベイラビリティゾーンにデータベースを配置し、1つのノードやネットワークに障害が起きてもデータが損なわれないよう、各ノードにデータを分散して配置します。

大きな特徴は、単一障害点がないことです。どこのノードからでもデータ更新が可能であり、スケーラビリティにも優れた、まさにクラウドらしい分散型構成だと言えるでしょう。ただし、ノードの故障や通信のエラーにより、複数のノード間で整合性がとれない(一貫性を損なう)ケースが発生します。

それらの問題を解決し、一貫性を担保する手段として、読み込み時に最新のデータで古いノードのデータを更新するReadRepair機能や、Quorumをベースに結果整合性をとる方法(雑に言えば、不整合が出た場合に、なるべく多くの一致したデータを判定する多数決に似た手法)が用意されています。

このようにCAPによる特性に応じて、各データベースに適したユースケースやデータ特性をまとめると以下のようになります。

各データベースに適したユースケースやデータ特性

タイプ ユースケース/データ特性 使いどころ
CA型 複雑な検索条件 集合関数や射影/結合、副問い合わせなどさまざまなオプションがあるケース
厳密なトランザクション/整合性 多額の決済データや人命に関わるようなデータなど、厳密な一貫性が必要なケース
高負荷なアップデート処理が多い 正規化を前提としたデータ構造により、アップデートの処理コストを最小限に抑えたいケース
CP型 キャッシュ 一部が利用できなくても大きな問題はなく、かつ拡張性が高いデータを利用して、高速化を測りたいケース
高速バッチ処理 OLAP(online analytical processing)、ETL(Extract/Transform/Load)、BI(Business Intelligence)など、シャーディングによる高速処理が見込めるケース
AP型 スケーラブルアプリケーション コネクションプールや単一障害点などがボトルネックとなりがちな、多数のアプリケーションからデータアクセスされる場合や、需要の予測が難しく後から拡張したいケース
マルチリージョンデータベース グローバルな複数のデータセンターに跨ってデータを共通化/レプリケートしたいケース
大量の書き込み IoTセンサーデータなど、リードレプリカでは対応が難しい書き込みが多いケース

次回は、クラウドならでは特性を多数備えたAP型データベースについてもう少し深掘りし、DynamoDBやApache Cassandraの特徴や違いについて紹介します。

著者紹介


川畑 光平(KAWABATA Kohei) - NTTデータ 課長代理

金融機関システム業務アプリケーション開発・システム基盤担当を経て、現在はソフトウェア開発自動化関連の研究開発・推進に従事。

Red Hat Certified Engineer、Pivotal Certified Spring Professional、AWS Certified Solutions Architect Professional等の資格を持ち、アプリケーション基盤・クラウドなどさまざまな開発プロジェクト支援にも携わる。