Redis(2.8系)の基本オペレーションとかSentinelの挙動とかの色々メモ

Redis



最近必要に迫られて、ようやくRedisをインストールして触ってみました。(Redis童貞からの脱却)
色々と、基本部分ではあるけど、せっかく実際に触りながら勉強したので、このエントリにメモしておこうと思います。
尚、使ってみたRedisのバージョンは、stableの最新版である2.8.7です。(OSは、LinuxのCentOS 6.5)


ちなみに、このエントリに書いていないような、Redisの基本的なアレコレについては、WEB+DB Press Vol.73のRedis特集(2.6向けではありますが)にほとんど書いてあるので読むべし。

WEB+DB PRESS Vol.73

WEB+DB PRESS Vol.73

  • 作者: 設樂洋爾,白土慧,はまちや2,大和田純,松田明,後藤大輔,ひろせまさあき,小林篤,近藤宇智朗,まかまか般若波羅蜜,Mr. O,川添貴生,重国和宏,柳澤建太郎,奥野幹也,佐藤鉄平,後藤秀宣,mala,中島聡,堤智代,森田創,A-Listers,WEB+DB PRESS編集部
  • 出版社/メーカー: 技術評論社
  • 発売日: 2013/02/23
  • メディア: 大型本
  • 購入: 12人 クリック: 131回
  • この商品を含むブログ (7件) を見る


さて、話は戻って、ここからが本題。
前提として試してみた環境は、サーバを3台用意して、その各サーバで"redis"プロセスと"redis-sentinel"プロセスを起動させるような構成です。
このエントリでは、設定の詳細というよりはコマンドレベルでのオペレーションとか気になった挙動について書こうと思う。

目次

長くなってしまったので目次をつけておくw

  • Redisのインストール
  • Redisの設定ファイルについて
  • Redisプロセスの起動
  • Redisプロセスの停止
  • インメモリデータの永続化について
  • Append Only File(AOF)モード
    • 手動で、AOFの再構成を行う
    • AOFファイルのチェック
  • レプリケーションの設定
    • 設定の持ち方
  • Slaveの切り離し
  • Redis Sentinelについて
    • Redis Sentinelの構成
  • マスタ/スレーブのノード情報をSentinelに尋ねる
    • マスタ情報の確認
    • スレーブ情報の確認
  • フェイルオーバーの挙動
    • 手動でフェイルオーバー
  • スレーブの再投入
    • データサイズによってのスレーブ再同期時間
    • スレーブ投入時、1台の設定のsentinel monitorのRedisマスタのホストを書き間違えた場合
  • PSYNC(Partial Resynchronization)
  • スレーブとして投入する際、持っているデータがマスタと違った場合
  • 3台のRedis/Sentinelの構成で、1台だけネットワーク分断が起こった場合
  • バックアップ
    • RDBファイルのチェック
  • リストア
  • IPv6での対応
  • 設定を変更するオペレーション
  • 簡易だけど性能テスト

Redisのインストール

いきなりですが、割愛しますw
一応このエントリで使った検証環境は、Redis 2.8.7のRPMファイルを自作していますが、ベースのSPECファイルはRemiリポジトリのものを参考にさせてもらいました。
以下リンク先より、ダウンロードできるRPMで同様のことができるはず。


あと、Redis起動時に警告されるので、

vm.overcommit_memory = 1

sysctl.confでこの辺の設定を有効にしておくとか。
あとは、maxclientsの数にあわせてlimits.confでFDの上限を増やしておくとか。

Redisの設定ファイルについて

ボリュームのある別エントリが書けそうなので、このエントリでは割愛しますw

Redisプロセスの起動

# /etc/init.d/redis start

redis-serverコマンドでもよい。

Redisプロセスの停止

$ redis-cli shutdown

ちゃんとRedis内のコマンドで終了させるが吉のようだ。

