Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
SlideShare a Scribd company logo
WebエンジニアのためのはじめてのredisWebエンジニアのためのはじめてのredis
@nasa9084@nasa9084
$ whoami$ whoami
北村壮大 (Masahiro Kitamura)
@nasa9084
北海道大学工学部
情報エレクトロニクス学科
コンピュータサイエンスコース
情報認識学研究室
KEYWORDS: emacs python お酒
  
  
初心者向けIT技術勉強会
HTTPのキホン
正規表現入門
Webサーバーを構築してみよう
はじめてのSQL
などなど…
redisredis
redisとは?redisとは?
remote dictionary server
Key-Value Store (KVS)
豊富なデータ型
in-memory
永続化もできる
簡単・速い
Python, Ruby等と相性◎
→Web技術者は学んで損はない!
Key-value Store (KVS)Key-value Store (KVS)
dict(Python)
hash(Perl, Ruby)
map(C++, Java, Go)
名前空間
RDBMSとの比較RDBMSとの比較
機能 RDBMS Redis
シンプルな用途 △ ◎
高速処理 △ ◎
水平分散 × ◎
高可用設計 △ ◎
永続性 ◎ ○
複雑なクエリ ◎ ×
トランザクション ◎ △
一貫性 ◎ △
memcachedとの比較memcachedとの比較
memcached redis
得意なデータ キャッシュ キャッシュ
データ型 文字列のみ いろいろ
永続化 × ○
ディスクIO 行わない 無効化できる
速度 高速 高速
マルチスレッド ○ ×
メモリ効率 △ ○
Redisのデータ型Redisのデータ型
StringString
文字列
文字列の一部置き換え
長さの取得
数値
INCR / DECR できる
最大512MB
バイナリセーフ
画像などもOK
StringString
redis python
> SET hoge fugafuga
OK
> GET hoge
"fugafuga"
> SET point 10
OK
> GET point
"10"
> INCR point
(integer) 11
> GET point
"11"
from redis import Redis
redis = Redis()
redis.set('hoge', 'fugafuga')
print(redis.get('hoge'))
#=> b'fugafuga'
redis.set('point', 10)
print(redis.get('point'))
#=> b'10'
redis.incr('point')
print(redis.get('point'))
#=> b'11'
ListList
Stringのリスト
実装はLinked List
先頭・末尾への挿入・アクセスは
中間要素へのアクセスは
最大232-1要素
O(1)
O(N)
ListList
redis python
> LPUSH 1 2 3
(integer) 3
> LRANGE piyo 0 -1
"3"
"2"
"1"
> LPOP piyo
"3"
> LRANGE piyo 0 -1
"2"
"1"
from redis import Redis
redis = Redis()
redis.lpush('piyo', 1, 2, 3)
print(redis.lrange('piyo', 0, -1))
#=> [b'3', b'2', b'1']
print(redis.lpop('piyo'))
#=> b'3'
print(redis.lrange('piyo', 0, -1))
#=> [b'2', b'1']
SetSet
Stringの集合
順序なし
重複なし
追加・削除・アクセスが平均で
最大232-1要素
O(1)
SetSet
redis python
> SADD foo 1 3 5
(integer) 3
> SMEMBERS foo
"1"
"3"
"5"
> SADD foo 1
(integer) 0
> SMEMBERS foo
"1"
"3"
"5"
from redis import Redis
redis = Redis()
redis.sadd('foo', 1, 3, 5)
print(redis.smembers('foo'))
#=>{b'3', b'5', b'1'}
redis.sadd('foo', 1)
print(redis.smembers('foo'))
#=>{b'3', b'5', b'1'}
Sorted Set (ZSet)Sorted Set (ZSet)
Stringの集合
重複なし
各メンバがScoreで順序付けされる
Scoreの取り出しは
追加は
O(1)
O(log N)
Sorted Set (ZSet)Sorted Set (ZSet)
redis python
> ZADD bar 20 ham
(integer) 1
> ZADD bar 10 egg
(integer) 1
> ZADD bar 30 spam
(integer) 1
> ZRANGE bar 0 -1 WITHSCORES
1) "egg"
2) "10"
3) "ham"
4) "20"
5) "spam"
6) "30"
from redis import Redis
redis = Redis()
redis.zadd('bar', 'ham', 20)
redis.zadd('bar', 'egg', 10)
redis.zadd('bar', 'spam', 30)
print(
redis.zrange('bar', 0, -1, withscores=
)
#=>[(b'egg', 10.0), (b'ham', 20.0), (b'spam
HashHash
StringからStringへのmap
Java: HashMap<String, String>
追加・削除・アクセスが
最大232-1ペア
O(1)
HashHash
redis python
> HSET bar 0:00 5
(integer) 1
> HGETALL bar
1) "0:00"
2) "5"
> HMSET bar 1:00 5 2:00 6
> HKEYS bar
1) "0:00"
2) "1:00"
3) "2:00"
> HGET bar 0:00
"5"
from redis import Redis
redis = Redis()
redis.hset('bar', '0:00', '5')
print(redis.hgetall('bar'))
#=>{b'0:00': b'5'}
add_dict = {
'1:00': '5',
'2:00': '6'
}
redis.hmset('bar', add_dict)
print(redis.hkeys('bar'))
#=>[b'0:00', b'1:00', b'2:00]
print(redis.hget('bar', '0:00'))
#=>b'5'
redisの使いどころredisの使いどころ
有効期限のあるデータ有効期限のあるデータ
keyに対して有効期限を設定できる
EXPIRE key seconds
keyにseconds秒の期限を設定する
EXPIREAT key timestamp
keyの期限をtimestampにする
RDBMSだと少し面倒
例えば例えば
Session ID
One Time Token
Sample CodeSample Code
from redis import Redis
from uuid import uuid4
class User:
def generate_apikey(self):
redis = Redis(host='localhost', port=6389)
if redis.exists(self.token):
return self.token
new_apikey = 'hbt-' + str(uuid4())
ttl = 10 * 60 * 60 # 10 minutes
redis.setex(new_apikey, self.name, ttl)
self.apikey = new_apikey
return self.apikey
https://github.com/web-apps-tech/hubotmaker.git
https://hubot.web-apps.tech/
リアルタイム・ランキングリアルタイム・ランキング
sorted set が活躍
zadd key score member
keyにscore点を持ったmemberを追加する
zincrby key increment member
keyのmemberにincrement点加点する
zrange key start stop
keyのstart番目からstop番目を取得する
Sample CodeSample Code
from redis import Redis
redis = Redis()
while True:
print('input member:score> ', end='')
ipt = input()
if ipt == 'show': # command 'show'
ranking = redis.zrange('ranking', 0, 5, withscores=True)[::-1]
for i, m in enumerate(ranking):
values = {
'rank': i+1,
'member': m[0].decode(),
'point': m[1]
}
print('{rank}: {member} ({point}pt)'.format(**values))
continue
member, score = args.split(':')
redis.zadd('ranking', member, int(score))
print('good bye')
https://github.com/nasa9084/samples.git
redisを使ってみるredisを使ってみる
try redistry redis
http://try.redis.io/
official docker containerofficial docker container
$ docker run redis
まとめまとめ
redisはいいぞ
あらためて まとめあらためて まとめ
in-memory KVS
永続化もできる
データ型が豊富
String, List, Set, Hash, SortedSet
SQLを書くのも面倒なデータに便利
Session IDとか
try redisなどで試せる

More Related Content

webエンジニアのためのはじめてのredis