Redis getting started

# Redis

## 前書き
RedisはいわゆるNoSQLの一種で、インメモリのKey Value Storeです。
今回は、Redis事始めをやってみましょう。

環境はCentOS7.2です。

## インストール
[公式サイトのインストール手順](http://redis.io/download#installation)にしたがって、まずはインストールをしてみましょう。

```console:
$ wget http://download.redis.io/releases/redis-3.0.7.tar.gz
$ tar xzf redis-3.0.7.tar.gz
$ cd redis-3.0.7
$ make
```
makeの段階でCC（コンパイラ）がないといわれたので、インストールします。

```console:
$ sudo yum -y install gcc
```

再度makeします。

```console:
$ make
```
以下のメッセージが出力されて失敗しました。

```console:
cd src && make all
make[1]: Entering directory `/root/redis-3.0.7/src'
    CC adlist.o
In file included from adlist.c:34:0:
zmalloc.h:50:31: fatal error: jemalloc/jemalloc.h: No such file or directory
 #include <jemalloc/jemalloc.h>
                               ^
```
いったんcleanしてからmakeしなおします。

```console:
$ make clean
$ make
```
うまく完了したので、make testしてみます。

```console:
$ make test
cd src && make test
make[1]: Entering directory `/root/redis-3.0.7/src'
You need tcl 8.5 or newer in order to run the Redis test
make[1]: *** [test] Error 1
make[1]: Leaving directory `/root/redis-3.0.7/src'
make: *** [test] Error 2
```

エラーが出ました。
tcl 8.5以上が必要と言われているので、インストールしてみましょう。

```console:
$ sudo yum -y install tcl
```

で、再度テストですが、下記のエラーで失敗しました。

```console:
[exception]: Executing test client: attach_to_replication_stream error. Received '' as count..
attach_to_replication_stream error. Received '' as count.
    while executing
"error "attach_to_replication_stream error. Received '$count' as count.""
    (procedure "attach_to_replication_stream" line 11)
    invoked from within
"attach_to_replication_stream"
    ("uplevel" body line 2)
    invoked from within
"uplevel 1 $code"
    (procedure "test" line 29)
    invoked from within
"test {MULTI / EXEC is propagated correctly (single write command)} {
        set repl [attach_to_replication_stream]
        r multi
        r set foo..."
    ("uplevel" body line 256)
    invoked from within
"uplevel 1 $code "
    (procedure "start_server" line 3)
    invoked from within
"start_server {tags {"multi"}} {
    test {MUTLI / EXEC basics} {
        r del mylist
        r rpush mylist a
        r rpush mylist b
        r rpus..."
    (file "tests/unit/multi.tcl" line 1)
    invoked from within
"source $path"
    (procedure "execute_tests" line 4)
    invoked from within
"execute_tests $data"
    (procedure "test_client_main" line 10)
    invoked from within
"test_client_main $::test_server_port "
```
11111番ポートが解放されていないと失敗するようです。[^1]
firewalldとSELinuxを一時的に設定にして、sudoで実行すると成功しました。

```console:
$ sudo firewall-cmd --zone=public --add-port=11111/tcp
$ sudo setenforce 0
$ sudo make test
```

最後にsudo make installしてインストールします。

```console:
$ sudo make install
```
[^1]: https://github.com/antirez/redis/issues/2818
## 起動/停止

ビルドの結果srcフォルダ以下にコマンドなどが作られています。
`redis-server`コマンドで、サーバを起動します。

```console:
$ cd src
$ ./redis-server
16834:C 21 Apr 09:25:19.433 # Warning: no config file specified, using the default config. In order to specify a config file use ./redis-server /path/to/redis.conf
16834:M 21 Apr 09:25:19.434 * Increased maximum number of open files to 10032 (it was originally set to 1024).
                _._                                                  
           _.-``__ ''-._                                             
      _.-``    `.  `_.  ''-._           Redis 3.0.7 (00000000/0) 64 bit
  .-`` .-```.  ```\/    _.,_ ''-._                                   
 (    '      ,       .-`  | `,    )     Running in standalone mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 6379
 |    `-._   `._    /     _.-'    |     PID: 16834
  `-._    `-._  `-./  _.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |           http://redis.io        
  `-._    `-._`-.__.-'_.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |                                  
  `-._    `-._`-.__.-'_.-'    _.-'                                   
      `-._    `-.__.-'    _.-'                                       
          `-._        _.-'                                           
              `-.__.-'                                               

16834:M 21 Apr 09:25:19.436 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
16834:M 21 Apr 09:25:19.436 # Server started, Redis version 3.0.7
16834:M 21 Apr 09:25:19.436 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
16834:M 21 Apr 09:25:19.436 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
16834:M 21 Apr 09:25:19.437 * The server is now ready to accept connections on port 6379
```

Ctrl+Cを送信することで停止できます。

```console:
^C16834:signal-handler (1461198459) Received SIGINT scheduling shutdown...
16834:M 21 Apr 09:27:39.974 # User requested shutdown...
16834:M 21 Apr 09:27:39.974 * Saving the final RDB snapshot before exiting.
16834:M 21 Apr 09:27:39.991 * DB saved on disk
16834:M 21 Apr 09:27:39.991 # Redis is now ready to exit, bye bye...
````

## デーモンで起動停止

今度はデーモンとしてRedisを起動/停止してみたいと思います。
Redisをデーモンとして起動するためには、`redis.conf`の設定が必要です。
tarの解凍ディレクトリにデフォルトの`redis.conf`があるので、コピーして編集しましょう。

```console:
$ mkdir server1
$ cp redis.conf server1
$ vim ./server1/redis.conf
```
damonizeの値を'yes'にします。

```text:server1/redis.conf
# By default Redis does not run as a daemon. Use 'yes' if you need it.
# Note that Redis will write a pid file in /var/run/redis.pid when daemonized.
# daemonize no
daemonize yes
```

設定ファイルを読み込ませて、Redisを起動します。

```console:
$ ./src/redis-server ./server1/redis.conf
```

何も出力されないので、psで起動確認してみましょう。

```console:
$ ps x | grep redis
 20013 ?        Ssl    0:00 ./src/redis-server *:6379
 20031 pts/0    R+     0:00 grep --color=auto redis
```

20013でredis-serverが起動できているのが確認できますね。

終了はRedisのコマンドラインツールredis-cliから実行します。

```console:
$ ./src/redis-cli shutdown
```

psコマンドで終了していることを確認します。

```console:
$ ps x | grep redis
 20035 pts/0    R+     0:00 grep --color=auto redis
```

## sytemlctlでサービス化
サービス定義を書いてsystemctlから操作できるようにします。

```console:
$ sudo vim /etc/systemd/system/redis.service
```

```file:/etc/systemd/system/redis.service
[Unit]
Description=Redis

[Service]
Type=simple
ExecStart=/usr/local/bin/redis-server /etc/redis/6379.conf
ExecStop=/usr/local/bin/redis-cli -p 6379 shutdown
User=redis
Group=redis  

[Install]
WantedBy=multi-user.target
```

## 参考
http://yomon.hatenablog.com/entry/2016/02/20/162648