[14721] 06 Mar 14:42:19.313 # User requested shutdown...
[14721] 06 Mar 14:42:19.313 * Saving the final RDB snapshot before exiting.
[14721] 06 Mar 14:43:08.700 * DB saved on disk
[14721] 06 Mar 14:43:08.700 * Removing the pid file.
[14721] 06 Mar 14:43:08.700 # Redis is now ready to exit, bye bye...

正常に終了されると、上記のような感じのログになる。

[9480] 06 Mar 14:34:56.291 # User requested shutdown...
[9480] 06 Mar 14:34:56.291 * Saving the final RDB snapshot before exiting.

こちらは、"/etc/init.d/redis stop"で終了させた場合。
スクリプトでkillprocしてるからだと思うけど、"DB saved on disk"が出力されず[FAILED]と表示されてコワい。
(まー、この辺はスクリプト書き直せよ、って話ではある。)

インメモリデータの永続化について

Redisには、インメモリのデータを定期的にスナップショットする(ディスクに書き落とす)仕組みがある。
設定ファイルの"save"項のパラメータに従って自動でやってはくれるが、手動でディスクに書き込むためには以下のRedisのコマンドをたたく。

$ redis-cli save

全てのデータセットをディスクに保存する。ただし、保存が完了するまではデータベースにアクセスできなくなる。

$ redis-cli bgsave

ディスクへの保存処理をバックグラウンドで行ってくれる。(フォークして子プロセスが処理してくれてる。)
保存中もデータへのアクセスは読み書きともに可能。

$ redis-cli lastsave
(integer) 1394162355

最後にスナップショットが取られた時刻は↑のような感じで確認できるが、UNIXTIMEである。

$ date --date "@`redis-cli lastsave`" +"%Y/%m/%d %H:%M:%S"
2014/03/07 12:19:15

なので、古典的ではあるが、dateコマンドをかませば、もう少しビジブルな感じで確認できたりもする。

Append Only File(AOF)モード

Redisのデフォルトのデータ永続化は、上記のスナップショットで、↑にも書いたが定期的にスナップショットを行っている。

デフォルトの設定では、以下のように記載があり、

save 900 1
save 300 10
save 60 10000

これは、最後にSAVE(保存)されてから、

  • 900秒以内に1個以上のkeyが更新された場合
  • 300秒以内に10個以上のkeyが更新された場合
  • 60秒以内に10000個以上のkeyが更新された場合

のいずれかの条件を満たした場合に、BGSAVEを実行するという動作を意味します。


で、これだとマスタに予期せぬダウンが生じた場合に、永続化しているとはいえ、タイミングによっては直近のデータをロストする(失う)ことになります。


そこで、Append Only File(AOF)モードが用意されていて、これは変更操作を全てログに保存するモードになります。MySQLでいうバイナリログみたいなもの。(って書くと突っ込まれるか...)
ログファイルへの出力タイミングは「常に(always)」「1秒ごと(everysec)」「fsyncせずOSに書き出しを任せる(no)」の3種類です。


設定は"appendonly"をyesにして起動すればOK。
ただし、"appendonly"がyesの場合は、"appendfilename"で指定しているログファイルからメモリにロードされるため、途中からAOFを有効にする場合、ログファイルが無い状態から起動するので、データが空っぽになってしまうので、要注意!

途中からAOFを有効にする場合は、必ずRedisの起動中に

$ redis-cli config set appendonly yes

を実行して、オンラインでAOFを有効にしてから、設定ファイルを変更するなりします。


ちなみに、スナップショットに比べて、AOFのログファイルサイズは結構大きくなります。そのため、定期的に再構成が実行されます(バックグラウンドで実行される)。再構成が実行されると、ログファイルがコンパクトになり、以下のようなRedisのログが出力されます。

