Google App Engineに関して活発になっている会話に基づき、Todd Hoff氏はBig Tableのような分散ストレージシステムの使用を最適化する手段である、一連の原則(source)を概説した。
Todd氏は、BigTableを 使用することの定義から始めている。さまざまなトレードオフを引き起こすことを仮定すると、Big Tableは以下のようなアプリケーションをビルドする必要のあるときに、値を付加する。a)「膨大な数のユーザに拡張」する必要があるアプリケーション、b)読み取りに対する更新の割合が制限されているアプリケーション。またTodd氏は、「読み取り速度および拡張可能性の最適化」をするためには、 概念的アプローチがリレーショナルデータベースで使用されたものとは根本的に違っているべきであり、また最初にややカウンターを認識して、さらにリスキーであるとよい。
リレーショナルワールドはエラーの回避に基づいており、正規化が複写を除去したり、更新の以上を回避するためのツールとして使用される。データの拡張縮小は、正規化されるのではなく、複写されるべきである。このパスは、Flickrによって選択された。「別々のコメントの関連を作成するよりもコメンターお よびコメントされるユーザの両方でコメントを複製する」という決定がなされた背景がある。その理由は、「 拡張可能性のユニットがユーザ側である場合、別の関連空間がない」からである。それゆえ、非正規化がTodd Hoff氏が呼ぶところのリレーショナルデータに反するとしても、BigTableデータパラダイムにおいて不可欠の部分である。
そう仮定すると、Todd氏はBig Tableストレージシステムの最大利用のため、覚えておくべきその他の原則を概説している。
- 高速な順次アクセスより、低速なランダムアクセスを想定する。
「BigTableでは、データはどこにでも存在できるので[…]平均的な検索時間は比較的高い」。速度を拡張可能性に対して、交換する。
- 並行読み取りのために、データをグループ化する。
並行読み取りを最大化するために、たとえば「エンティティを保管して、複数の読み取りを必要とするJoinを実行せずに、一度のアクセスで読み取りができる」ように、そして、「属性を複写して、使用される必要がある場所にそれらを保管するように、ソリューションがデモされることになっている。
- ディスクおよびCPUはチープなので、心配せずに、拡張縮小する。
「[...] 単にさらに多くのマシン上で実行することにより、アプリケーションは、必要な限り拡張することができる。拡張可能性のすべての障害が取り除かれた」。
- 使用方法に関する構造データ。
クエリーの速度を改善するために、データフォーマットは使用されることになるフォーマットにできる限り近づける。それゆえ、Hoff氏は「アプリケーショ ンベースのエンティティのSQLセット」の交換を主張した。しかしながら、「これはオブジェクト指向のデータベースと同様でない」ことを強調するのは重要である。振る舞いは、エンティティに拘束されないが、アプリケーションによって提供され、「複数のアプリケーションは同様のエンティティを読み取ることが できるが、まったく違う振る舞いを実装する」。
- 書き込み時に、属性を計算する。
これによって、「読み出し時に必要な作業を軽減」し、「膨大なデータでアプリケーションが繰り返される」(効率が悪い)のを防ぐことができる。
- オプションフィールドで、大規模なエンティティを作成する。
小規模なエンティティをたくさん正規化したり、作成したりする代わりに、「オプションパーツがある大規模なエンティティを作成すれば、一度の読み取りを実行できるし、それから実行時にあるものを決定することができる」。
- モデルでスキーマを定義する。
非正規化のコンテキストにおいて複数のエンティティ全体でのデータの一貫性を保つには、スキーマが「コードで定義されている必要がある。それは、関係すべてを追跡でき、整合性を維持することができる唯一のコードであるからである」。
- Ajaxで更新を非表示にする。
増分がほとんどないデータベースの更新を支援する。
- Putsは重要。
「1つのクエリーで実行することができる更新の数がかなり制限されている」ことを考慮して、Todd氏は「外部CPUによって動かされる、より小さなバッチで更新を実行すること」を提案している。
- 明確なコストモデルによる設計。
「クエリーの形式でOKをクリックすれば、データベース操作の支払いの準備が完了したことを示す」。
- 最小数のエレメントのエンティティで 多対多の関係を確立する。
「長いリストを保持すると、比較的効率が悪い」ので、「できるだけ、リストの項目数は少なくする」ようにする。
- 無限のクエリーを避ける。
Todd氏は、属性からの直近の限られた値のみを表示することを提案している。それは、「大きなクエリーは拡張縮小しない」からである。
- データストアエンティティとの関連を避ける。
「カウントの経過を追い、要求ごとに更新や読み取られるようなエンティティ、といったグローバルカウンターは避ける」べきである。
- 大規模なエンティティグループを回避する。
「エンティティグループへのすべての書き込みは順次的である」から、「規模の小さい、局在のグループ」を使用するほうがより好ましい。
Todd Hoff氏は、こうした原則の洞察についてさらに深く突き詰め(source)、GQL(source)スレッドからの例を使用しながら、それらを説明している。
原文はこちらです: