31
Redis 速速速 @Wantedly 速速速速 / Yoshinori Kawasaki

Redis速習会@Wantedly

Embed Size (px)

Citation preview

Page 1: Redis速習会@Wantedly

Redis 速習会@Wantedly

川崎禎紀 / Yoshinori Kawasaki

Page 2: Redis速習会@Wantedly

シゴトでココロオドル

• Redis の基本的な使い方• Ruby on Rails からの Redis の使い方

今日速習する内容

Page 3: Redis速習会@Wantedly

シゴトでココロオドル

REmote DIctionary Server

Page 4: Redis速習会@Wantedly

シゴトでココロオドル

In-memory

http://www.eecs.berkeley.edu/~rcs/research/interactive_latency.html

Page 5: Redis速習会@Wantedly

シゴトでココロオドル

• 高速な KVS– メモリに全てのデータを保存

• 様々なデータ型– 後述

• ディスクに非同期で永続化– 後述

• 用途– データベース– キャシュ– message broker

Redis

Page 6: Redis速習会@Wantedly

シゴトでココロオドル

• シングルスレッド• 普通は CPU 律速にならず、メモリまたはネットワーク律速になる• 最新バージョンは 3.0.5– https://raw.githubusercontent.com/

antirez/redis/3.0/00-RELEASENOTES• ドキュメントがしっかりしている

Redis (contd)

Page 7: Redis速習会@Wantedly

シゴトでココロオドル

$ brew install redis$ redis-server /usr/local/etc/redis.conf$ redis-cli127.0.0.1:6379> PINGPONG

課題 PING

Page 8: Redis速習会@Wantedly

シゴトでココロオドル

127.0.0.1:6379> GET foo(nil)127.0.0.1:6379> SET foo barOK127.0.0.1:6379> GET foo"bar"127.0.0.1:6379> GETSET foo baz"bar"127.0.0.1:6379> GET foo"baz"

課題 GET, SET

Page 9: Redis速習会@Wantedly

シゴトでココロオドル

• String– 数値も String

• List– 双方向リンクリスト– LPOP, LPUSH, RPOP, RPUSH, RPOPLPUSH…– ブロッキング版 BLPOP, BRPOP, BRPOPLPUSH

• Set– 集合

• Sorted set– スコアつき集合– range query が使える– スコアボードとかにつかう

Data Types

Page 10: Redis速習会@Wantedly

シゴトでココロオドル

• Hash– Key-Value set

• Bitmap (bit array)– bit 列

• HyperLogLog– 集合の cardinarity

• Geospatial item– 緯度経度。まだ安定版にはない。

• http://redis.io/topics/data-types• http://redis.io/topics/data-types-intro

Data Types (contd)

Page 11: Redis速習会@Wantedly

シゴトでココロオドル

127.0.0.1:6379> GET baz(nil)127.0.0.1:6379> INCR baz(integer) 1127.0.0.1:6379> GET baz"1"127.0.0.1:6379> INCRBY baz 1000(integer) 1001127.0.0.1:6379> GET baz"1001"

課題 INCR, DECR

Page 12: Redis速習会@Wantedly

シゴトでココロオドル

127.0.0.1:6379> SET foo helloOK127.0.0.1:6379> EXPIRE foo 10(integer) 1127.0.0.1:6379> GET foo"hello"127.0.0.1:6379> TTL foo(integer) 1127.0.0.1:6379> GET foo(nil)127.0.0.1:6379> TTL foo(integer) -2

課題 EXPIRE

Page 13: Redis速習会@Wantedly

シゴトでココロオドル

• http://redis.io/commands

コマンド一覧

Page 14: Redis速習会@Wantedly

シゴトでココロオドル

• RDB– デフォルト– 非同期スナップショット

• fork して書き込むので親process でdisk I/O 発生しない– 履歴バックアップしやすい– リスタート時の読み込みがはやい– 数分のデータロスの可能性

• AOF– 追記型

• disk seek が発生しない– RDBのログ相当 (PostgreSQL の WAL)

• 再生可能– スナップショットよりサイズが大きい– 単独で使わない方がいい

• 作者は将来統合したいと思っている– “we'll likely end up unifying AOF and RDB into a single persistence

model in the future (long term plan).”

ディスク永続化

http://redis.io/topics/persistence

Page 15: Redis速習会@Wantedly

シゴトでココロオドル

• Hash, List, Set( 整数のみ ), Sorted Set はデータ数とデータ長が設定値より少ない場合、エンコードされて保存される• CPU とメモリのトレードオフ

メモリ最適化されたデータ型

http://redis.io/topics/memory-optimization

Page 16: Redis速習会@Wantedly

シゴトでココロオドル

• noeviction– don't expire at all, just return an error on write operations– デフォルト。キャッシュとして使わない場合

• volatile-lru– remove the key with an expire set using an LRU algorithm– キャッシュとデータ永続化を両方使いたい場合

• allkeys-lru– remove any key according to the LRU algorithm– 冪乗則のアクセスパターンの場合– まよったらこれ

• volatile-random– remove a random key with an expire set– キャッシュとデータ永続化を両方使いたい場合

• allkeys-random– remove a random key, any key– 均等にアクセスがある場合

• volatile-ttl– remove the key with the nearest expire time (minor TTL)– キャッシュ生成時によいTTLを設定できるならこれ

• EXPIRE使うとメモリを余計にとる• キャッシュとデータ永続化は別々のRedisインスタンスにするのがオススメ