[1487] 11 Mar 22:29:45.425 * Background append only file rewriting started by pid 2778
[2778] 11 Mar 22:29:45.723 * SYNC append only file rewrite performed
[2778] 11 Mar 22:29:45.724 * AOF rewrite: 8 MB of memory used by copy-on-write
[1487] 11 Mar 22:29:45.726 * Background AOF rewrite terminated with success
[1487] 11 Mar 22:29:45.726 * Parent diff successfully flushed to the rewritten AOF (5119 bytes)
[1487] 11 Mar 22:29:45.726 * Background AOF rewrite finished successfully

手動で、AOFの再構成を行う

以下のコマンドを実行すべし。バックグラウンドで実行される。

$ redis-cli bgrewriteaof

AOFファイルのチェック

redis-check-aofコマンドで行う。

$ redis-check-aof /var/lib/redis/appendonly.aof
AOF analyzed: size=36201089, ok_up_to=36201089, diff=0
AOF is valid

こんな感じ。
もし、壊れていた場合は、"--fix"オプションで修復できるとのこと。

レプリケーションの設定

Redisはマスタに対して複数のスレーブをもてるし、スレーブのスレーブ(孫スレーブ)も作れる。非同期I/Oによるレプリケーション。スレーブはデフォルトRead Only。(slave-read-only が yes になっている)


設定は、スレーブ側のredis.confに以下の記載をする。

slaveof (マスタのIPアドレス) 6379

IPアドレスのところは、名前解決できるホスト名/FQDNとかでもよい。
もし、マスタのRedisを6379ポートで待ち受けていない場合は、6379のところを設定しているポート番号に変える。

$ redis-cli slaveof (マスタのIPアドレス) 6379

ちなみに、こんな感じでRedisのコマンドでも可能。


レプリケーションがはられると、以下のような感じでINFOコマンドで確認できる。

$ redis-cli info replication
# Replication
role:master
connected_slaves:2
slave0: .....
slave1: .....

・・・・・以下省略・・・・・

マスタ側から見ると、どのホストがスレーブなのかと、その状態が分かる。

$ redis-cli info replication
# Replication
role:slave
master_host: .....
master_port:6379
master_link_status:up

・・・・・以下省略・・・・・

スレーブ側から見ると、マスタへのレプリケーションのステータスとかがわかります。

設定の持ち方

個人的には、冗長構成を意識したときに、設定ファイルにマスタのありか(IPアドレスとか)を書いておくと、マスタが変更されたときに怖いことが起こる可能性があるので、設定ファイルには書かずにredis-cliとかで設定しておくのが良いのかなと思っていました。
が、が、、、後述しますが、Redis Sentinelを使っていると、sentinel君が勝手にredis.confに、slaveofを書いてくれたりします・・・w
いずれにせよ、マスタ/スレーブの状態管理は、基本的にSentinelに任せてしまう形がいいと思っている。

Slaveの切り離し

$ redis-cli slaveof no one

スレーブ側から上記のRedisコマンドをたたくと、マスタから切り離される。

追記

Sentinel構成でのスレーブノード切り離しは以下リンク先を参考にしてください。

Redis Sentinelについて

Redis Sentinelを使うと、各サーバのRedisプロセス(マスタ/スレーブ)の状態を監視してくれ、マスタに問題が発生したら、別のスレーブへ自動でフェイルオーバーしてくれるようになります。

port 26379
bind 0.0.0.0
daemonize yes
logfile "/var/log/redis/sentinel.log"
pidfile "/var/run/redis/sentinel.pid"
dir "/var/lib/redis"

sentinel monitor mymaster (マスタのアドレス) 6379 2
sentinel down-after-milliseconds mymaster 10000
sentinel failover-timeout mymaster 900000
sentinel parallel-syncs mymaster 1

Sentinelの設定ファイル(/etc/redis-sentinel.conf)は、↑のような感じにした。
今回、Sentinelは3台構成なので、quorumの数は"2"にしている。(sentinel monitorの項の一番右端のパラメータ)

# /etc/init.d/redis-sentinel [start|stop]

ちなみに、Sentinelの起動/停止は、以下のような感じ。


