557 lines
13 KiB
Markdown
557 lines
13 KiB
Markdown
---
|
||
categories: databases nosql
|
||
title: Howto Redis
|
||
...
|
||
|
||
* Documentation : <https://redis.io/documentation>
|
||
* Rôle Ansible : <https://forge.evolix.org/projects/ansible-roles/repository/show/redis>
|
||
|
||
|
||
[Redis](https://redis.io/) est un serveur noSQL clé-valeur. Une valeur peut être une chaîne de caractères, un tableau, une liste, etc.
|
||
Redis tourne en mémoire, et sauvegarde de temps en temps ses données sur le disque.
|
||
|
||
|
||
## Installation
|
||
|
||
~~~
|
||
# apt install redis-server redis-tools
|
||
~~~
|
||
|
||
|
||
*Sous Debian Stretch*, la version de Redis est 3.2.6 :
|
||
|
||
~~~
|
||
$ /usr/bin/redis-server -v
|
||
Redis server v=3.2.6 sha=00000000:0 malloc=jemalloc-3.6.0 bits=64 build=826601c992442478
|
||
|
||
# systemctl status redis
|
||
● redis-server.service - Advanced key-value store
|
||
Loaded: loaded (/lib/systemd/system/redis-server.service; enabled; vendor preset: enabled)
|
||
Active: active (running) since Wed 2017-09-27 16:34:26 CEST; 17h ago
|
||
Docs: http://redis.io/documentation,
|
||
man:redis-server(1)
|
||
Main PID: 24822 (redis-server)
|
||
Tasks: 3 (limit: 4915)
|
||
CGroup: /system.slice/redis-server.service
|
||
└─24822 /usr/bin/redis-server 127.0.0.1:6379
|
||
|
||
~~~
|
||
|
||
*Sous Debian Jessie*, la version de Redis est 2.8.17 :
|
||
|
||
~~~
|
||
$ /usr/bin/redis-server -v
|
||
Redis server v=2.8.17 sha=00000000:0 malloc=jemalloc-3.6.0 bits=64 build=4c1d5710660b9479
|
||
|
||
# systemctl status redis
|
||
● redis-server.service - Advanced key-value store
|
||
Loaded: loaded (/lib/systemd/system/redis-server.service; enabled)
|
||
Active: active (running) since Thu 2017-09-28 10:01:18 CEST; 10min ago
|
||
Main PID: 4245 (redis-server)
|
||
CGroup: /system.slice/redis-server.service
|
||
└─4245 /usr/bin/redis-server 127.0.0.1:6379
|
||
|
||
~~~
|
||
|
||
Si on utilise [systemd](HowtoSystemd), on surcharge l'unité `redis.service` en spécifiant
|
||
le `RuntimeDirectory` (voir la note
|
||
[dans la documentation de la migration Wheezy -> Jessie](HowtoDebian/MigrationWheezyJessie#redis)).
|
||
|
||
|
||
## Configuration
|
||
|
||
La configuration principale se fait dans `/etc/redis/redis.conf` dont voici quelques options :
|
||
|
||
~~~
|
||
daemonize yes
|
||
pidfile /var/run/redis.pid
|
||
|
||
unixsocket /var/run/redis/redis.sock
|
||
bind 127.0.0.1
|
||
port 6379
|
||
timeout 300
|
||
|
||
loglevel notice
|
||
logfile /var/log/redis/redis-server.log
|
||
|
||
databases 16
|
||
save 900 1
|
||
save 300 10
|
||
save 60 10000
|
||
|
||
dbfilename dump.rdb
|
||
dir /var/lib/redis
|
||
|
||
#requirepass <password>
|
||
|
||
maxclients 128
|
||
maxmemory 104857600
|
||
~~~
|
||
|
||
La plupart des options sont reconfigurables en mode CLI via la commande _CONFIG SET_.
|
||
La liste des arguments peut être listée :
|
||
|
||
~~~
|
||
redis> CONFIG get *
|
||
1) "dir"
|
||
2) "/var/lib/redis"
|
||
3) "dbfilename"
|
||
4) "dump.rdb"
|
||
5) "requirepass"
|
||
6) (nil)
|
||
7) "masterauth"
|
||
8) (nil)
|
||
9) "maxmemory"
|
||
10) "0"
|
||
~~~
|
||
|
||
## Utilisation
|
||
|
||
En mode CLI :
|
||
|
||
~~~
|
||
$ redis-cli
|
||
redis 127.0.0.1:6379>
|
||
redis> set foo 3
|
||
OK
|
||
redis> get blabla
|
||
(nil)
|
||
redis> get foo
|
||
3
|
||
redis> keys *
|
||
1) "foo"
|
||
redis> mset un 1 deux 2 trois 3 quatre 4
|
||
OK
|
||
redis> keys *
|
||
1) "un"
|
||
2) "foo"
|
||
3) "deux"
|
||
4) "trois"
|
||
5) "quatre"
|
||
redis> *keys *r*
|
||
1) "four"
|
||
2) "three"
|
||
redis> get four
|
||
"4"
|
||
redis> del "trois" "quatre"
|
||
(integer) 2
|
||
~~~
|
||
|
||
On peut se connecter avec la socket si elle existe :
|
||
|
||
~~~
|
||
$ redis-cli -s /path/to/redis.sock
|
||
~~~
|
||
|
||
Mais aussi en réseau (sans authentification, attention) :
|
||
|
||
~~~
|
||
$ telnet 127.0.0.1 6379
|
||
Trying 127.0.0.1...
|
||
Connected to 127.0.0.1.
|
||
Escape character is '^]'.
|
||
get foo
|
||
$1
|
||
3
|
||
quit
|
||
Connection closed by foreign host.
|
||
~~~
|
||
|
||
En PHP, il existe différentes bibliothèques. Nous utilisons principalement <http://github.com/nicolasff/phpredis>
|
||
et nous utilisons un fork pour avoir un packaging Debian propre :
|
||
|
||
~~~
|
||
$ git clone <https://github.com/gcolpart/phpredis>
|
||
$ cd phpredis
|
||
$ tar --exclude debian --exclude .git -cvzf ../php5-redis_0.1~git20120519.orig.tar.gz .
|
||
$ git-buildpackage -us -uc
|
||
~~~
|
||
|
||
|
||
## Sessions PHP avec Redis
|
||
|
||
Redis peut notamment être utilisé pour stocker les sessions PHP. Par exemple :
|
||
|
||
~~~
|
||
session.save_handler = redis
|
||
session.save_path = "tcp://127.0.0.1:6379?auth=<password>"
|
||
~~~
|
||
|
||
|
||
## Instances Redis
|
||
|
||
Il est possible de faire fonctionner plusieurs instances de Redis sur un serveur ; chacune avec ses propres données, sa propre configuration et son propre utilisateur.
|
||
|
||
### Template systemd
|
||
|
||
Creer le template d'unité systemd suivant dans /etc/systemd/system/redis@.service :
|
||
|
||
~~~
|
||
[Unit]
|
||
Description=Advanced key-value store
|
||
After=network.target
|
||
|
||
[Service]
|
||
ExecStartPre=/bin/mkdir -m 0755 -p /run/redis/%i
|
||
ExecStartPre=/bin/chown redis-%i: /run/redis/%i
|
||
PermissionsStartOnly=yes
|
||
|
||
Type=forking
|
||
PIDFile=/run/redis/%i/redis.pid
|
||
ExecStart=/usr/bin/redis-server /etc/redis/redis-%i.conf --unixsocket /run/redis/%i/redis.sock --pidfile /run/redis/%i/redis.pid
|
||
ExecStop=/usr/bin/redis-cli -s /run/redis/%i/redis.sock shutdown
|
||
Restart=always
|
||
User=redis-%i
|
||
Group=redis-%i
|
||
|
||
[Install]
|
||
WantedBy=multi-user.target
|
||
~~~
|
||
|
||
Recharger la configuration systemd :
|
||
|
||
~~~
|
||
systemctl daemon-reload
|
||
~~~
|
||
|
||
### Installation
|
||
|
||
Créer un utilisateur système pour l’instance :
|
||
|
||
~~~
|
||
useradd --system --home-dir /var/lib/redis/instance1 redis-instance1
|
||
~~~
|
||
|
||
Créer ensuite le *datadir* et le dossier de log :
|
||
|
||
~~~
|
||
mkdir -m 0750 -p /var/lib/redis/instance1 /var/log/redis/instance1
|
||
chown redis-instance1: /var/lib/redis/instance1 /var/log/redis/instance1
|
||
~~~
|
||
|
||
Créer ensuite le fichier de configuration suivant dans /etc/redis/redis-instance1.conf :
|
||
|
||
~~~
|
||
daemonize yes
|
||
|
||
port 0 # Listen only on unix socket defined by systemd unit
|
||
unixsocketperm 770 # Unix socket only accessible by user and group of instance1
|
||
timeout 300
|
||
|
||
loglevel notice
|
||
logfile /var/log/redis/instance1/redis-server.log
|
||
|
||
databases 16
|
||
save 900 1
|
||
save 300 10
|
||
save 60 10000
|
||
|
||
dbfilename dump.rdb
|
||
dir /var/lib/redis/instance1
|
||
|
||
#requirepass <password>
|
||
|
||
maxclients 128
|
||
maxmemory 104857600
|
||
~~~
|
||
|
||
### Administration
|
||
|
||
L'instance Redis "instance1" est maintenant administrable via :
|
||
|
||
~~~
|
||
systemctl start redis@instance1
|
||
systemctl stop redis@instance1
|
||
systemctl restart redis@instance1
|
||
systemctl status redis@instance1
|
||
systemctl enable redis@instance1
|
||
systemctl disable redis@instance1
|
||
~~~
|
||
|
||
|
||
## Sauvegardes
|
||
|
||
<http://redis.io/topics/persistence>
|
||
|
||
Par défaut, Redis sauvegarde de temps en temps ses données sur le disque (mode RDB persistence).
|
||
Il suffit donc de copier le fichier */var/lib/redis/dump.rdb* pour sauvegarder une base Redis à chaud !
|
||
|
||
Pour restaurer les données, il suffira d'éteindre Redis, remettre en place le fichier RDB, et relancer Redis.
|
||
|
||
|
||
## Réplication
|
||
|
||
<http://redis.io/topics/replication>
|
||
|
||
Côté "slave" il suffit de mettre en place la configuration :
|
||
|
||
~~~
|
||
slaveof 192.0.43.10 6379
|
||
#masterauth <password>
|
||
~~~
|
||
|
||
Une fois le démon relancé on peut vérifier l'état de la réplication de la façon suivante :
|
||
|
||
~~~
|
||
#redis-cli -h X.X.X.X -p 6379 info replication
|
||
~~~
|
||
|
||
On peut arrêter la réplication et passer un slave en master
|
||
|
||
~~~
|
||
#redis-cli -h X.X.X.X -p 6379 slaveof no one
|
||
~~~
|
||
|
||
~~~
|
||
#redis-cli -h X.X.X.X -p 6379 info replication
|
||
# Replication
|
||
role:master
|
||
connected_slaves:1
|
||
master_repl_offset:631177410
|
||
repl_backlog_active:0
|
||
repl_backlog_size:1048576
|
||
repl_backlog_first_byte_offset:630128835
|
||
repl_backlog_histlen:1048576
|
||
~~~
|
||
|
||
### Tests
|
||
|
||
On test une écriture sur le master, est-ce répliqué sur le slave ?
|
||
|
||
~~~
|
||
redis [master] 127.0.0.1:6379> set key value
|
||
redis [slave] 127.0.0.1:6379> get key
|
||
~~~
|
||
|
||
On devrait avoir « value ». Par ailleurs on pourra lire dans les logs du slave (/var/log/redis/redis-server.log) :
|
||
|
||
~~~
|
||
[26287] 06 Sep 15:04:04 * MASTER <-> SLAVE sync: receiving 34 bytes from master
|
||
~~~
|
||
|
||
Depuis redis 2.6 (2.4 en Wheezy), par défaut, le slave est en read-only, on peut le passer en read & write, en mettant ceci dans la configuration du slave :
|
||
|
||
~~~
|
||
slave-read-only off
|
||
~~~
|
||
|
||
### Sentinel
|
||
|
||
Sentinel permet de faire du failover avec des slaves Redis.
|
||
Attention, il est encore en développement. Il est donc dans la branche instable du dépôt de redis.
|
||
Par ememple, une instance master redis1 et un slave redis2. En cas de panne les rôles s'échangent, redis2 devient master et redis1 devient le slave.
|
||
|
||
#### Unité systemd
|
||
|
||
Créer l’unité systemd suivant dans /etc/systemd/system/redis-sentinel.service :
|
||
|
||
~~~
|
||
[Unit]
|
||
Description=Advanced key-value store (monitoring)
|
||
After=network.target
|
||
|
||
[Service]
|
||
Type=simple
|
||
PIDFile=/run/redis/sentinel.pid
|
||
ExecStart=/usr/bin/redis-sentinel /etc/redis/sentinel.conf --unixsocket /run/redis/sentinel.sock --pidfile /run/redis/sentinel.pid
|
||
ExecStop=/usr/bin/redis-cli -s /run/redis/sentinel.sock shutdown
|
||
Restart=always
|
||
User=redis
|
||
Group=redis
|
||
|
||
[Install]
|
||
WantedBy=multi-user.target
|
||
~~~
|
||
|
||
Créer ensuite le fichier de configuration suivant dans /etc/redis/sentinel.conf :
|
||
|
||
~~~
|
||
port 16379
|
||
dir "/tmp"
|
||
sentinel monitor replication1 127.0.0.1 6379 1
|
||
sentinel down-after-milliseconds 1000
|
||
sentinel config-epoch replication1 7
|
||
sentinel leader-epoch replication1 8
|
||
sentinel known-slave replication1 127.0.0.1 6380
|
||
sentinel current-epoch 8
|
||
~~~
|
||
|
||
Sentinel doit pouvoir ecrire dans son fichier de configuration :
|
||
|
||
~~~
|
||
chown redis: /etc/redis/sentinel.conf
|
||
~~~
|
||
|
||
|
||
## Benchmarks
|
||
|
||
<http://redis.io/topics/benchmarks>
|
||
|
||
~~~
|
||
redis-benchmark -n 100000
|
||
=##### PING (inline)=
|
||
100000 requests completed in 1.88 seconds
|
||
50 parallel clients
|
||
3 bytes payload
|
||
keep alive: 1
|
||
|
||
97.82% <= 1 milliseconds
|
||
99.80% <= 2 milliseconds
|
||
99.89% <= 3 milliseconds
|
||
99.93% <= 4 milliseconds
|
||
99.93% <= 5 milliseconds
|
||
100.00% <= 6 milliseconds
|
||
100.00% <= 6 milliseconds
|
||
53276.50 requests per second
|
||
|
||
=##### PING=
|
||
100000 requests completed in 1.97 seconds
|
||
50 parallel clients
|
||
3 bytes payload
|
||
keep alive: 1
|
||
|
||
93.58% <= 1 milliseconds
|
||
99.36% <= 2 milliseconds
|
||
99.61% <= 3 milliseconds
|
||
99.71% <= 4 milliseconds
|
||
99.81% <= 5 milliseconds
|
||
99.87% <= 6 milliseconds
|
||
99.88% <= 7 milliseconds
|
||
99.88% <= 8 milliseconds
|
||
99.92% <= 10 milliseconds
|
||
99.93% <= 11 milliseconds
|
||
99.93% <= 12 milliseconds
|
||
99.95% <= 13 milliseconds
|
||
100.00% <= 13 milliseconds
|
||
50761.42 requests per second
|
||
|
||
=##### MSET (10 keys)=
|
||
100000 requests completed in 3.12 seconds
|
||
50 parallel clients
|
||
3 bytes payload
|
||
keep alive: 1
|
||
|
||
19.71% <= 1 milliseconds
|
||
91.36% <= 2 milliseconds
|
||
98.93% <= 3 milliseconds
|
||
99.66% <= 4 milliseconds
|
||
99.75% <= 5 milliseconds
|
||
99.76% <= 8 milliseconds
|
||
99.77% <= 9 milliseconds
|
||
99.77% <= 10 milliseconds
|
||
99.80% <= 11 milliseconds
|
||
99.80% <= 14 milliseconds
|
||
99.85% <= 15 milliseconds
|
||
99.89% <= 22 milliseconds
|
||
99.89% <= 23 milliseconds
|
||
99.94% <= 24 milliseconds
|
||
99.95% <= 160 milliseconds
|
||
99.95% <= 208 milliseconds
|
||
99.95% <= 245 milliseconds
|
||
99.95% <= 246 milliseconds
|
||
100.00% <= 246 milliseconds
|
||
32020.49 requests per second
|
||
|
||
=##### SET=
|
||
100000 requests completed in 1.86 seconds
|
||
50 parallel clients
|
||
3 bytes payload
|
||
keep alive: 1
|
||
|
||
97.80% <= 1 milliseconds
|
||
99.78% <= 2 milliseconds
|
||
99.84% <= 3 milliseconds
|
||
99.87% <= 4 milliseconds
|
||
99.93% <= 5 milliseconds
|
||
99.95% <= 10 milliseconds
|
||
99.96% <= 11 milliseconds
|
||
100.00% <= 12 milliseconds
|
||
100.00% <= 12 milliseconds
|
||
53850.30 requests per second
|
||
|
||
=##### GET=
|
||
100000 requests completed in 2.02 seconds
|
||
50 parallel clients
|
||
3 bytes payload
|
||
keep alive: 1
|
||
|
||
91.26% <= 1 milliseconds
|
||
99.65% <= 2 milliseconds
|
||
99.86% <= 3 milliseconds
|
||
99.89% <= 4 milliseconds
|
||
99.92% <= 5 milliseconds
|
||
99.97% <= 7 milliseconds
|
||
100.00% <= 7 milliseconds
|
||
49407.12 requests per second
|
||
|
||
[etc.]
|
||
~~~
|
||
|
||
|
||
## Monitoring
|
||
|
||
### En live
|
||
|
||
Voir des stats toutes les secondes :
|
||
|
||
~~~
|
||
$ redis-cli --stat
|
||
------- data ------ --------------------- load -------------------- - child -
|
||
keys mem clients blocked requests connections
|
||
227947 1.25G 21 0 15259436851 (+0) 252707982
|
||
227948 1.25G 22 0 15259437470 (+619) 252708002
|
||
227951 1.25G 20 0 15259438412 (+942) 252708021
|
||
227951 1.25G 18 0 15259438787 (+375) 252708025
|
||
[…]
|
||
~~~
|
||
|
||
Voir les requêtes que redis reçoit :
|
||
|
||
~~~
|
||
$ redis-cli monitor
|
||
~~~
|
||
|
||
### Nagios/Icinga
|
||
|
||
Depuis *Debian Stretch*, un check redis à été ajouté dans le paquet `nagios-plugins-contrib`, permettant d'avoir un check plus sophistiqué qu'un simple check TCP. Il est capable de surveiller la réplication, la consommation de mémoire... tout en retournant diverses informations sur le status du serveur. Il faut penser à installer la lib redis pour perl, absente des dépendances.
|
||
|
||
~~~
|
||
# apt install libredis-perl nagios-plugins-contrib
|
||
$ /usr/lib/nagios/plugins/check_redis -H 127.0.0.1
|
||
OK: REDIS 3.2.6 on 127.0.0.1:6379 has 0 databases (), up 17 hours 56 minutes
|
||
~~~
|
||
|
||
|
||
Sur *Debian Jessie*, il n'y a pas de check redis embarqué. A place, on peut faire un check Nagios « basique » consiste à initier une connexion TCP sur le socket unix du serveur Redis, et s'assurer qu'il répond bien :
|
||
|
||
~~~
|
||
$ /usr/lib/nagios/plugins/check_tcp -H /var/run/redis.pid
|
||
~~~
|
||
|
||
Il est toujours possible de récupérer le check avancé, pour l'utiliser sur *Jessie* :
|
||
|
||
* <https://exchange.nagios.org/directory/Plugins/Databases/check_redis-2Epl/details>
|
||
* <https://github.com/willixix/WL-NagiosPlugins/blob/master/check_redis.pl>
|
||
|
||
|
||
### Munin
|
||
|
||
* Un plugin Munin existe pour grapher divers paramètres comme la mémoire utilisée par Redis, le nombre de clés utiliséees, le nombre de requêtes par seconde, et le nombre de clients connectés.
|
||
|
||
~~~
|
||
# mkdir -p /usr/local/share/munin/plugins/
|
||
# cd /usr/local/share/munin/plugins/
|
||
# wget "https://raw.githubusercontent.com/munin-monitoring/contrib/master/plugins/redis/redis_"
|
||
# chmod -R 755 /usr/local/share/munin
|
||
# cd /etc/munin/plugins/
|
||
# for module in connected_clients key_ratio keys_per_sec per_sec used_keys used_memory; do ln -s /usr/local/share/munin/plugins/redis_ redis_${module}; done
|
||
~~~
|
||
|
||
Si vous avez un mot de passe à votre redis :
|
||
|
||
~~~
|
||
# cat /etc/munin/plugin-conf.d/munin-node
|
||
[redis_*]
|
||
env.password PASSWORD
|
||
~~~
|