今さらPython3 (59) - Redis その1

ひきつづき第8章。

入門 Python 3

入門 Python 3

Redis

Redisは、データ構造サーバーで原則としてメモリに収めると聞くと、memcachedに近いモノを想像してしまうけど、ディスクにデータを保存できるとか、文字列以外のデータ構造もあるなら、先にこっちを教えてくれよって感じもするw。

これもインストールして試してみよう。こうやって、自分のMacにゴミが溜まっていくわけだが、将来への投資だから甘んじて受け入れよう。(何様?)

$ brew install Redis
==> Downloading https://homebrew.bintray.com/bottles/redis-3.0.1.yosemite.bottle.tar.gz
######################################################################## 100.0%
==> Pouring redis-3.0.1.yosemite.bottle.tar.gz
==> Caveats
To have launchd start redis at login:
    ln -sfv /usr/local/opt/redis/*.plist ~/Library/LaunchAgents
Then to load redis now:
    launchctl load ~/Library/LaunchAgents/homebrew.mxcl.redis.plist
Or, if you don't want/need launchctl, you can just run:
    redis-server /usr/local/etc/redis.conf
==> Summary
🍺  /usr/local/Cellar/redis/3.0.1: 9 files, 888K

Homebrewで簡単にインストールできました。起動の仕方も書いてあったので、そのまま起動してみる。

$ redis-server /usr/local/etc/redis.conf
11263:M 24 Dec 12:10:39.549 * Increased maximum number of open files to 10032 (it was originally set to 256).
                _._                                                  
           _.-``__ ''-._                                             
      _.-``    `.  `_.  ''-._           Redis 3.0.1 (00000000/0) 64 bit
  .-`` .-```.  ```\/    _.,_ ''-._                                   
 (    '      ,       .-`  | `,    )     Running in standalone mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 6379
 |    `-._   `._    /     _.-'    |     PID: 11263
  `-._    `-._  `-./  _.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |           http://redis.io        
  `-._    `-._`-.__.-'_.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |                                  
  `-._    `-._`-.__.-'_.-'    _.-'                                   
      `-._    `-.__.-'    _.-'                                       
          `-._        _.-'                                           
              `-.__.-'                                               

11263:M 24 Dec 12:10:39.551 # Server started, Redis version 3.0.1
11263:M 24 Dec 12:10:39.551 * The server is now ready to accept connections on port 6379

つづいて、ドライバのインストール。これは、別ターミナルウィンドウを開いて行う必要あり。てか、最初から2つ開いておけば良いんだけどね。

$ pip3 install redis
Collecting redis
  Downloading redis-2.10.5-py2.py3-none-any.whl (60kB)
    100% |████████████████████████████████| 61kB 4.4MB/s 
Installing collected packages: redis
Successfully installed redis-2.10.5

これで準備完了のはず。Pythonに戻って、

>>> import redis
>>> conn = redis.Redis()

Redisの起動画面にPort番号なんかが出ていたが、redis.Redis('localhost', 6379)でもOKという事だね。これで準備完了。

文字列

>>> conn.keys('*')
[]

すべてのキーのリストを出そうとしたが、まだ何も作っていないので空のリストが返ってきた。

>>> conn.set('secret', 'ni!')
True
>>> conn.set('carats', 24)
True
>>> conn.set('fever', 101.5)
True
>>> conn.keys('*')
[b'fever', b'carats', b'secret']
>>> conn.get('secret')
b'ni!'
>>> conn.get('carats')
b'24'
>>> conn.get('fever')
b'101.5'

とりあえず3つキーと値を登録して、それらの値を取り出してみたところ。

>>> ni = 'ni!'
>>> ni == conn.get('secret')
False
>>> ni == conn.get('secret').decode('utf-8')
True

バイナリになっているので、文字列として扱うときはデコードする必要がありそう。

>>> conn.setnx('secret', 'icky-icky-icky-ptang-zoop-boing!')
False
>>> conn.get('secret')
b'ni!'
>>> conn.getset('secret', 'icky-icky-icky-ptang-zoop-boing!')
b'ni!'
>>> conn.get('secret')
b'icky-icky-icky-ptang-zoop-boing!'
>>> 

setnx()は上書きを禁止した状態で値のセットを試みる、getset()は元の値を返しつつ、新しい値に上書きするオプション。

>>> conn.getrange('secret', -6, -1)
b'boing!'
>>> conn.setrange('secret', 0, 'ICKY')
32
>>> conn.get('secret')
b'ICKY-icky-icky-ptang-zoop-boing!'

getrange()はキーの指定した範囲の内容を取り出している。setrange()は指定した位置(0なので先頭)から文字列を置き換えている。戻り値の32とは何を意味するんだろう?

>>> conn.mset({'pie': 'cherry', 'cordial': 'sherry'})
True
>>> conn.mget(['fever', 'carats'])
[b'101.5', b'24']
>>> conn.delete('fever')
1
>>>
>>> conn.keys('*')
[b'carats', b'cordial', b'secret', b'pie']
>>> 

mset(), mget()で複数のキーを設定したり、値を取得できる。delete()は要素の削除ができる。

>>> conn.incr('carats')
25
>>> conn.incr('carats', 10)
35
>>> conn.decr('carats')
34
>>> conn.decr('carats', 15)
19
>>> conn.set('fever', '101.5')
True
>>> conn.incrbyfloat('fever')
102.5
>>> conn.incrbyfloat('fever', 0.5)
103.0
>>> conn.incrbyfloat('fever', -2.0)
101.0
>>> conn.incr('carats', -10)
9
>>> conn.decr('carats', -10)
19

インクリメント、デクリメントをやっている。オプションなしだと1(floatなら1.0)ずつ、第2引数に数字を指定してやることで、その数値分値を動かすことが出来る。decrbyfloatがないので負数を使っていると説明されているが、incr/decrで負数を使う事が禁じられているわけではないようだ。

(つづく)