Redis Sentinelは起動すると、設定してあるRedisのマスタノードにアクセスを行い、レプリケーションまわりの情報などを取得し、スレーブノードを把握します。
また、設定ファイルを確認すると、それらの情報が自動的に書き込まれていることがわかります。(!)

Redis Sentinelの構成

下記リンク先で、けんじおじさんも書いているけど、Split-brain-syndromeを防ぐ意味でも、複数台のSentinelを出来る限りネットワーク構成を意識して、動かしておくべきだと思う。

マスタ/スレーブのノード情報をSentinelに尋ねる

マスタネームの部分(mymaster)は、適宜置き換えてください。
(26379番ポートはSentinelプロセスがLISTENしているポート番号。)

マスタ情報の確認

$ redis-cli -p 26379 sentinel master mymaster
 1) "name"
 2) "mymaster"
 3) "ip"
 4) "(マスタのアドレス)"

・・・・・省略・・・・・

スレーブ情報の確認

$ redis-cli -p 26379 sentinel slaves mymaster
1)  1) "name"
    2) "(スレーブ1のアドレス):6379"
    3) "ip"
    4) "(スレーブ1のアドレス)"

・・・・・省略・・・・・

2)  1) "name"
    2) "(スレーブ2のアドレス):6379"
    3) "ip"
    4) "(スレーブ2のアドレス)"

・・・・・省略・・・・・

フェイルオーバーの挙動

実際にマスタを落とすとどういうことが起こるかログで追ってみる。

登場人物は以下の3つ。

  • 旧マスタ(今からダウンする。)
  • 新マスタ(元々はスレーブ。旧マスタのダウン後に、新マスタとして昇格)
  • スレーブ(基本的にスレーブのままだったノード)


まず、テストのため旧マスタをダウンさせる。

[28424] 08 Mar 00:02:30.907 # +sdown sentinel (旧マスタのアドレス):26379 (旧マスタのアドレス) 26379 @ mymaster (旧マスタのアドレス) 6379
[28424] 08 Mar 00:02:31.895 # +sdown master mymaster (旧マスタのアドレス) 6379

この時、スレーブのノードのsentinelのログを見ると、しばらく(およそ"down-after-milliseconds"の設定値)して旧マスタのsdownを検知。(自身のSentinelプロセスが旧マスタのダウンを検知。)

[28424] 08 Mar 00:02:36.258 # +new-epoch 1
[28424] 08 Mar 00:02:36.258 # +vote-for-leader 42c4a78c19874f75daef42368d568422972e18d9 1
[28424] 08 Mar 00:02:37.068 # +odown master mymaster (旧マスタのアドレス) 6379 #quorum 2/2
[28424] 08 Mar 00:02:37.491 # +switch-master mymaster (旧マスタのアドレス) 6379 (新マスタのアドレス) 6379

そこから、リーダーの選出および、旧マスタのodownを検知。(quorumパラメータで指定した数のSDOWN)
"quorum 2/2"の記載がありますね。そこから新マスタが選ばれて、switch-masterが走ります。

[28424] 08 Mar 00:02:37.491 * +slave slave (スレーブのアドレス):6379 (スレーブのアドレス) 6379 @ mymaster (新マスタのアドレス) 6379
[28424] 08 Mar 00:02:37.493 * +slave slave (旧マスタのアドレス):6379 (旧マスタのアドレス) 6379 @ mymaster (新マスタのアドレス) 6379
[28424] 08 Mar 00:02:42.507 # +sdown slave (旧マスタのアドレス):6379 (旧マスタのアドレス) 6379 @ mymaster (新マスタのアドレス) 6379

そして、Sentinelの持つ情報としてスレーブ情報の更新をします。旧マスタがスレーブへと降格して、ダウンした状態であることが検出されます。

手動でフェイルオーバー

