分散の種類としては、レプリケーションとクラスタリングがあります。
レプリケーションは、マスタに書き込んだデータをスレーブにコピーすることで、書き込みはマスタ、読み取りはスレーブと担当を分けることで負荷を分散させます。読み取りにはマスタも参加することもあります。
クラスタリングは、キーのハッシュ値などによって保存するサーバーが決まり、書き込みと読み取りの両方を同時に負荷分散します。
レプリケーション
レプリケーションはRedisの基本機能として提供されているので、すぐに利用できます。
設定も簡単で、スレーブサーバーの設定ファイルに1行追記するだけです。
それでは試してみます。ここではRedis1をマスター、Redis2をスレーブとします。
インストール&設定
●Redis1(10.0.0.10), Redis2(10.0.0.20)
インストールします。
# cd /usr/local/src # curl -OL http://redis.googlecode.com/files/redis-2.6.4.tar.gz # tar xzf redis-2.6.4.tar.gz # cd redis-2.6.4 # make # make install # mkdir /etc/redis /var/lib/redis # cd /usr/local/src/redis-2.6.4/ # cp redis.conf /etc/redis/2013/01/22追記:redis-2.6.3だとスムーズに行かない環境があるようなので、記事中のバージョンをredis-2.6.4に変更しました。
●Redis2
スレーブ側の設定ファイルでマスタを指定します。
# vim /etc/redis/redis.conf --- slaveof 10.0.0.10 6379 ---
●Redis1, Redis2
起動します。
# nohup redis-server /etc/redis/redis.conf &
確認
●Redis1
書き込みます。
# redis-cli redis 127.0.0.1:6379> set hello "world" OK redis 127.0.0.1:6379> get hello "world"
●Redis2
マスタで書き込んだキーを読みとります。
# redis-cli redis 127.0.0.1:6379> get hello "world"
ちゃんと取得出来ました。
クラスタリング
現時点での最新安定バージョン2.6.9ではまだクラスタリングはサポートされておらず、unstable版に含まれていす。
この機能はまだ不安定なため、正式サポートを待つ形になります。
別の方法として、twemproxyというmemcached, redisプロトコルに対応したtwitter製のプロキシを使うことで簡単なクラスタリングを実現できます。
ちなみにmemcachedプロトコルでのtwemproxyの使用はこちらが参考になります。
suz-lab:TwemproxyからElastiCacheに分散(同じキーは同じElastiCacheへ)してみる
インストール&設定
●Redis1(10.0.0.10), Redis2(10.0.0.20)
redisは普通にインストールします。
# cd /usr/local/src # curl -OL http://redis.googlecode.com/files/redis-2.6.4.tar.gz # tar xzf redis-2.6.4.tar.gz # cd redis-2.6.4 # make # make install # mkdir /etc/redis /var/lib/redis # cd /usr/local/src/redis-2.6.4/ # cp redis.conf /etc/redis/ # nohup redis-server /etc/redis/redis.conf &2013/01/22追記:redis-2.6.3だとスムーズに行かない環境があるようなので、記事中のバージョンをredis-2.6.4に変更しました。
●Proxy(10.0.0.30)
twemproxyと必要なautoconfツール群をインストールします。
yumのデフォルトで入るバージョンは古いためエラーになるのでソースから入れます。
# cd /usr/local/src # curl -OL http://redis.googlecode.com/files/redis-2.6.4.tar.gz # tar xzf redis-2.6.4.tar.gz # cd redis-2.6.4 # make # make install # cd ../ # curl -OL http://ftp.gnu.org/gnu/autoconf/autoconf-2.69.tar.gz # tar xvzf autoconf-2.69.tar.gz # cd autoconf-2.69 # ./configure # make # make install # cd ../ # curl -OL http://ftp.gnu.org/gnu/automake/automake-1.12.tar.gz # tar xvzf automake-1.12.tar.gz # cd automake-1.12 # ./configure # make # make install # cd ../ # curl -OL http://ftp.jaist.ac.jp/pub/GNU/libtool/libtool-2.4.2.tar.gz # tar xvzf libtool-2.4.2.tar.gz # cd libtool-2.4.2 # ./configure # make # make install # cd ../ # curl -OL https://github.com/twitter/twemproxy/archive/v0.2.2.zip # unzip v0.2.2.zip # cd twemproxy-0.2.2/ # /usr/local/bin/autoreconf -fvi # ./configure # make # make install2013/01/22追記:redis-2.6.3だとスムーズに行かない環境があるようなので、記事中のバージョンをredis-2.6.4に変更しました。
twemproxyの設定ファイルを作成します。
# cd ~/ # vim nuckcracker.yml redis: listen: 0.0.0.0:22222 hash: fnv1a_64 distribution: ketama auto_eject_hosts: true timeout: 400 redis: true servers: - 10.0.0.10:6379:1 twemredis1 - 10.0.0.20:6379:1 twemredis2
- listen:twemproxyのリスンポートの指定です。
- distribution:分散方式(ketama=ConsistentHashingのことです)
- hash:ハッシュ方式(fnv系はmd5などと比べて短い値でも分散率が高いですが、衝突率はmd5より高いようです)
- auto_eject_hosts:失敗が多かったホストを自動的にリングから外されます。
- timeout:分散先サーバーとの通信タイムアウト時間(ミリ秒)です。
- redis:trueならredisプロトコル、falseならmemcachedプロトコルになります。
- servers:分散先のサーバー群です。
起動します。
# nutcracker -c nutcracker.yml -d
確認
●Proxy
いくつかキーとバリューをsetします。
# redis-cli redis 127.0.0.1:22222> set hoge "moge" OK redis 127.0.0.1:22222> get hoge "moge" redis 127.0.0.1:22222> set hello "world" OK redis 127.0.0.1:22222> get hello "world"
●Redis1
セットしたキーを取得します。
いくつかは取得できません。
# redis-cli redis 127.0.0.1:6379> get hoge "moge" redis 127.0.0.1:6379> get hello (nil)
●Redis 2
セットしたキーを取得します。
Redis1で取得できなかったキーは取得でき、Redis1 で取得できたキーは取得出来ません。
# redis-cli redis 127.0.0.1:6379> get hoge (nil) redis 127.0.0.1:6379> get hello "world"
●Proxy
Proxy側からは両方取得できます。
# redis-cli redis 127.0.0.1:22222> get hoge "moge" redis 127.0.0.1:22222> get hello "world"
きちんと分散されているようです。
再ハッシュ
自動再ハッシュはサポートされていないので、SLAVEのONとOFFを切り替えを行なったりして、データをコピーしながら再構成していくような工夫が必要なようです。
たとえば、1つのRedisサーバーからもう1台追加してクラスタリングする場合、まずSLAVEOFで1台目をマスタにしてデータをコピーします。その後twemproxyを起動して、2台目をSLAVE解除します。
2台目にコピーされたデータのうち、2台目に割り振られるハッシュキーだけが使用され、約半分は1台目に割り振られるため、使われなくなります。
このようにしてレプリケーションやクラスタリングで負荷を分散させたり、ホットスタンバイをつくることができます。
レプリケーションとクラスタリングを組み合わせたり、シングルポイントとなるtwemproxyを冗長化させたりすることも可能ですね。
以上です。