Datastore は、多数のマシン間でデータを分散し、マスターのない同期レプリケーションを広範な地理的領域で使用することで、高可用性、スケーラビリティ、耐久性を実現します。ただしその反面、この設計では書き込みスループットが制限されます。1 つのエンティティ グループに対し、1 秒につき 1 回程度の commit しか行えないためです。複数のエンティティ グループにまたがるクエリやトランザクションにも制限があります。このページではこうした制限事項について詳しく説明します。また、アプリケーションの書き込みスループットに対する要件を満たしつつも、強整合性をサポートするようにデータを構築するためのおすすめの方法を紹介します。
整合性のレベル
Datastore のクエリでは、次の 2 つの整合性レベルのいずれかで結果を返すことができます。
- 強整合性クエリでは、結果が必ず最新になります。ただし、完了までに時間がかかる場合や、一部の状況ではサポートされない場合があります。
- 結果整合性クエリは、一般的により高速に実行されます。ただし、最新ではない結果が返される場合があります。
結果整合性クエリでは、結果の収集に使用されるインデックスも、結果整合性に基づいてアクセスされます。この結果、現時点でクエリ条件とは一致しなくなったエンティティが返される場合や、クエリ条件と一致するエンティティが省略される場合もあります。強整合性クエリでは、トランザクション上の整合性を維持するため、単一の一貫性のあるデータ スナップショットに基づいた結果が得られます。
整合性の保証
クエリでは各クエリの特性に基づき、異なる整合性レベルを保証した結果が返されます。
- 祖先クエリ(単一のエンティティ グループに対して実行されるクエリ)はデフォルトで強整合性を持ちますが、後述のように、Datastore の読み取りポリシーを設定することで結果整合性クエリにすることもできます。
- グローバル クエリ(単一のエンティティ グループに対して実行されないクエリ)は、常に結果整合性を持ちます。
多くのアプリケーションでは、相互に関連性のないデータに対する広範なビューを取得するのであれば、結果整合性(複数のエンティティ グループにまたがるグローバル クエリ、やや古いデータが返される場合もある)の使用で対応できます。一方、関連性の高い単一のデータセットを表示したり編集したりする場合は、強整合性(祖先クエリ、または単一エンティティの検索)の使用が適しています。このようなアプリケーションの場合は通常、関連性の高いデータ同士をエンティティ グループにまとめると効率的です。エンティティ グループの数が多ければ、スループットが向上します。エンティティ グループの数を少なくすると、1 回の祖先クエリで読み取り可能なエンティティの量が増えます。アプリケーションではこれらを踏まえ、スループットと整合性の適切なバランスを決定する必要があります。
Datastore の読み取りポリシー
パフォーマンスを向上させるため、結果整合性を維持した結果が得られるように、クエリの読み取りポリシーを設定できます(Datastore API を使用して強整合性ポリシーを明示的に設定することもできますが、現実的な効果はありません。グローバル クエリでは常に、ポリシーに関係なく、結果的に整合しているからです)。
結果整合性に基づく読み取りを有効にするには、クエリ オブジェクトの読み取りオプションを使用します。
C#
Cloud Datastore 用のクライアント ライブラリをインストールして使用する方法については、Cloud Datastore のクライアント ライブラリをご覧ください。 詳細については、Cloud Datastore C# API のリファレンス ドキュメントをご覧ください。
Cloud Datastore への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。
Go
Cloud Datastore 用のクライアント ライブラリをインストールして使用する方法については、Cloud Datastore のクライアント ライブラリをご覧ください。 詳細については、Cloud Datastore Go API のリファレンス ドキュメントをご覧ください。
Cloud Datastore への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。
Java
Cloud Datastore 用のクライアント ライブラリをインストールして使用する方法については、Cloud Datastore のクライアント ライブラリをご覧ください。 詳細については、Cloud Datastore Java API のリファレンス ドキュメントをご覧ください。
Cloud Datastore への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。
Node.js
Cloud Datastore 用のクライアント ライブラリをインストールして使用する方法については、Cloud Datastore のクライアント ライブラリをご覧ください。 詳細については、Cloud Datastore Node.js API のリファレンス ドキュメントをご覧ください。
Cloud Datastore への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。
PHP
Cloud Datastore 用のクライアント ライブラリをインストールして使用する方法については、Cloud Datastore のクライアント ライブラリをご覧ください。 詳細については、Cloud Datastore PHP API のリファレンス ドキュメントをご覧ください。
Cloud Datastore への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。
Python
Cloud Datastore 用のクライアント ライブラリをインストールして使用する方法については、Cloud Datastore のクライアント ライブラリをご覧ください。 詳細については、Cloud Datastore Python API のリファレンス ドキュメントをご覧ください。
Cloud Datastore への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。
Ruby
Cloud Datastore 用のクライアント ライブラリをインストールして使用する方法については、Cloud Datastore のクライアント ライブラリをご覧ください。 詳細については、Cloud Datastore Ruby API のリファレンス ドキュメントをご覧ください。
Cloud Datastore への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。
トランザクションと整合性に関する考慮事項
Datastore の commit は、トランザクション型、非トランザクション型のいずれかです。前者の場合、トランザクションのコンテキストで実行され、トランザクションの一連の変更がすべて適用されるか、一切適用されません。後者の場合、一連の変更の一部が適用されるか、一切適用されません。
1 つのトランザクションには、作成、更新、削除の変更をいくつでも含めることができます。トランザクションではデータの整合性を維持するため、そのトランザクション内のすべての変更を一括して Datastore に適用します。いずれかの変更が失敗した場合は、どの変更も適用されません。また同一のトランザクション内で実行されるすべての強整合性読み取り(祖先クエリまたは lookup
オペレーション)において、単一の一貫性のあるデータ スナップショットが利用されます。強整合性クエリでは、祖先フィルタを指定する必要があります。トランザクションに参加するクエリは、常に強整合性を維持します。トランザクションには最大 25 のエンティティ グループを使用できます。結果整合性読み取りにはこのような制限はなく、多くの場合に適しています。結果整合性読み取りを使用する場合は、大量のエンティティ グループ間でデータを分散できる可能性があります。この結果、異なるエンティティ グループ間で commit を並列実行することで、書き込みスループットが向上します。ただし結果整合性読み取りがアプリケーションに適するかどうかを判断するには、その特性を理解しておく必要があります。
- 結果整合性読み取りによる結果は、最新のトランザクションを反映していない場合があります。このタイプの読み取りでは、読み取りを実行しているレプリカが最新であることが保証されないためです。代わりに結果整合性読み取りでは、クエリの実行時にこのレプリカで使用可能な任意のデータが使用されます。
- 複数のエンティティ グループを対象として commit されたトランザクションは、すべてではなく一部のエンティティにしか適用されていないように見える場合があります。しかし、1 つのトランザクションが 1 つのエンティティ内で部分的に適用されたように見えることはありません。
- クエリ結果には、フィルタ条件に適合しないはずのエンティティが含まれる場合や、フィルタ条件に適合するはずのエンティティが除外される場合があります。これはインデックスを読み取るために使用されるスナップショットが、エンティティを読み取るために使用されるスナップショットのバージョンと異なる場合があるためです。
整合性に対応するデータ構造
強整合性に対応するデータ構造化の方法を理解するため、単純なタスクリスト アプリケーションを作成する 2 つの方法を比較してみます。1 つ目の方法では、個々のエンティティをそれぞれ独自の新規エンティティ グループ内に作成します(つまりどのエンティティもルート エンティティとなる)。
C#
Cloud Datastore 用のクライアント ライブラリをインストールして使用する方法については、Cloud Datastore のクライアント ライブラリをご覧ください。 詳細については、Cloud Datastore C# API のリファレンス ドキュメントをご覧ください。
Cloud Datastore への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。
Go
Cloud Datastore 用のクライアント ライブラリをインストールして使用する方法については、Cloud Datastore のクライアント ライブラリをご覧ください。 詳細については、Cloud Datastore Go API のリファレンス ドキュメントをご覧ください。
Cloud Datastore への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。
Java
Cloud Datastore 用のクライアント ライブラリをインストールして使用する方法については、Cloud Datastore のクライアント ライブラリをご覧ください。 詳細については、Cloud Datastore Java API のリファレンス ドキュメントをご覧ください。
Cloud Datastore への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。
Node.js
Cloud Datastore 用のクライアント ライブラリをインストールして使用する方法については、Cloud Datastore のクライアント ライブラリをご覧ください。 詳細については、Cloud Datastore Node.js API のリファレンス ドキュメントをご覧ください。
Cloud Datastore への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。
PHP
Cloud Datastore 用のクライアント ライブラリをインストールして使用する方法については、Cloud Datastore のクライアント ライブラリをご覧ください。 詳細については、Cloud Datastore PHP API のリファレンス ドキュメントをご覧ください。
Cloud Datastore への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。
Python
Cloud Datastore 用のクライアント ライブラリをインストールして使用する方法については、Cloud Datastore のクライアント ライブラリをご覧ください。 詳細については、Cloud Datastore Python API のリファレンス ドキュメントをご覧ください。
Cloud Datastore への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。
Ruby
Cloud Datastore 用のクライアント ライブラリをインストールして使用する方法については、Cloud Datastore のクライアント ライブラリをご覧ください。 詳細については、Cloud Datastore Ruby API のリファレンス ドキュメントをご覧ください。
Cloud Datastore への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。
次にエンティティの種類 Task
に対してクエリを実行し、優先度が 4 以上となる未処理のタスクを優先度順に降順で並べ替えるように指示します。
C#
Cloud Datastore 用のクライアント ライブラリをインストールして使用する方法については、Cloud Datastore のクライアント ライブラリをご覧ください。 詳細については、Cloud Datastore C# API のリファレンス ドキュメントをご覧ください。
Cloud Datastore への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。
Go
Cloud Datastore 用のクライアント ライブラリをインストールして使用する方法については、Cloud Datastore のクライアント ライブラリをご覧ください。 詳細については、Cloud Datastore Go API のリファレンス ドキュメントをご覧ください。
Cloud Datastore への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。
Java
Cloud Datastore 用のクライアント ライブラリをインストールして使用する方法については、Cloud Datastore のクライアント ライブラリをご覧ください。 詳細については、Cloud Datastore Java API のリファレンス ドキュメントをご覧ください。
Cloud Datastore への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。
Node.js
Cloud Datastore 用のクライアント ライブラリをインストールして使用する方法については、Cloud Datastore のクライアント ライブラリをご覧ください。 詳細については、Cloud Datastore Node.js API のリファレンス ドキュメントをご覧ください。
Cloud Datastore への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。
PHP
Cloud Datastore 用のクライアント ライブラリをインストールして使用する方法については、Cloud Datastore のクライアント ライブラリをご覧ください。 詳細については、Cloud Datastore PHP API のリファレンス ドキュメントをご覧ください。
Cloud Datastore への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。
Python
Cloud Datastore 用のクライアント ライブラリをインストールして使用する方法については、Cloud Datastore のクライアント ライブラリをご覧ください。 詳細については、Cloud Datastore Python API のリファレンス ドキュメントをご覧ください。
Cloud Datastore への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。
Ruby
Cloud Datastore 用のクライアント ライブラリをインストールして使用する方法については、Cloud Datastore のクライアント ライブラリをご覧ください。 詳細については、Cloud Datastore Ruby API のリファレンス ドキュメントをご覧ください。
Cloud Datastore への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。
ただし、ここでは(祖先クエリではなく)結果整合性クエリを使用しているため、クエリの結果に新規エンティティが含まれていない可能性があります。それでも commit 直後であれば、結果整合性クエリでもほぼすべての書き込みが有効です。多くのアプリケーションでは、現在のユーザー自身による変更を処理する場合、結果整合性クエリによる結果を提供するソリューションで通常は十分であり、この程度のレイテンシは完全に許容範囲となります。
強整合性を実現する場合は、祖先パスを持つエンティティを作成する方法がより効果的です。祖先パスは、作成された各エンティティがグループ化される共通のルート エンティティを識別します。この例では、種類が TaskList
、名前が default
となる祖先パスを使用します。
C#
Cloud Datastore 用のクライアント ライブラリをインストールして使用する方法については、Cloud Datastore のクライアント ライブラリをご覧ください。 詳細については、Cloud Datastore C# API のリファレンス ドキュメントをご覧ください。
Cloud Datastore への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。
Go
Cloud Datastore 用のクライアント ライブラリをインストールして使用する方法については、Cloud Datastore のクライアント ライブラリをご覧ください。 詳細については、Cloud Datastore Go API のリファレンス ドキュメントをご覧ください。
Cloud Datastore への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。
Java
Cloud Datastore 用のクライアント ライブラリをインストールして使用する方法については、Cloud Datastore のクライアント ライブラリをご覧ください。 詳細については、Cloud Datastore Java API のリファレンス ドキュメントをご覧ください。
Cloud Datastore への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。
Node.js
Cloud Datastore 用のクライアント ライブラリをインストールして使用する方法については、Cloud Datastore のクライアント ライブラリをご覧ください。 詳細については、Cloud Datastore Node.js API のリファレンス ドキュメントをご覧ください。
Cloud Datastore への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。
PHP
Cloud Datastore 用のクライアント ライブラリをインストールして使用する方法については、Cloud Datastore のクライアント ライブラリをご覧ください。 詳細については、Cloud Datastore PHP API のリファレンス ドキュメントをご覧ください。
Cloud Datastore への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。
Python
Cloud Datastore 用のクライアント ライブラリをインストールして使用する方法については、Cloud Datastore のクライアント ライブラリをご覧ください。 詳細については、Cloud Datastore Python API のリファレンス ドキュメントをご覧ください。
Cloud Datastore への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。
Ruby
Cloud Datastore 用のクライアント ライブラリをインストールして使用する方法については、Cloud Datastore のクライアント ライブラリをご覧ください。 詳細については、Cloud Datastore Ruby API のリファレンス ドキュメントをご覧ください。
Cloud Datastore への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。
これで、共通のルート エンティティによって識別されるエンティティ グループ内で強整合性の祖先クエリを実行できます。
C#
Cloud Datastore 用のクライアント ライブラリをインストールして使用する方法については、Cloud Datastore のクライアント ライブラリをご覧ください。 詳細については、Cloud Datastore C# API のリファレンス ドキュメントをご覧ください。
Cloud Datastore への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。
Go
Cloud Datastore 用のクライアント ライブラリをインストールして使用する方法については、Cloud Datastore のクライアント ライブラリをご覧ください。 詳細については、Cloud Datastore Go API のリファレンス ドキュメントをご覧ください。
Cloud Datastore への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。
Java
Cloud Datastore 用のクライアント ライブラリをインストールして使用する方法については、Cloud Datastore のクライアント ライブラリをご覧ください。 詳細については、Cloud Datastore Java API のリファレンス ドキュメントをご覧ください。
Cloud Datastore への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。
Node.js
Cloud Datastore 用のクライアント ライブラリをインストールして使用する方法については、Cloud Datastore のクライアント ライブラリをご覧ください。 詳細については、Cloud Datastore Node.js API のリファレンス ドキュメントをご覧ください。
Cloud Datastore への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。
PHP
Cloud Datastore 用のクライアント ライブラリをインストールして使用する方法については、Cloud Datastore のクライアント ライブラリをご覧ください。 詳細については、Cloud Datastore PHP API のリファレンス ドキュメントをご覧ください。
Cloud Datastore への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。
Python
Cloud Datastore 用のクライアント ライブラリをインストールして使用する方法については、Cloud Datastore のクライアント ライブラリをご覧ください。 詳細については、Cloud Datastore Python API のリファレンス ドキュメントをご覧ください。
Cloud Datastore への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。
Ruby
Cloud Datastore 用のクライアント ライブラリをインストールして使用する方法については、Cloud Datastore のクライアント ライブラリをご覧ください。 詳細については、Cloud Datastore Ruby API のリファレンス ドキュメントをご覧ください。
Cloud Datastore への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。
この方法では、1 つのタスクリストにつき 1 つのエンティティ グループに書き込むことで、強整合性を実現できます。ただしタスクリストへの変更は、1 秒あたりわずか 1 回の書き込みに制限されます(エンティティ グループに対してサポートされる制限)。書き込みの使用率が高くなると予想されるアプリケーションの場合は、他の手段を使用することを検討してください。たとえばアプリケーションが、ユーザーがメッセージを公開メッセージ ボードに投稿できるゲストブックであるとします。最新の投稿は、有効期限を設定して Memcache 内に保管し、Memcache と Datastore 内の最新投稿を表示する方法や、Cookie に投稿をキャッシュして、なんらかの状態を URL などに完全に格納する方法が考えられます。現在のユーザーがアプリケーションに投稿している間に、このユーザーにデータを提供するキャッシュ ソリューションを見つけることが目標となります。トランザクション内で lookup
、祖先クエリ(読み取りポリシーが結果整合性に設定されていないことが前提)、またはなんらかのオペレーションを実行する場合は、常に最新の書き込みデータが表示されることに留意してください。
その他のトランザクション使用例については、こちらをご覧ください。
トランザクションに対するエンティティ グループの制限
データをエンティティ グループに編成する場合、実行可能なトランザクションの種類が制限されることがあります。
- トランザクションがアクセスするすべてのデータは、最大 25 のエンティティ グループに制限されます。
- トランザクション内でクエリを使用する場合は、適切なデータと一致する祖先フィルタを指定できるように、データをエンティティ グループに編成する必要があります。
- 1 つのエンティティ グループに対し、1 秒につき約 1 つのトランザクションという書き込みスループットの上限があります。これは高い信頼性とフォールト トレランスを実現するため、Datastore が広範な地域にわたって個々のエンティティ グループをマスターなしで同期複製するために生じる制限です。
エンティティとインデックスの更新方法の詳細については、トランザクション分離の記事をご覧ください。