ちなみに、Redis Sentinelを使っていると手動でフェイルオーバーさせることもできます。意図的に実施するので、フェイルオーバーというよりはテイクオーバーと言うべきか。

$ redis-cli -p 26379 sentinel failover mymaster

こんな感じで実行すると、別のスレーブがマスタへと昇格し、旧マスタはスレーブになります。
マスタネームの部分(mymaster)は、適宜置き換えてください。

スレーブの再投入

さて、ここまで↑の流れで旧マスタはダウンしたままですが、復帰させてみます。
この時点で、旧マスタはRedisプロセスもSentinelプロセスも停止したままです。


まず、旧マスタのRedisプロセスを起動します。

[28424] 08 Mar 02:12:28.289 # -sdown slave (旧マスタのアドレス):6379 (旧マスタのアドレス) 6379 @ mymaster (新マスタのアドレス) 6379

すると、他のSentinelから復旧したことが検知(sdownステータスが消滅)され、この時点でスレーブとしてレプリケーションが始まります。なんて優秀な子なの・・・!


次に、Sentinelの設定ファイルは、マスタの指定として、旧マスタが指定されたままの状態ですが、あえてこのままSentinelプロセスを起動してみましょう。

[28424] 08 Mar 02:17:04.590 # -sdown sentinel (旧マスタのアドレス):26379 (旧マスタのアドレス) 26379 @ mymaster 10.34.67.38 6379
[28424] 08 Mar 02:17:06.610 * -dup-sentinel master mymaster (新マスタのアドレス) 6379 #duplicate of (旧マスタのアドレス):26379 or 046473c114c613a4129606d5e7869b8ac74c4898
[28424] 08 Mar 02:17:06.610 * +sentinel sentinel (旧マスタのアドレス):26379 (旧マスタのアドレス) 26379 @ mymaster (新マスタのアドレス) 6379

すると、こんな感じで、Duplicateが検知され、正しい情報に直されて問題なく起動しました・・・。Sentinelの設定ファイルも正しいマスタ/スレーブの情報が記載されています。

データサイズによってのスレーブ再同期時間

試しにまっさらなスレーブ(ゼロデータ)を作って、適当なテストデータを持つ、約2500万Key、約7.0GBメモリデータ量、RDBファイル(後述)約1.9GBで構成されたマスタに対して、レプリケーションをはってみます。
ログを見るとわかりやすいですが、以下のような挙動です。

[22377] 10 Mar 02:37:48.061 * SLAVE OF (マスタのアドレス):6379 enabled (user request)
[22377] 10 Mar 02:37:48.081 * Connecting to MASTER (マスタのアドレス):6379
[22377] 10 Mar 02:37:48.081 * MASTER <-> SLAVE sync started
[22377] 10 Mar 02:37:48.081 * Non blocking connect for SYNC fired the event.
[22377] 10 Mar 02:37:48.083 * Master replied to PING, replication can continue...
[22377] 10 Mar 02:37:48.083 * Partial resynchronization not possible (no cached master)
[22377] 10 Mar 02:37:48.084 * Full resync from master: 39590427e03792c2d34904f163b57c024707e91e:575
[22377] 10 Mar 02:38:37.742 * MASTER <-> SLAVE sync: receiving 2027774958 bytes from master
[22377] 10 Mar 02:38:55.390 * MASTER <-> SLAVE sync: Flushing old data
[22377] 10 Mar 02:38:55.390 * MASTER <-> SLAVE sync: Loading DB in memory
[22377] 10 Mar 02:39:50.654 * MASTER <-> SLAVE sync: Finished with success
  • マスタに接続する
  • 部分再同期を試みる(不可状態だったので完全再同期を実施)
  • マスタからRDBファイルを受信
  • 完全再同期なので古いデータのフラッシュ
  • RDBファイルからメモリへデータの展開
  • 完了後、サービスを開始(この段階でデータにアクセス可能)


