share facebook facebook2 twitter menu hatena pocket slack

2013.01.24 THU

Redisってなんじゃ?(レプリケーションとクラスタリング)

三浦 悟

WRITTEN BY三浦 悟

Redisはとても高速ですが、メモリ量の圧迫や負荷によっては分散が必要な場合があり、
分散の種類としては、レプリケーションとクラスタリングがあります。

レプリケーションは、マスタに書き込んだデータをスレーブにコピーすることで、書き込みはマスタ、
読み取りはスレーブと担当を分けることで負荷を分散させます。
読み取りにはマスタも参加することもあります。

クラスタリングは、キーのハッシュ値等によって保存するサーバーが決まり、書き込みと読み取りの両方を
同時に負荷分散します。

○レプリケーション

レプリケーションはRedisの基本機能として提供されているので、すぐに利用することができ、
設定も簡単で、スレーブサーバーの設定ファイルに1行追記するだけとなります。

それでは試してみます。
ここではRedis1をマスター、Redis2をスレーブとします。

インストール&設定

○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/

※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

Redisを起動します。


# 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の使用はTwemproxyからElastiCacheに分散
(同じキーは同じElastiCacheへ)してみる
(suz-lab)の記事が参考になります。

インストール&設定

○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 install

※2013/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を
冗長化させたりすることも可能です。

こちらの記事はなかの人(memorycraft)監修のもと掲載しています。
元記事は、こちら

三浦 悟

三浦 悟

高円寺在住のなんじゃ系男子 またの名をmemorycraftといいます。 炭水化物大好き 日々の「なんじゃ?」を記事にしてます。