2017年9月13日水曜日

Redisの水平分割をうまくやるジャストアイデア

Redisをのせているサーバのリソースが逼迫したときに取る戦略の1つとして、水平分割という方法がある。
この水平分割は、データの偏りや、再分割をうまくやろうとすると困難が伴い、泥臭く運用をやる必要がある。

しかし、最初から、クライアントコード上で水平分割の数を決め打ちして扱うと楽になるのではないか?と考えた。
たとえば、サービス開始時には、Redisに将来分割するであろう超大量のユーザIDをキーにしたデータを格納するとして、クライアントは、キーを32分割して扱うようにし、それをすべて1つのRedisに入れてしまえば良い。

メリット:分割しやすくなる。
Redisサーバ数を1から2へ分割するときは、まず、Redis AからRedis Bへレプリケーションを構築して、クライアント上で32分割しておいたキーを、16づつ振り分ける設定をして、レプリケーションを停止する。そうするだけで、サーバリソースをスケールアウトできる。余計になったキーは、あとでバッチで消せばよい。
ノードの負荷の偏りが予想されるときは、Redis Aに20、Redis Bに12を割り当てる、などといったこともできる。

デメリット:最初に決めたRedis分割数までスケールアウトさせたら、その先は泥臭くがんばる必要がある。そうならないように、最初に分割数を多めの数、たとえば、128などに決めておけばよいはず。
分割するとき、1人のユーザIDのデータ更新頻度がレプリケーションのレイテンシを超えるとデータの整合性に不安ができる。アプリケーションによるが、数msで1人の人間がガンガンデータを更新してくることがあるかどうか?この点をクリアできるか、検討する必要がある。