「Xeon-E5(SandyBridge), SAS(15000rpm)x4(RAID10), CentOS6系KVMによる仮想マシン」だと、上記のような感じでした。ざっくりですが転送に49秒、メモリへのロードに55秒ですね。
このあたりはマシンのスペックやネットワーク環境に依存しますので、参考までに。

スレーブ投入時、1台の設定のsentinel monitorのRedisマスタのホストを書き間違えた場合

"dup-sentinel master"というログが出力されて検知されます。
その後、設定が正しいステータスに修正されて動き続けるため、心配ご無用でした。

PSYNC(Partial Resynchronization)

Redis 2.8系から、PSYNC(Partial Resynchronization)と呼ばれる部分的な再同期の仕組みをRedisはサポートしています。

Starting with Redis 2.8, master and slave are usually able to continue the replication process without requiring a full resynchronization after the replication link went down.

This works by creating an in-memory backlog of the replication stream on the master side. The master and all the slaves agree on a replication offset and a master run id, so when the link goes down, the slave will reconnect and ask the master to continue the replication. Assuming the master run id is still the same, and that the offset specified is available in the replication backlog, replication will resume from the point where it left off. If either of these conditions are unmet, a full resynchronization is performed (which is the normal pre-2.8 behavior).

Replication – Redis

バージョン2.8以前では、マスタとスレーブのレプリケーションリンクがダウンした際に、完全な再同期が必要だったみたいですが、2.8以降では部分的な再同期をサポートしています。
2.8では、レプリケーションストリームをメモリ内のバックログで保持していて、レプリケーションリンクがダウンした後、スレーブがマスタに再接続にいった際に、これまでレプリケーションを行っていたマスタ実行IDをリクエストし、一致していてかつ指定されたオフセットがレプリケーションのバックログから利用可能であれば、レプリケーションが中断されたところから、再開(部分的に同期)します。


ログ的には、

[22862] 10 Mar 21:09:32.225 * Connecting to MASTER (マスタのアドレス):6379
[22862] 10 Mar 21:09:32.226 * MASTER <-> SLAVE sync started
[22862] 10 Mar 21:09:32.227 * Non blocking connect for SYNC fired the event.
[22862] 10 Mar 21:09:32.227 * Master replied to PING, replication can continue...
[22862] 10 Mar 21:09:32.228 * Trying a partial resynchronization (request 7ddd9c24985efd4a0fe3866bfa27291ce2396017:191305).
[22862] 10 Mar 21:09:32.229 * Successful partial resynchronization with master.
[22862] 10 Mar 21:09:32.229 * MASTER <-> SLAVE sync: Master accepted a Partial Resynchronization.

こんな感じで、再接続に成功した後に、partial resynchronizationを試みています。


尚、注意点としては、意図的にレプリケーションを止めた(slaveof no one)ときは、いったんマスタの情報(ID)を失うことになるので、その後もう一度レプリケーションリンクを作成しても、完全な再同期となります。


あと、レプリケーションのバックログのサイズやTTLに関しては、

  • repl-backlog-size
  • repl-backlog-ttl

あたりで指定可能です。

スレーブとして投入する際、持っているデータがマスタと違った場合

マスタが保持しているデータが正しい状態と認識し、スレーブは完全にマスタのデータと同期される状態になる。

(非同期なレプリケケーションをしている以上、タイミングによってはマスタとスレーブのデータがずれてしまうこともあるため、フェイルオーバー時などのデータの取り扱いは注意しておくべし。)

3台のRedis/Sentinelの構成で、1台だけネットワーク分断が起こった場合

redis01 redis02 redis03
master slave slave

という構成だったとしよう。
この3台のうち、redis01だけネットワーク分断が発生して独立してしまったとする。
redis01だけ疎通が取れない状態なので、redis02とredis03は協調して、マスタのフェイルオーバーを行い、redis01はslave扱いにする。
しかし、redis01は、redis02とredis03のスレーブノードがダウンしたという判定をしてマスタであり続ける。


その結果、以下のような状態となる。

