MacでRedis


- RedisとはNoSQLデータベース一種とのことです。基本インメモリのデータベースとのこと。
- pythonから使おうかとインストールしてみました。
- いつもながら前準備なしの手探りでやってますｗ

## インストール ： brewでOK

- 現時点での最新版がbrewでインストールできるようです。

```sh
sh-3.2$ brew info redis
redis: stable 3.2.9 (bottled), devel 4.0RC3, HEAD
Persistent key-value database, with built-in net interface
https://redis.io/
Not installed
```

- インストール

```
sh-3.2$ brew install redis
==> Downloading https://homebrew.bintray.com/bottles/redis-3.2.9.sierra.bottle.tar.gz
######################################################################## 100.0%
==> Pouring redis-3.2.9.sierra.bottle.tar.gz
==> Using the sandbox
==> Caveats
To have launchd start redis now and restart at login:
  brew services start redis
Or, if you don't want/need a background service you can just run:
  redis-server /usr/local/etc/redis.conf
==> Summary
🍺  /usr/local/Cellar/redis/3.2.9: 13 files, 1.7MB
```

## 起動

- redis-serverコマンドで起動できるそうな。

```
sh-3.2$ which redis-server
/usr/local/bin/redis-server
sh-3.2$ redis-server
5577:C 02 Jul 00:00:40.715 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
5577:M 02 Jul 00:00:40.716 * Increased maximum number of open files to 10032 (it was originally set to 4864).
                _._
           _.-``__ ''-._
      _.-``    `.  `_.  ''-._           Redis 3.2.9 (00000000/0) 64 bit
  .-`` .-```.  ```\/    _.,_ ''-._
 (    '      ,       .-`  | `,    )     Running in standalone mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 6379
 |    `-._   `._    /     _.-'    |     PID: 5577
  `-._    `-._  `-./  _.-'    _.-'
 |`-._`-._    `-.__.-'    _.-'_.-'|
 |    `-._`-._        _.-'_.-'    |           http://redis.io
  `-._    `-._`-.__.-'_.-'    _.-'
 |`-._`-._    `-.__.-'    _.-'_.-'|
 |    `-._`-._        _.-'_.-'    |
  `-._    `-._`-.__.-'_.-'    _.-'
      `-._    `-.__.-'    _.-'
          `-._        _.-'
              `-.__.-'

5577:M 02 Jul 00:00:40.717 # Server started, Redis version 3.2.9
5577:M 02 Jul 00:00:40.717 * The server is now ready to accept connections on port 6379
```

- 6379 ポートで起動したっぽい。

## 接続してみる。

- telnet でも使えたwww
- ちなみにquitで抜けられます。

```sh
sh-3.2$ telnet localhost 6379
Trying ::1...
Connected to localhost.
Escape character is '^]'.
set foo bar
+OK
get foo
$3
bar
```

- redis-cliでつなげてみます。

```sh
sh-3.2$ redis-cli
127.0.0.1:6379> set foo bar
OK
127.0.0.1:6379> get foo
"bar"
```

- ヨユーですね。

## サーバ止めてみる。

- redis-serverを止めました。

```sh
5577:signal-handler (1498921932) Received SIGINT scheduling shutdown...
5577:M 02 Jul 00:12:12.118 # User requested shutdown...
5577:M 02 Jul 00:12:12.118 * Saving the final RDB snapshot before exiting.
5577:M 02 Jul 00:12:12.119 * DB saved on disk
5577:M 02 Jul 00:12:12.120 # Redis is now ready to exit, bye bye...
sh-3.2$
```

- redis-cliも接続できません。

```sh
127.0.0.1:6379> get foo
Could not connect to Redis at 127.0.0.1:6379: Connection refused
```

## サーバ再起動してみる。

- 再度redis-serverを再起動してredis-cliで確認してみます。

```sh
not connected> get foo
"bar"
127.0.0.1:6379>
```

- あれ？インメモリデータベースじゃなかったの？データ残ってました。
- wikipediaの説明をみるとデフォルト2秒おきにファイルに書き込んでるとか。
- 細かくは``redis-server /usr/local/etc/redis.conf```などで起動する際の.confを調べたほうが良さそうですね。

## python から利用

- 本題です。

### モジュールのインストール

- redisモジュールをインストールします。

```sh
sh-3.2$ pip install redis
Collecting redis
  Downloading redis-2.10.5-py2.py3-none-any.whl (60kB)
    100% |████████████████████████████████| 61kB 364kB/s
Installing collected packages: redis
Successfully
```

### Pythonプログラム

- こんなプログラムにしてみました。

```python:redis-test.py
import os
import sys
import redis

# 接続パス、環境変数にあればそれ優先
REDIS_URL = os.environ.get('REDIS_URL') if os.environ.get(
    'REDIS_URL') != None else 'redis://localhost:6379'
# データベースの指定
DATABASE_INDEX = 1  # 0じゃなくあえて1

# コネクションプールから１つ取得
pool = redis.ConnectionPool.from_url(REDIS_URL, db=DATABASE_INDEX)
# コネクションを利用
r = redis.StrictRedis(connection_pool=pool)

# 接続エラーがあれば終了
try:
    print('DB size : ' + str(r.dbsize()))
except Exception as e:
    print(type(e))
    sys.exit()

# 設定したデータベースの削除
r.flushdb()
    
# キーの登録 飛び飛び
for i in range(5):
    r.set('key' + str(i * 2), {'val': 'val' + str(i)})

# キーの参照
for i in range(10):
    key = 'key' + str(i)
    print(key + ' → ' + str(r.get(key)))

# キー一覧
print(r.keys())
```

- 実行

```sh
sh-3.2$ python redis-test.py
key0 → b"{'val': 'val0'}"
key1 → None
key2 → b"{'val': 'val1'}"
key3 → None
key4 → b"{'val': 'val2'}"
key5 → None
key6 → b"{'val': 'val3'}"
key7 → None
key8 → b"{'val': 'val4'}"
key9 → None
[b'key0', b'key4', b'key2', b'key6', b'key8']
```

- 簡単でした。

## ディスクに書き込んでた。

- サーバーのログをみてみるとディスクに書き込み処理をしてまいした。

```sh
6274:M 02 Jul 01:01:04.088 * 10000 changes in 60 seconds. Saving...
6274:M 02 Jul 01:01:04.088 * Background saving started by pid 8407
8407:C 02 Jul 01:01:04.728 * DB saved on disk
```

## データベースの指定・切り替え

- データベースのテーブルというかスキーマみたいなの区分けもできます。
- サンプルソースの```db=DATABASE_INDEX```ですね。
- コマンドラインから指定するときは```redis-cli -n 番号```か、コマンドの中で```SELECT 番号```で切り替えられるようです。
- サンプルプログラム実行後に試してみます。

```sh
sh-3.2$ redis-cli
127.0.0.1:6379> dbsize
(integer) 0                   --- DB = 0 の件数は空
127.0.0.1:6379> SELECT 1      --- DB = 1 に切り替え
OK
127.0.0.1:6379[1]> dbsize
(integer) 5                   --- DB = 0 の件数は5件
127.0.0.1:6379[1]> keys *     --- キー一覧
1) "key0"
2) "key4"
3) "key2"
4) "key6"
5) "key8"
127.0.0.1:6379[1]>
```