3. Redis est plus gourmand
que Memcache
(de 2 à 10 fois plus).
4. Redis n’est pas Memcache
Ni un MemcacheDB
Flared
http://labs.gree.jp/Top/OpenSource/Flare-en.html
Elliptics Network
http://www.ioremap.net/projects/elliptics
6. Getting started
http://code.google.com/ Ne nécessite aucune
p/redis/ dépendance
Licence BSD Ne nécessite quasiment
pas de configuration
Fonctionne sur
quasiment n’importe Sait se faire tout petit
quel système Unix (il (exécutable : 150 ko,
existe aussi un début de mémoire : 2 Mo, cpu:
portage Windows) 0,00%)
12. Les snapshots
Redis Clef 3’
Clef 1 Clef 2
Bgsave Clef 3
Important :
vm.overcommit_memory=1
13. Configuration des snapshots
# after 900 sec (15 min) if at least 1 key changed
# after 300 sec (5 min) if at least 10 keys changed
# after 60 sec if at least 10000 keys changed
save 900 1
save 300 10
save 60 10000
14. Warning!
Il faut disposer de suffisamment de mémoire pour
stocker les copies pendant la sauvegarde.
Au besoin, répartir les données sur plusieurs instances
(et plusieurs disques).
15. Append-Only File
Journal des commandes Pendant l’écriture d’un
qui modifient les nouveau journal, les
données. écritures continuent à
être écrites dans
Toute la base peut être
l’ancien.
reconstruite d’après ce
journal. Les commandes
manquantes sont
BGREWRITEAOF: réécrit
concaténées au
un journal optimisé.
nouveau. Done.
16. Append-Only File
fsync() après chaque commande, chaque seconde ou
jamais.
On contrôle le moment où l’on souhaite réécrire le
journal.
Format future-proof et plus résistant aux corruptions
que les snapshots.
17. Avantages
Les sauvegardes ne bloquent jamais la lecture ni
l’écriture.
Habituellement, les bases de données ont du mal à
suivre lorsqu’il y a un grand nombre d’écritures.
(même les bases nosql, lorsque les données sont
persistantes...)
Les accès aléatoires ne sont pas bien plus coûteux que
les accès séquentiels.
18. La persistance : pourquoi ?
Pour pouvoir redémarrer avec un cache qui n’est pas
vide.
Pour éventuellement ne pas avoir besoin d’une autre
base de données.
21. Les chaînes
clef (chaîne) -> valeur (chaîne)
2^32-1 clefs d’1 Go max (2^64-1 clefs en interne)
GET / SET / EXISTS
DEL (multiple, atomique)
MGET / MSET (multiple, atomique)
INCR / DECR / INCRBY / DECRBY / APPEND
22. Les chaînes
SETNX user:1:_lock 1
...
SETNX DEL user:1:_lock
MSETNX
MSETNX
peuvent se combiner user:1:name -> bob
avec EXPIRE pour user:1:zipcode -> 46310
éviter les deadlocks user:1:_lock -> 1
...
DEL user:1:_lock
26. MySQL...
SELECT * FROM table ORDER BY RAND() LIMIT 1
SELECT * FROM table
WHERE id >=
(SELECT FLOOR(MAX(id) * RAND()) FROM table)
ORDER BY id LIMIT 1;
27. MySQL...
If there are some holes in the table you can fix it by:
SELECT (SELECT myTable2.id from myTable myTable2
where myTable2.id>=b.num
LIMIT 1) c FROM (SELECT FLOOR(RAND() * (SELECT
count(*) FROM myTable)) num
,@num:=@num+1 from (SELECT @num:=0) a , myTable
LIMIT X) b ;
28. MySQL...
To improve performance you can combine this solution
with a left join:
SELECT IF(c.id is null, (SELECT c2.id FROM myTable c2
WHERE c2.id > b.num
LIMIT 1), c.id) d FROM (SELECT FLOOR(RAND() *
(SELECT count(*) FROM myTable))
num ,@num:=@num+1 FROM (SELECT @num:=0) a ,
myTable LIMIT X) b LEFT JOIN
myTable c ON( c.id=b.num);
29. MySQL...
«The solution to account for gaps produces results
weighted toward id values
that follow gaps.»
Oops!
30. MySQL...
«On ajoute un champ avec des nombres aléatoires et à
chaque lecture, on permute celui qu’on vient de lire
avec celui d’une autre ligne au hasard !»
Wow.
33. Les listes
Compactes - 64 Mo Jusqu’à 2^32-1
pour une liste d’1 million éléments par liste.
d’éléments. N’ayez pas
Tout comme les clefs de
peur !
type «string», les clefs de
Mais moins que du ce type peuvent expirer,
JSON / Igbinary / Thrift / être effacées en groupe,
Protobuf... renomées et extraites
aléatoirement.
35. Les listes
todo processing
Tâche 1 Tâche 2 Tâche 3
RPOPLPUSH todo processing
Worker
36. Les listes
todo processing
Tâche 1 Tâche 2 Tâche 3
RPOPLPUSH todo processing Retourne Tâche 3
Worker
37. Les listes
todo processing
Tâche 1 Tâche 2 Tâche 3
RPOPLPUSH processing todo
Nettoyeur
(n’oubliez pas le lock !)
38. Les listes : BLPOP/BRPOP
Retourne et efface le
dernier élément
S’il n’y en a pas, attend
(max 10 sec) qu’il y en
BRPOP queue 10 ait un
Deux clients
n’obtiendront jamais le
même élément.
39. Les listes : BLPOP/BRPOP
Tente d’obtenir un
élément de queue1
BRPOP Sinon, tente dans
queue1 queue2 queue3 queue2, puis queue3.
10 Génial pour gérer des
listes de tâches avec
des priorités
40. Les listes : BLPOP/BRPOP
BLPOP : devinez :)
BRPOPPUSH : dans la TODO list pour la v1.4
41. SORT
Retourne une copie triée des éléments d’une liste, d’un
ensemble ou d’un zset.
Mais pas seulement !
42. SORT : Warning!
users = [ joe, robert, john ]
SORT users
1. robert
2. joe
3. john
43. SORT
users = [ joe, robert, john ]
SORT users ALPHA
1. joe
2. john
3. robert
44. SORT
users = [ joe, robert, john ]
SORT users ALPHA DESC LIMIT 0 2
1. robert
2. john
45. SORT
users = [ joe, robert, john ]
DEL stcache
SORT users ALPHA DESC LIMIT 0 2 STORE stcache
EXPIRE stcache 30
LRANGE stcache 0 50
47. SORT
users = [ 1, 2, 3 ]
SORT users
BY user:*:age user:1:name frank
user:1:age 30
3 user:2:name robert
1 user:2:age 42
2 user:3:name anais
user:3:age 3
(si les préfixes sont longs,
pensez à à sharedobjects)
48. SORT
SORT users
user:1:name frank
BY user:*:age
user:1:age 30
GET user:*:name
user:2:name robert
user:2:age 42
anais
user:3:name anais
frank
user:3:age 3
robert
49. SORT
SORT users
BY user:*:age
user:1:name frank
GET #
user:1:age 30
GET user:*:name
user:2:name robert
GET user:*:age
user:2:age 42
user:3:name anais
3 anais 3
user:3:age 3
1 frank 30
2 robert 42
50. SORT : astuces
Récupère tous les éléments d’une liste, sans tri :
SORT list BY none
Récupère tous les utilisateurs, triés par identifiants :
SORT users GET # GET user:*:name GET user:*:age
Récupère tous les utilisateurs, sans tri :
combinez les deux :)
51. Les ensembles (sets)
Listes d’éléments distincts
Jusqu’à 2^32-1 éléments par ensemble
74 Mo pour une clef avec 1 million d’éléments
«clef primaire» ou «liste des membres de...»
L’ordre n’est pas garanti lors d’un SORT BY xyz
RANDOMKEY, EXPIRE, RENAME, ...
56. Les ensembles : SUNION
iphone = [ 1, 5, 8, 10 ]
union des ensembles, ruby = [ 2, 4, 5, 10 ]
mais le résultat reste
un SET : il ne contient
donc que des valeurs SUNION iphone ruby
uniques.
[ 4, 5, 8, 10, 1, 2 ]
57. Les ensembles (sets)
16/02/2010 1 8 12 23
15/02/2010 2 10 19
14/02/2010 2 7 11 19 24
SUNION / SINTER :
Visiteurs uniques ou qui reviennent d’un jour sur l’autre
63. Les ensembles triés (Zsets)
Liste d’éléments uniques
À chaque élément est associé un «score» (double)
L’ensemble est toujours pré-trié selon le score.
65. Les ensembles triés (Zsets)
ZADD / ZREM : ajoute / retire un élément
ZCARD : retourne le nombre d’éléments
ZINCRBY : ajoute / retire un nombre au score
précédent
ZSCORE : change le score d’un élément
66. Les ensembles triés (Zsets)
ZRANGE 0 -1 : retourne tous les éléments, classés par
score
ZRANGE 0 9 : retourne ceux qui ont les 10 plus petits
scores
ZRANGE 10 19 : pour la pagination
67. Les ensembles triés (Zsets)
ZREVRANGE 0 -1 : retourne tous les éléments, classés
par scores décroissants
ZREVRANGE 0 9 : retourne ceux qui ont les 10
meilleurs scores
ZREVRANGE 10 19 : pour la pagination
68. Les ensembles triés (Zsets)
ZRANGEBYSCORE 2 200000 : retourne tous les
éléments dont le score est entre 2 et 200000
ZRANGEBYSCORE supporte aussi la pagination (LIMIT
offset count) et peut retourner les scores en plus des
éléments (WITHSCORE)
ZCOUNT : compte le nombre d’éléments dont le score
est situé dans un intervalle
Bornes ouvertes ou fermées : (2 200000 : 2 est exclu.
69. Les ensembles triés (Zsets)
Classements en temps réel, y compris avec des
millions de données
Tris avec des critères sur mesure
Implémentations d’autres structures de données
(ex: trie)
Bientôt : ZPREV / ZNEXT (x éléments précédant /
suivant un élément de référence), ZRANK (rang d’un
élément), INTER et UNION.
73. La mémoire virtuelle
La RAM, ça va vite
Les disques (même SSD) beaucoup moins
L’OS attribue aux applications des pages de mémoire,
qui peuvent être de la mémoire physique ou sur disque.
74. La mémoire virtuelle
Les pages dont on a (à vue de nez) besoin
immédiatement : l’OS essaye de les placer / déplacer
en mémoire physique
Les pages dont on n’a (à vue de nez) pas besoin dans
l’immédiat : l’OS essaye de les déplacer sur disque
Tout espace réellement disponible en RAM peut être
utilisé comme cache disque
75. La mémoire virtuelle
La mémoire virtuelle permet aussi aux applications
d’utiliser une plus grande quantité de mémoire que la
mémoire physique disponible.
Pourquoi ne pas s’en servir pour que Redis puisse
stocker plus de données que ce que la mémoire peut
contenir ?
Le pire c’est que... ça fonctionne.
77. La mémoire virtuelle
L’OS n’a aucune idée de la structure des données
applicatives
La taille d’une page mémoire est généralement entre 4
Ko et 16 Ko
Dans Redis, une valeur occupe plusieurs blocs de
mémoire non consécutifs
Les structures de données sont optimisées pour une
recherche en RAM
78. La mémoire virtuelle
On peut écrire les données de façon beaucoup plus
simple sur disque et surtout beaucoup plus compacte.
Moins d’espace de stockage => moins d’I/O
Redis a sa propre gestion de la mémoire virtuelle
79. La mémoire virtuelle
Espace de stockage divisé en pages, mais la taille des
pages peut être librement choisie
Toutes les clefs sont en RAM
Les valeurs peuvent être en disque ou en RAM
Redis sait toujours quelles clefs sont sur disque, leur
taille et leur position exacte.
80. La mémoire virtuelle
Redis peut être configuré pour conserver les valeurs
uniquement sur disque : si 1 million de clefs prennent
200 Mo, il n’y aura toujours que 200 Mo d’utilisé
quelque soit ce que les clefs contiennent.
81. La mémoire virtuelle
Une quantité maximale de RAM à utiliser peut être
configurée.
Les valeurs sont transférées sur disque en fonction de
leur «swappabilité» :
= temps écoulé depuis la dernière utilisation * taille
Gestion threadée des copies de/vers le disque.
83. Modèle Redis vs Memcache
Architecture «traditionnelle» : tout est sur disque et on
stocke les lectures les plus récentes dans memcache
Redis : un «cache» qui stocke éventuellement les
données les moins utiles sur disque
84. Modèle Redis vs Memcache
Architecture (hélas) classique : on met à jour une base
SQL, puis on met à jour memcache. Si la base SQL se
traîne, tout traîne. Et les incohérences entre les caches
et les bases arrivent vite.
Redis : on ne met à jour que Redis, qui s’occupe aussi
de la durabilité sans bloquer les accès clients, qui
s’effectuent en mémoire.
Scale en lecture mais aussi en écriture.
95. La réplication
Réplication Master -> Slaves
Reconfigurable à chaud
Asynchrone
EXPIRE transformé en EXPIREAT
COW comme pour les snapshots
96. La réplication
Le slave n’a pas besoin d’avoir des données de départ
Le master effectue un dump en tâche de fond
Le slave attend la fin du dump puis le charge
Le master transmet au slave la liste des modifications
effectuées pendant le dump ainsi que les modifications
suivantes
La réplication ne bloque jamais le master
105. Le protocole
Authentification simple (mot de passe)
Protocole binary-safe
Pipelining
TCP uniquement, mais l’attente de la réponse du
serveur n’est pas obligatoire.
L’UDP est dans la TODO-list.
106. Les bibliothèques clientes
Actionscript 3 Groovy
C (Credis) Haskell
Clojure Java
Common Lisp LUA
Erlang .NET
Go NodeJS
108. :(
Sharding uniquement supporté en Ruby (redis-rb), PHP
(Redisent, Rediska, Predis) et Scala.
Il est possible de grouper des clefs sur un shard en
respectant certaines conventions pour le nom de ces
clefs.
Ce n’est que du sharding, il n’y a aucune redondance
ni reconfiguration.
Pas de Spymemcached ni de Moxi.