redis01 redis02 redis03
master master slave


次に、ネットワーク分断していたredis01を再びネットワーク疎通が取れた場合、他sentinelの状態を確認し、switch-masterを行い、自身をスレーブにする。その結果、以下の構成となる。

redis01 redis02 redis03
slave master slave


なかなか優秀な挙動だ。

バックアップ

"インメモリデータの永続化について"のところで記載した、SAVE または BGSAVE を実行するとデータがディスクへと保存される。(セーブが完了したかは、LASTSAVEコマンドで確認しましょう)
バックアップはそのファイルを別の場所にとっておけばいい。
ファイルは、redis.confで設定されている"dir"のディレクトリに、"dbfilename"で設定しているファイル名で取得されているはず。

Redis is very data backup friendly since you can copy RDB files while the database is running: the RDB is never modified once produced, and while it gets produced it uses a temporary name and is renamed into its final destination atomically using rename(2) only when the new snapshot is complete.

Redis Persistence – Redis

尚、RDBファイルは普通にコピーして保存すればよいとの事。

RDBファイルのチェック

Redisには「redis-check-dump」という、RDBファイルに問題が無いかを確認するコマンドがある。

$ redis-check-dump /var/lib/redis/dump.rdb
==== Processed 24821447 valid opcodes (in 2027774941 bytes) ====================
CRC64 checksum is OK

こんな感じで実行してチェックすることができる。

リストア

バックアップの逆のことをすれば良いだけ。要は、RDBファイルをredis.confで指定されている"dir", "dbfilename"に従って配置し、Redisを起動すればOKです。

IPv6での対応

IPv6環境でも稼動させてみたが、Redisプロセス自体は軽く確認していた限り問題なく動いている。
ただし、Sentinel側で、各ノードのIPv6アドレスが正常な形式で取得できず、きちんと動作しない。マスタのダウンを検知して、フェイルオーバー処理は行うものの、途中で全Sentinelプロセス自体がクラッシュして落ちる始末。今後に期待したい。

=== REDIS BUG REPORT START: Cut & paste starting from here ===
[1778] 27 Feb 20:06:22.278 #     Redis 2.8.6 crashed by signal: 11
[1778] 27 Feb 20:06:22.278 #     Failed assertion: <no assertion failed> (<no file>:0)
[1778] 27 Feb 20:06:22.278 # --- STACK TRACE

実は、IPv6を検証したのはバージョン2.8.6ではあったのだが、、、上記のようなログが出力されて落ちた。

設定を変更するオペレーション

例えば、maxmemoryを増やすオペレーションをやってみる。単純だが以下の2通り。

  • redis.confのmaxmemoryのパラメータを変更して、Redisプロセスの再起動
  • 以下のようにRedisのCONFIG SETコマンドを使う
$ redis-cli config set maxmemory 8589934592

上記は、maxmemoryを8GBに変更した例。
ちなみに、インメモリで持ってる容量を下回る設定も"OK"と返り、設定変更されたので、なかなかカジュアルに変えれる感があって怖い・・・w

簡易だけど性能テスト

  • Xeon-E5(SandyBridge), SAS(15000rpm)x4(RAID10), CentOS6系KVMによる仮想マシン。
  • マスタのデータは、約2500万Key、約7.0GBメモリデータ量、RDBファイル(後述)約1.9GBな状態。
  • AOFは無効
  • マスタ1に対してスレーブ2な環境。
  • マスタにてredis-benchmarkコマンドをローカルに対して実施。
$ redis-benchmark -q
PING_INLINE: 103092.78 requests per second
PING_BULK: 103092.78 requests per second
SET: 86956.52 requests per second
GET: 98039.22 requests per second
INCR: 63291.14 requests per second
LPUSH: 69930.07 requests per second
LPOP: 72992.70 requests per second
SADD: 84033.61 requests per second
SPOP: 84033.61 requests per second
LPUSH (needed to benchmark LRANGE): 68965.52 requests per second
LRANGE_100 (first 100 elements): 43290.04 requests per second
LRANGE_300 (first 300 elements): 22321.43 requests per second
LRANGE_500 (first 450 elements): 17064.85 requests per second
LRANGE_600 (first 600 elements): 13513.51 requests per second
MSET (10 keys): 42016.80 requests per second


