データベース - 第5部 : コンシステントハッシュ

Overview

コンシステントハッシュ(Consistent Hashing)とは何でしょうか? これを知る前に、まずhashing(ハッシュ化)という言葉は「刻んで混ぜる」と理解できます。Hash Mapはインデックスにデータをマッピングしたデータ構造です。O(1)であり最も効率的だと言えます。通常はキーと値のペアで保存するのが一般的です。

ハッシュについてはこれくらいにして、分散ハッシュについて話してみましょう。

分散ハッシュ

以下のハッシュテーブルがあると仮定してみましょう。今、私たちはこのデータを分散データストアに保存しようとしています。

KEY HASH HASH mod 3
“john” 1633428562 2
“bill” 7594634739 0
“jane” 5000799124 1
“steve” 9787173343 0
“kate” 3421657995 2

3台のサーバーに分けて保存すると、以下のように整理されます。 それぞれ A:0, B:1, C:2 のインデックスを持ちます。

A B C
“bill” “jane” “john”
“steve”   “kate”

このようにうまく使っている状況で、突然機器が1台故障したと考えてみましょう。サーバーCがダウンしたと仮定すると、再び以下のようにハッシュテーブルとサーバーにデータが割り当てられることになります。

KEY HASH HASH mod 2
“john” 1633428562 0
“bill” 7594634739 1
“jane” 5000799124 0
“steve” 9787173343 1
“kate” 3421657995 1

これで A:0, B:1 の2台のストレージにデータが以下のように保存されます。

A B
“john” “bill”
“jane” “steve”
“kate”  

このようになると、Cに存在していたすべてのキーの位置が変更されることになり、この時、元データからの再ハッシュ(re-hashing)作業が必要となります。これはオリジンサーバーに負荷を与えることになります。そしてその間、クライアントがリクエストしたデータは失われてしまいます。

これを解決するために登場したハッシュ手法が、まさにコンシステントハッシュ(Consistent Hashing)です。

Consistent Hashing

image

上の画像が今回話す全てです。 上の画像に従ってハッシュ化を行うと考えてみましょう。

KEY HASH ANGLE (DEG)
“john” 1633428562 58.7
“C” 2269549488 81.7
“kate” 3421657995 123.1
“jane” 5000799124 180
“A” 5572014557 200.5
“bill” 7594634739 273.4
“B” 8077113361 290.7
“steve” 787173343 352.3

サーバーもハッシュテーブルに一緒に配置します。

ここで各キーが位置するサーバーを見つけるルールは一つです。

反時計回りに回る時、最も近いサーバーがそのキーが位置する保存場所です。

先ほど述べた基準でキーが保存されている場所を整理すると以下のようになります。

KEY HASH ANGLE (DEG) LABEL SERVER
“john” 1632929716 58.7 “C” C
“kate” 3421831276 123.1 “A” A
“jane” 5000648311 180 “A” A
“bill” 7594873884 273.4 “B” B
“steve” 9786437450 352.3 “C” C

では、一体この手法のメリットは何でしょうか?

想像してみましょう。もしCの機器が削除されたとします。既存の手法ではすべてのキーが再ハッシュされなければなりませんでした。

まさにここで、この手法を通じて私たちはCの機器に割り当てられているキーだけ再ハッシュが必要であることを知ることができます。

A、Bのサーバーを見ているキーは、すでに最も近い位置A、Bを見ているためです。Cがなくなってもそれらのキーに変更事項はありません。Cサーバーに割り当てられたキーだけ再ハッシュが必要です。

逆に機器が追加されても K/N (キーの数 / 機器数)だけの再ハッシュが必要なだけで、すべてのキーに対して再ハッシュが必要なわけではありません。

例えばキーが3つで、機器が2つだった時。この間に機器が1つ入ると考えると、機器にキーが均等に入るように設計したと仮定すれば、3/3 = 1つのキーに対して再ハッシュが起こり得て、これは結局、機器1つにつき1つのキーが保存されるバランスの取れた姿を見せることができます。

Consistent Hashing は問題を抱えています。それはキーの偏りです。これをどうすれば緩和できるでしょうか?

Ketama Consistent Hashing

image

まず最も簡単な方法は、サーバーを複数のトークンに分割して Consistent Hashing Circle に配置することです。 これがまさに Ketama Consistent Hashing 手法です。AサーバーをA0-A10まで分散させ、キーの配置が極力均一になるようにします。

考察

  • 結局、再ハッシュ(rehashing)は避けられない問題です。最小限の再ハッシュで済むように設計し、構築することが分散処理の要求事項だと考えられます。

サンプルプロジェクト ( 上記の理論を簡単に実装してみました )

Appendix