maxmemory に達した場合の挙動

http://redis.io/topics/lru-cache

Page 17: Redis速習会@Wantedly

シゴトでココロオドル

$ redis-cli FLUSHALL$ redis-benchmark -t SET -r 100000 -n 1000000 $ redis-cli INFO | grep used_memoryused_memory:11745408used_memory_human:11.20Mused_memory_rss:20680704used_memory_peak:20696752used_memory_peak_human:19.74M

課題 メモリ使用量

Page 18: Redis速習会@Wantedly

シゴトでココロオドル

• コメントが充実している• 一度ざっと目を通すのがオススメ• 場所– Homebrew でインストールした人

• /usr/local/etc/redis.conf– GitHub 3.0 branch

• https://github.com/antirez/redis/blob/3.0/redis.conf

課題 設定ファイル

Page 19: Redis速習会@Wantedly

シゴトでココロオドル

$ redis-cli -h 130.211.253.154130.211.253.154:6379> SUBSCRIBE channels:1Reading messages... (press Ctrl-C to quit)1) "subscribe"2) "channels:1"3) (integer) 11) "message"2) "channels:1"3) "wantedly!"

$ redis-cli -h 130.211.253.154127.0.0.1:6379> PUBLISH channels:1 wantedly!(integer) 1

課題 Pub/Sub

Page 20: Redis速習会@Wantedly

シゴトでココロオドル

• Pipelining– 複数コマンドを同時リクエスト– RTT を削減

• Transaction– MULTI / EXEC コマンド– Rollback はしない

• Lua スクリプト– EVAL コマンド– RDB の stored procedure のようなことも出来る

• Master-Slave replication• Redis Sentinel• Redis Cluster

その他の機能

Page 21: Redis速習会@Wantedly

シゴトでココロオドル

ここから Ruby の話になります

Page 22: Redis速習会@Wantedly

シゴトでココロオドル

• redis• redis-rails• redis-rack• redis-activesupport• redis-actionpack• redis-namespace• redis-objects• hiredis• sidekiq, resque

Gem

Page 23: Redis速習会@Wantedly

シゴトでココロオドル

Rails と使う場合# For Rails.cache# config/application.rbconfig.cache_store = :redis_store, 'redis://localhost:6379/0/cache', { expires_in: 90.minutes }

# For session store# config/initializers/session_store.rbMyApplication::Application.config.session_store :redis_store, servers: ‘redis://localhost:6379/0/cache’

実体は別の gem

require 'redis-store'require 'redis-activesupport'require 'redis-actionpack'

redis-rails gem

Page 24: Redis速習会@Wantedly

シゴトでココロオドル

redis-rails で使えないコマンドが使えるコマンドがそのままメソッド名になっている # Remove the last element in a list, append it to another list and return it. # # @param [String] source source key # @param [String] destination destination key # @return [nil, String] the element, or nil when the source key does not exist def rpoplpush(source, destination) synchronize do |client| client.call([:rpoplpush, source, destination]) end end

redis gem

Page 25: Redis速習会@Wantedly

シゴトでココロオドル

• redis gem は pure ruby• hiredis gem は C で書かれた

connection と reply parser の hiredisを使えるようにする• benchmark– https://github.com/redis/hiredis-

rb#benchmarks

hiredis gem

Page 26: Redis速習会@Wantedly

シゴトでココロオドル

Redisのdata typeをRuby的なdata typeにマップしてくれるclass Team < ActiveRecord::Base include Redis::Objects

lock :trade_players, :expiration => 15 # sec value :at_bat counter :hits counter :runs counter :outs counter :inning, :start => 1 list :on_base list :coaches, :marshal => true set :outfielders hash_key :pitchers_faced # "hash" is taken by Ruby sorted_set :rank, :global => trueend

redis-objects gem

Page 27: Redis速習会@Wantedly

シゴトでココロオドル

@team = [email protected]_base << 'player1'@team.on_base << 'player2'@team.on_base << 'player3'@team.on_base # ['player1', 'player2', 'player3']@[email protected][email protected]_base.length # [email protected]_base.delete('player2')

redis-objects gem (contd)

Page 28: Redis速習会@Wantedly

シゴトでココロオドル

key にデフォルトの namespace をつけるredis = Redis.newnamespaced_redis = Redis::Namespace.new(:foo, redis: redis)namespaced_redis.set(‘bar’, ‘baz’) # equivalent to redis.set('ns:foo', 'bar'))redis.get('foo:bar') # => 'baz'

redis-namespace gem

Page 29: Redis速習会@Wantedly

シゴトでココロオドル

• ソースコード– [email protected]:wantedly/instant-learn-redis.git

• SNS 的なやつ– User: id, name, email, avatar_url– Relation: user_id, friend_id

• プロフィールページ– 共通の友人一覧が遅い– http://localhost:3000/users/2

課題 mutual friends

Page 30: Redis速習会@Wantedly

シゴトでココロオドル

$ git clone [email protected]:antirez/redis.git

オプショナル課題

Page 31: Redis速習会@Wantedly

シゴトでココロオドル

• 速習したこと– Redis の基本的な使い方– Ruby on Rails からの Redis の使い方

• 速習しなかったこと– Lua スクリプト– Master-Slave replication– Cluster– Sentinel– 実運用にむけた注意点

• ドキュメント読もう!• ソースも読もう!!

まとめ