$ redis-benchmark -q -d 100
PING_INLINE: 99009.90 requests per second
PING_BULK: 101010.10 requests per second
SET: 72992.70 requests per second
GET: 96153.84 requests per second
INCR: 83333.34 requests per second
LPUSH: 76335.88 requests per second
LPOP: 86956.52 requests per second
SADD: 102040.82 requests per second
SPOP: 100000.00 requests per second
LPUSH (needed to benchmark LRANGE): 76923.08 requests per second
LRANGE_100 (first 100 elements): 39062.50 requests per second
LRANGE_300 (first 300 elements): 12330.46 requests per second
LRANGE_500 (first 450 elements): 7547.17 requests per second
LRANGE_600 (first 600 elements): 5455.54 requests per second
MSET (10 keys): 30030.03 requests per second


$ redis-benchmark -q -d 1000
PING_INLINE: 72992.70 requests per second
PING_BULK: 96153.84 requests per second
SET: 66666.66 requests per second
GET: 68965.52 requests per second
INCR: 74074.07 requests per second
LPUSH: 53763.44 requests per second
LPOP: 70921.98 requests per second
SADD: 77519.38 requests per second
SPOP: 76923.08 requests per second
LPUSH (needed to benchmark LRANGE): 54644.81 requests per second
LRANGE_100 (first 100 elements): 8976.66 requests per second
LRANGE_300 (first 300 elements): 2975.30 requests per second
LRANGE_500 (first 450 elements): 1782.85 requests per second
LRANGE_600 (first 600 elements): 1241.16 requests per second
MSET (10 keys): 15974.44 requests per second


$ redis-benchmark -q -d 10000
PING_INLINE: 64935.07 requests per second
PING_BULK: 64102.56 requests per second
SET: 18115.94 requests per second
GET: 60975.61 requests per second
INCR: 62893.08 requests per second
LPUSH: 21321.96 requests per second
LPOP: 40322.58 requests per second
SADD: 73529.41 requests per second
SPOP: 86956.52 requests per second
LPUSH (needed to benchmark LRANGE): 32679.74 requests per second
LRANGE_100 (first 100 elements): 831.60 requests per second
LRANGE_300 (first 300 elements): 281.19 requests per second
LRANGE_500 (first 450 elements): 188.22 requests per second
LRANGE_600 (first 600 elements): 135.57 requests per second
MSET (10 keys): 14245.01 requests per second

ちなみに、VM to VM (CentOS 6 on KVM, Max 1Gbps)な環境で取得すると、Maxが65000reqests/secあたりでキャップされていた。(ネットワーク通信のオーバーヘッド)

他、参考になるリンク

Redis 2.8 でSentinelまわりの挙動について検証された結果が記載されている。


Redis入門 インメモリKVSによる高速データ管理

Redis入門 インメモリKVSによる高速データ管理

WEB+DB PRESS Vol.73

WEB+DB PRESS Vol.73

  • 作者: 設樂洋爾,白土慧,はまちや2,大和田純,松田明,後藤大輔,ひろせまさあき,小林篤,近藤宇智朗,まかまか般若波羅蜜,Mr. O,川添貴生,重国和宏,柳澤建太郎,奥野幹也,佐藤鉄平,後藤秀宣,mala,中島聡,堤智代,森田創,A-Listers,WEB+DB PRESS編集部
  • 出版社/メーカー: 技術評論社
  • 発売日: 2013/02/23
  • メディア: 大型本
  • 購入: 12人 クリック: 131回
  • この商品を含むブログ (7件) を見る