パーティショニング

参考:https://lets.postgresql.jp/documents/technical/partitioning/1

データを複数に分割して格納すること。
データを分割することにより、性能や運用性が向上し、故障の影響を局所化することができる。

典型的なデータの分割方法は「レンジ (範囲)」「リスト」「ハッシュ」の3種類である。またそれらを組み合わせた「コンポジット (複合)」分割が用意されている場合もある。

レンジ・パーティショニング

値の範囲ごとに分割する方法のこと。パーティションそれぞれが互いに重ならないような範囲を受け持ち、その範囲に収まるデータを格納する。
たとえば、履歴を蓄積するテーブルを日や月単位で分割することがある。
古い情報だが、2010年当時は、Twiterでもそのようなパーティションが行われていたようだ。

Twitterというサービスには、Kallen氏が「時間的局所性」(temporal locality)と呼ぶ独特のアクセスパターンがある。「実際にはほとんどのクエリは、より新しい情報へのバイアスがかかっている」(同)からだ。ほとんどの人のリクエストは最新のパーティションに対するクエリで完結する。すべてのユーザーがアクティブなわけではないため、「あるユーザーの直近のつぶやき20件」は、複数のパーティションにさかのぼっていくことになるが、それでもこの戦略によりアクセス時間の平均は事実上O(1)となっているのだという。

https://atmarkit.itmedia.co.jp/news/201004/19/twitter.html

タイムスタンプ列に基づいて分割することでアクセスの多い直近のデータのみを選択的にキャッシュできるようになる。

リスト・パーティショニング

特定の選択肢から値を選ぶ列がある場合に、その値に基づいて分割を行う方法である。それぞれのパーティションは1つまたは複数の選択肢を受け持つことになり、パーティションごとに集計が必要な場合にアクセス範囲を絞ることができ高速に動作するようになる。

たとえば、地域IDやカテゴリーによる分割がある。
ただし、パーティション間の偏りが生じやすく、都道府県であれば「東京都」パーティションは他県と比べてデータが大きくなったりするため、事前の検討が重要になる。

ハッシュ・パーティショニング

ハッシュ値に基づいて各パーティションに均等に分配する方法のこと。
たとえば、N 分割する場合には、1~N の整数を返すハッシュ関数を定義し、その返値に基づいて分割を行う。

例としては先ほどのTwitterに関する記事から引用させていただく。

例えばユーザーIDを偶数、奇数に分けて2つのDBに分けて保存するテクニック。特定のユーザーのつぶやきを表示する場合、IDが偶数か奇数かで問い合わせすべきDBが一意に決まるため、分割すればするほどレスポンスが上がり、1つ1つのDBのサイズも抑えられる。
ただ、ユーザーIDに基づくパーティショニングでは、特定のIDを持つつぶやきを見つけることができなくなる。そのIDのつぶやきを誰がしたかが分からないからだ。このため、せっかくパーティショニングした複数のDBをすべて検索しなくてはいけなくなる。

(図)
パーティショニングの1つの方法。つぶやきのIDを元に分けることが考えられるが、この分割方法ではユーザーIDに対応するつぶやきの検索には全パーティションに対するアクセスが発生してしまう

つぶやきのIDでパーティショニングしても、逆の問題が起こる。特定のIDを持つつぶやきがどのパーティションにあるかは分かるが、あるユーザーIDに紐付いたつぶやきのIDは、結局すべてのパーティションを検索しないと分からないからだ。

https://atmarkit.itmedia.co.jp/news/201004/19/twitter.html

memcached(メムキャッシュディー – memory cache daemon)

参考:https://e-words.jp/w/memcached.html
参考:https://www.ossnews.jp/oss_info/memcached

メモリ上で動作するKVS(Key-Value Store)の分散メモリキャッシュサーバーソフトウェアのこと。
データベースへの問い合わせ結果を一時的にキャッシュし、次に同じデータが産業された際に、メモリから即時レスポンスを返すことができ、データベースへのアクセス回数を減らすことでWebアプリケーションのパフォーマンスを向上することができる(任意のバイナリデータを格納することもでき、画像ファイルの配信高速化などに用いられることもある)。
確保したメモリ容量がいっぱいになると、最終アクセス日時が古い順に既存データを削除して新規データ用の容量を確保するような仕組み(LRU:Least Recently Used)を持つ。

複数のmemcachedサーバを並列に動作させることで分散キャッシュシステムを構築することができるが、memcached自身はデータの分散や統一的なアクセス手段を提供せず、キャッシュの読み書きを行うクライアント側(Webアプリケーション)の責任で各サーバへの振り分けや読み込みを管理する必要がある。