redis勉強会資料(2015/06 update)
DESCRIPTION
Redis勉強会の資料です。2013年に初版をアップしました。2015年6月にRedis-Clusterの内容を追記して再アップを行っています。TRANSCRIPT
Redis 勉強会資料(Redis Cluster 追記版 )
株式会社インテリジェンス大谷 祐司
・山口県下関出身の 34 歳
・インテリジェンスの新規事業チームの開発責任者。
・企画からアプリ、インフラまで幅広くやっています。
・車とプログラミングを愛しています。
・土日は育児しながら勉強しています。
・ Facebook の友達申請は気軽にぜひ! https://www.facebook.com/yuji.otani.16
自己紹介
はじめに
今回の勉強会は最近注目の Redisがテーマです。
インテリジェンスでも採用実績が増えていますので、しっかりと理解していきましょう。
アジェンダ
・ Redis の歴史・ Redis の特徴・アーキテクチャ・ Redis のデータ型・バージョンアップと機能追加
アジェンダ
・ Redis の設定ファイル・ PHP から Redis を操作する・社内での活用事例・おまけ: phpredis でできること
Redis の歴史
Redis の歴史
2009 年に Salvatore Sanfilippo というイタリアの技術者によって開発されました。2010 年から VMWare が支援を行っています。
ANSI C 言語で書かれています。
採用実績 ( 日本 )
DeNA
サイバーエージェントニコニコ動画GMO
LINE
採用実績 ( 海外 )
github.com
flicker.com
twitter.com
intasgram.com
stackoverflow.com
AWS も Redis を提供
AWS も Redis を提供
2013 年 9 月から AWS の標準キャッシュに採用。Memcached or Redis を選択可能に。
ElastiCache
Redis の特徴
シングルスレッド
Redis はシングルスレッドで動作します。MySQL のように複数の処理を並列で行う事は不可能です。必然的に、全てのデータ操作は排他的になります。
Redis
コマンド
コマンド
コマンド
コマンド
1 スレッドで順番に処理
データベースの構造
Redis
DB
Key-Value
Key-Value
Key-Value
Key-Value
DB
ID を指定して複数の DB を持つ事ができます。各 DB は独立してキーと値を保持できます。
Key-Value
Key-Value
Key-Value
Key-Value
高いパフォーマンス
全てのデータセットをメモリ内に読み込む
高速なデータアクセスを実現※ メモリは HDD の 10 万倍早い。
高いパフォーマンス
複数の操作を1回で実行可能
アプリケーション ⇔ Redis 間の通信量を削減
コマンドコマンドコマンド
実行
データ構造のサポート
・ 5 種類の型を値として扱う事ができる。・値を計算して戻す事ができる。 ※ LUA スクリプティング / セット型の集合演算
複雑なデータ構造の保持や計算をRedis に任せる事が可能
メモリを使い果たしたら?
仮想メモリ (HDD) を使ってメモリ拡張
バージョン 2.6以降は廃止。
メモリを使い果たしたら?
特定のルールに従って削除
5 つのパターンから設定可能※ 設定ファイル: maxmemory-policy
メモリオーバー時の削除ルール
① LRU アルゴリズムを使用し、期限切れになったキーを削除 ② LRC アルゴリズムに従い、どれかのキーを削除③ 期限切れになったセットの中から、ランダムにキーを削除④ どれかのキーをランダムに削除⑤ 一番期限に近いキーから削除
※LRU アルゴリズム→未使用の時間が最も長いデータを抽出する。
メモリを使い果たしたら?
それでもメモリを確保できないときは、書き込みが全てエラーになります。
レプリケーション
MASTER-SLAVE のレプリケーション構築が可能。MASTER は複数台の SLAVE を設定できる。
MASTER
SLAVE SLAVE SLAVE
レプリケーション
Redis のレプリケーションは非同期。Master-Slave でデータの差分が出る事がある。
データの特性によって参照先の選択が必要。
レプリケーション
Redis のレプリケーションはマルチマスタではない。
参照系、更新系、データ特性などによって、正しくクエリを振り分ける事が重要!
データ永続化 ( バックアップ )
①SAVE/BGSAVE
⇒DB のフルダンプ( RDB = Redis DataBase)を作成。
SAVE/BGSAVE
Redis RDB全データ
データ永続化 ( バックアップ )
②AOF(Append Only File)
⇒コマンド実行ログ。ここからデータ復元可能。
コマンド
Redis AOFコマンド
トランザクション
複数コマンドを纏めて実行・アトミックな操作の保証(他の処理をブロック)・ MULTI でトランザクション開始・全て実行 (EXEC) or 全て未実行 (DISCARD)
MULTI
コマンドコマンドコマンド
EXEC( 実行 )
DISCARD(未実行 )
or
Slow-Log の出力
設定の閾値よりも遅いクエリをメモリに記録。
秒数を指定して SLOWLOG コマンドを実行
遅いクエリの一覧を取得
コマンド実行状況の確認
MONITOR コマンド実行
受け取ったコマンドを無限にダンプ( QUIT コマンドで終了)
コマンドの実行状況を把握できる。
Lua スクリプティング
スクリプト言語「 Lua」を Redis上で実行可能。予め Redis にスクリプトを登録する事ができる。動作はアトミック ( 他の操作をブロックする )
高度な計算を Redis で実行可能
Lua スクリプティング
実行中は他のリクエストをブロックする。
時間が長い処理を行うのは危険。
Redis Sentinel
Redis プロジェクトで開発されている管理サーバ死活監視 / 通知 / 自動フェイルオーバーを実現V2.4.16以降で利用可能
シャーディング
Redis単体ではシャーディング不可能。( クライアントライブラリで実現可能 )
Redis-Cluster で実現可能になる予定。
Redis-Cluster
・インスタンスのデータノード化・対障害性・柔軟なスケーリング・現在開発中
http://redis.io/topics/cluster-spec
アーキテクチャ
Redis のアーキテクチャ
Redis はイベント駆動アーキテクチャで動作。シングルスレッドで大量のリクエストを処理します。
Redis の動作イメージ
1プロセス / 1スレッドで動作
Redis
コマンド
コマンド
コマンド
コマンド
1 スレッドで順番に処理
Redis のアーキテクチャ
1台のサーバで複数コアを活用するには?
同一サーバに複数台の Redis を立ち上げ、別サーバとして動かす事を推奨。
http://redis.io/topics/faq
Redis は CPU の 1 コアのみを使用します。
Redis のデータ型
Redis には 5 つのデータ型があります。各データ型について紹介します。
文字列型
・全てのデータの基本となる型。・バイナリセーフで、どんな値でも扱える。・最大 1G まで扱える。
Orange
リスト型
・文字列型のリスト。・先頭又は末尾に値の追加が可能。・リスト長をキャッシュして、高速に取得可能
Apple Orange Lemon Kiwi Peach
1 2 3 4 5
値を順番に保持
セット型
・文字列型の順不同の集合。・同じメンバを重複して登録する事はできない。・集合演算用コマンドが使用できる。
AppleOrange
Lemon
Kiwi
Peach
値を順不同で保持
セット型の集合演算用のコマンド
積集合( SINTER)
和集合( SUNION)
セット型の集合演算用のコマンド
差集合( SDIFF)
セット型の集合演算用のコマンド
ソート済みセット型
・文字列型の集合。・「スコア」の値でソートされた順位を持っている。・同じメンバを重複して登録する事はできない。・スコアの値、順位で範囲検索が可能。
Appleスコ
ア :10
Orangeスコ
ア :30
Lemonスコ
ア :50
Kiwiスコ
ア :70
Peachスコ
ア :90
1 2 3 4 5
値をスコアの大きさ順に保持
同じスコアの場合の順位は?
同一順位が複数できるのではなく、ランダムの順位になります。
※ この問題は Redis3.0 で対応予定です。https://github.com/antirez/redis/issues/943
ハッシュ型
・順番がない文字列型のフィールドと値のマップ。・フィールド値での検索が可能。・値を指定しての検索は不可能。
AppleOrange
Lemon
Kiwi
Peach
AB C
DE
値とキーをセットで保持
バージョンアップと機能追加
初回リリース: 2009 年 2 月
Ver2.0 リリース: 2010 年 9 月
・ 仮想メモリのサポート⇒実メモリに乗り切らないデータをディスクへ書き出す ※ 2.4 で非推奨になる⇒ 2.6 で完全に削除。
・ ハッシュ型の追加⇒1 つのキー上に複数の key/value を持てる
Ver2.0 リリース: 2010 年 9 月
コマンド追加・ トランザクションが利用可能に (MULTI/EXEC)
・ 複数キーから値を取得する (BLPOP/BRPOP)
・ 非同期メッセージング( PUBLISH/SUBSCRIBE)
Ver2.2 リリース: 2011 年 2 月
・ SlowLog のサポート
・ コマンドで文字列を配列として利用可能に。(SETBIT/GETBIT/SETRANGE/GETRANGE/STRLEN)
Ver2.4 リリース: 2011 年 10 月
・ 「 OBJECT」コマンドの追加( 設定値の参照数、型、操作されていない時間を確認 )
・ 「 CLIENT」コマンドの追加(接続の kill 、接続先一覧、接続先名称の設定 /取得 )
・ スレーブ接続がノンブロッキングになる
Ver2.4 リリース: 2011 年 10 月
・ jemalloc によるメモリ断片化問題の回避
・ データバックアップ (RDB) の高速化
※jemalloc→ 動的メモリ確保を行う関数
Ver2.6 リリース: 2012 年 10 月
・ Lua スクリプティング (eval コマンド ) サポート
・ EXPIRE がミリ秒単位の指定に対応
・ クライアントの接続上限数が無くなった
・ Redis Cluster に向けたコア部分の修正
Ver2.6 リリース: 2012 年 10 月
・ クラッシュレポートの改善
・ 統合メモリテスト機能
・ データのシリアライズ / デシリアライズ
・ SLAVE がデフォルトで更新不可に
Ver2.6 リリース: 2012 年 10 月
・ 「 PTTL」コマンド追加( キーの生存期間をミリ秒で取得 )
・ 「 BITCOUNT」コマンド追加(文字列のビット数を取得 )
・ 「 BITOP」コマンド追加(文字列のビット操作を行う )
Ver2.8 リリース: 2013 年 11 月
・ 部分的なレプリケーションの再同期
・ IPV6 サポート
・ Redis Sentinelへの対応(死活監視 / フェイルオーバー )
Ver3.0 リリース: 2015 年 3 月
・ Redis Clusterへの対応。
・ WAIT コマンドの追加。
・ LRU アルゴリズムの改善。
Redis の設定
起動方式
daemonize
⇒デーモンとして起動
pidfile
⇒デーモン起動時の pid ファイル位置
接続オプション
port
⇒接続ポート
bind
⇒接続元の制限
接続オプション
timeout
⇒コネクションのタイムアウト秒数
requirepass
⇒接続パスワード
ログ関連
loglevel
⇒出力ログのレベル。
logfile
⇒ログの出力先。
データバックアップ
save
⇒データベースをディスクに保存するタイミングsave <seconds> <changes>( 複数設定可能 )
rdbcompression
⇒ダンプデータの圧縮。
dbfilename
⇒ダンプデータファイル名
動作環境
dir
⇒作業用のファイル出力先。
databases
⇒データベース最大数
レプリケーション (SLAVE)
slaveof
⇒マスターサーバのホスト、ポート。
masterauth
⇒マスターに接続する際のパスワード
レプリケーション (SLAVE)
slave-serve-stale-data
⇒レプリケーションが壊れたとき、 SLAVE のみで 動作するか。
repl-ping-slave-period
⇒slave から master に ping を送る間隔
slave-read-only
⇒slave を読み取り専用にするか。
レプリケーション (SLAVE)
repl-timeout
⇒マスタデータ受信時のタイムアウト(秒)
slave-priority
⇒マスタ昇格するスレーブを選択する際の優先度。
repl-disable-tcp-nodelay
⇒TCP_NODELAY を無効化するか※TCP_NODELAY
→Linux におけるソケット機能を向上させる。
セキュリティ
requirepass
⇒アクセス用のパスワード
rename-command
⇒危険なコマンドを実行されないように、コマンドを独自のものに設定できる。
DB 設定
maxclients
⇒最大クライアント数
maxmemory
⇒最大メモリ使用量
DB 設定
maxmemory-policy
⇒最大メモリに達した時、何から削除していくか
maxmemory-samples
⇒最大メモリに達したときに削除を行う際、 チェックを行うサンプル数( このサンプルの中で該当した物を削除する )
Slow-Log
slowlog-log-slower-than
⇒ログ出力の閾値
slowlog-max-len
⇒ログの最大サイズ
高度な設定
glueoutputbuf
⇒レスポンス時に小さな出力バッファを繋げてパフォーマンスを上げる。
activerehashing
⇒メインハッシュテーブルの再ハッシュ化を行う。メモリを効率的に使えるが、最大で2ミリ秒の遅延が発生。
Cluster 設定
cluster-enabled
⇒Cluster の利用
cluster-config-file
⇒Cluster 設定ファイル
cluster-node-timeout
⇒ノード間通信のタイムアウト時間
RedisCluster の活用
79
・クラスタリングとは。
・ Redis Cluster の特徴は?
・実際に使ってみてどうだったか?
Redis Cluster について
80
・複数台の「アクティブな」サーバで DB を構成する。
・データの冗長性や処理の負荷分散を実現できる。
・サーバの台数を増やしてシステムの拡張を行う事ができる。
・逆にサーバの台数を減らす事も可能。
クラスタリングとは?
81
・複数台で分散してデータを持つ ( シャーディング )
・同じデータは複数台で持たない。
・ノード毎に Master-Slave 構成が可能 (障害時は Slave が Master に自動で昇格 )
・ノードを追加 / 削除した際にリシャーディンングが可能。
Redis Cluster の特徴
82
Redis Cluster の構成例
Internet
LB
①命令をルールで均等に分散
②命令を実行する
③Slave にデータをバックアップ
(1 サーバに 3 つのRedis が起動 )
nginx
nginx
nginx
83
・ノードに 0-16384 の数字 (slot) を割り振る。
・リクエストのキーを計算して、対象のサーバを判別する。 [HASH_SLOT = CRC16(key) mod 16384]
クラスタリングの概要
[slot 0-5460]
[slot 5461-10922]
[slot 10923-16383]
①サーバを選んで命令②対象のサーバを判別して命令を転送
node1
node2
node3③命令を実行して結果を返す
PHP から Redis を操作する
フレームワークの対応
⇒Redisent ベースのライブラリが付属。
その他主要なフレームワーク⇒ライブラリを使用する必要があります。
PHP には様々な Redis ライブラリが存在します。
phpredis
作者: Nicolas Favre-Felix( Acunu)
国:イギリスPHP Ver : 5以上URL : https://github.com/nicolasff/phpredis
記述言語: C
ライセンス: PHP License, version 3.01
Predis
作者:ダニエレ・アレッサンドリ( nrk)
国:イタリアPHP Ver : 5.3以上URL : https://github.com/nrk/predis
記述言語: PHP
ライセンス: MIT
Redis の活用事例
・ランキングデータ・「みんなで倒す」ボスデータ・ユーザ集計データ・単純な KVS として ( トークン等 )
など、多くの用途で活用されています。
ソーシャルゲームでの活用事例
ランキングデータ
User:Aスコ
ア :10
User:Aスコ
ア :50
User:Aスコ
ア :70
User:Aスコ
ア :90
1 3 4 5
ユーザランキング
User:Aスコ
ア :30
プレイ結果
ソート済みセット型
・ゲームのプレイ結果「ユーザ ID」「スコア」をソート済みセットに登録⇒スコア順のユーザランキングが生成される。
・順位での検索、ユーザでの検索、スコアでの検索が可能。⇒RDBだとランク取得に order_by が必要になり、処理が重い。
ランキングデータ
「みんなで倒す」ボスデータ
ボス情報 出現時間
キー: prefix {ボス ID}:{ユーザ ID}
ハッシュ型
ボス HP
攻撃履歴 A 攻撃履歴 B 攻撃履歴 C
・ダメージ与えるたびにボスの HP をデクリメント。⇒キャッシュ内で値を一意に保つ事ができる。
・ハッシュ内に攻撃履歴の情報を field : value で追加。⇒複数データを一括で取得 / 削除する事ができる。
「みんなで倒す」ボスデータ
ユーザーデータ
所持アイテム数 ステータス
キー: prefix {ユーザ ID}
ハッシュ型
合計攻撃力クエスト進捗
・ユーザに関する集計値を保持⇒DB が冗長になるのを防ぐ
・ステータスなど頻繁にアクセスする値を保持⇒値の構造化による高速なアクセスを実現
ユーザデータの保持
KVS としての活用 ( トークン等 )
画面アクセス用トークン
キー: prefix {ユーザ ID}{ 画面 ID}
文字列型
KVS としての活用 ( トークン等 )
・単純な Key/Value として保持⇒memcached からの代替が容易 expire をキー単位で設定できる
・ハッシュ型を使用して階層として保持⇒データの取得 / 削除が一括で行える 数値の管理がやりやすい。
最後に
Redis が AWS で採用された意味はとても大きいと思います。恐らく簡単には廃れないでしょう。これからもどんどん活用して、理解を深めていきましょう!
勉強会は以上になります。ご清聴ありがとうございました。
参考ページ
http://www.cyberagent.co.jp/technology/pdf/2012_16.pdfhttp://redis.io/http://rest-term.com/archives/3045/https://github.com/nicolasff/phpredishttp://d.hatena.ne.jp/zentoo/20130718/1374152848http://tech.gmo-media.jp/post/48748908427/introduce-redis-sentinelhttp://www.atmarkit.co.jp/news/201009/07/redis.htmlhttp://gihyo.jp/dev/clip/01/orangenews/vol59/0002
参考ページ
http://sourceforge.jp/magazine/11/02/24/060248
http://sourceforge.jp/magazine/11/10/18/0435209
http://sourceforge.jp/magazine/12/10/24/0530252
http://antirez.com/news/49