Redis (PHP Unconference 2012, deutsch)

2,016 views
1,941 views

Published on

Grundlagen, Features und Einsatzzwecke von Redis

Published in: Technology
2 Comments
3 Likes
Statistics
Notes
  • Danke für's Feedback :)
    Da es hier eher um die grundlegenden Features von Redis geht, habe ich die Punkte mit der Speicheroptimierung hier absichtlich weggelassen. Natürlich ist es richtig, aber geht eventuell schon zu weit. Gleiches gilt für die Schreiboperationen in einem LUA-Script.

    Dass die bisherigen Transaktionen bald entfernt werden, werde ich noch hinzufügen. Danke für den Hinweis ;)
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Bei Listen und Hashes sollte man ggf. erwähnen, dass die je nach Größe anders gespeichert bzw. kodiert werden, was in einigen Fällen wichtig sein kann (siehe http://redis.io/topics/memory-optimization).

    Die Transaktionen werden bald aus Redis entfernt, da diese Funktionalität seit der Version 2.6 über LUA-Skripte abbildbar und somit doppelt vorhanden ist (siehe http://redis.io/topics/transactions).

    Beim Skripting finde ich wichtig zu erwähnen, dass ein Skript, welches mind. eine schreibende Operation ausgeführt hat, nicht mehr beendet werden kann. Dafür muss dann der Server per 'SHUTDOWN NOSAVE' beendet werden (siehe http://redis.io/commands/eval).
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
No Downloads
Views
Total views
2,016
On SlideShare
0
From Embeds
0
Number of Embeds
21
Actions
Shares
0
Downloads
0
Comments
2
Likes
3
Embeds 0
No embeds

No notes for slide

Redis (PHP Unconference 2012, deutsch)

  1. 1. Wer bin ich? Norman Soetbeer Twitter: @TheBattleRattleGame Developer @ InnoGames
  2. 2. Redis LevelDB Key-Value Storages MemcacheDB Document Storages NoSQL … Graph-Datenbanken Datenbanken SQL …
  3. 3. In-Memory alle Daten immer im RAM sehr schnell – 100.000 Schreibzugriffe / Sekunde – 80.000 Lesezugriffe / SekundeSingle-Threaded non-blocking I/O Ausnahme: Threads für Festplattenzugriffe
  4. 4. Key Valueplayer:1:name SuperPimp99player:1:score 12345player:2:name MegaBasher12player:2:score 45678town:27:name Troja… …
  5. 5. Key Valueplayer:1:name SuperPimp99player:1:score 12345player:2:name MegaBasher12player:2:score 45678town:27:name Troja… … beliebige Zeichenkette (binary-safe) keine Maximallänge bekannt ABER: längere Strings = mehr Speicher + schlechtere Performance
  6. 6. Key Valueplayer:1:name SuperPimp99player:1:score 12345player:2:name MegaBasher12player:2:score 45678town:27:name Troja… …  verschiedene Datentypen
  7. 7. Allgemeine Befehle EXPIRE / EXPIREAT: Lifetime für einen Eintrag setzen TTL: verbleibende Lifetime bestimmen PERSIST: entfernt Ablaufzeit EXISTS: Existenz eines Eintrags prüfen TYPE: Datentyp eines Eintrags bestimmen
  8. 8. String Key Value player:1:name SuperPimp99 player:1:score 12345 player:2:name MegaBasher12 player:2:score 45678 town:27:name Troja … … beliebige Zeichenkette (binary-safe) max. 512 MB
  9. 9. String Key Value player:1:name SuperPimp99 player:1:score 12345 player:2:name MegaBasher12 player:2:score 45678 town:27:name Troja … …Wert lesen SchlüsselnameGET player:1:name"SuperPimp99"
  10. 10. String Key Value player:1:name SuperPimp99 Klaus player:1:score 12345 player:2:name MegaBasher12 player:2:score 45678 town:27:name Troja … …Wert schreiben Schlüsselname WertSET player:1:name KlausOK
  11. 11. String Key Value player:1:name Klaus player:1:score 12345 player:2:name MegaBasher12 player:2:score 45678 town:27:name Troja … …Wert schreiben, falls noch nicht vorhanden Schlüsselname WertSETNX player:1:name Hans0
  12. 12. String Key Value player:1:name Klaus player:1:score 12345 player:2:name MegaBasher12 player:2:score 45678 town:27:name Troja … …Länge eines Strings bestimmen SchlüsselnameSTRLEN player:2:name12
  13. 13. String Key Value player:1:name Klaus Meier player:1:score 12345 player:2:name MegaBasher12 player:2:score 45678 town:27:name Troja … …String anhängen Schlüsselname WertAPPEND player:1:name " Meier"11
  14. 14. String Key Value player:1:name Klaus Meier player:1:score 12345 player:2:name MegaBasher12 player:2:score 45678 town:27:name Troja … …Teil eines Strings auslesen / schreiben Schlüsselname End-OffsetGETRANGE player:1:name 1 4"laus" Start-Offset
  15. 15. String Key Value player:1:name Klaus Meier player:1:score 12345 player:2:name MegaBasher12 01001011 01101100 … player:2:score 45678 town:27:name Troja … …Einzelne Bits setzen / auslesen Schlüsselname OffsetGETBIT player:1:name 61
  16. 16. String Key Value player:1:name Klaus Meier player:1:score 12345 12346 player:2:name MegaBasher12 player:2:score 45678 town:27:name Troja … …Inkrement / Dekrement SchlüsselnameINCR player:1:score12346
  17. 17. StringAnwendungsbeispiele Speicherung "einfacher" Werte Flags (Key vorhanden / nicht vorhanden) Zähler Sequenz / ID-Generator
  18. 18. Liste Key Value … … player:1:actions account:login build:main recruit:sword account:logout … … Sequenz von Elementen (Strings) in definierter Reihenfolge max. 232-1 Elemente pro Liste
  19. 19. Liste Key Value … … LPUSH RPUSH player:1:actions account:login build:main recruit:sword account:logout account:login … …Elemente anhängen Schlüsselname WertRPUSH player:1:actions account:login5
  20. 20. Liste Key Value … … player:1:actions build:main recruit:sword account:logout account:login … LPOP … RPOP account:loginElemente entfernen SchlüsselnameLPOP player:1:actions"account:login"
  21. 21. Liste Key Value … … player:1:actions build:main recruit:sword account:logout account:login … …Länge der Liste bestimmen SchlüsselnameLLEN player:1:actions4
  22. 22. Liste Key Value … … player:1:actions build:main recruit:sword account:logout account:login 0 1 2 3 … … (-4) (-3) (-2) (-1)Element an beliebiger Position auslesen Schlüsselname OffsetLINDEX player:1:actions 1"recruit:sword"
  23. 23. Liste Key Value … … player:1:actions build:main recruit:sword account:logout account:login 0 1 2 3 … … (-4) (-3) (-2) (-1)Sequenz auslesen Schlüsselname End-OffsetLRANGE player:1:actions 1 3"recruit:sword" Start-Offset"account:logout""account:login"
  24. 24. Liste Key Value … … 0 1 2 3 (-4) (-3) (-2) (-1) vorher player:1:actions build:main recruit:sword account:logout account:login player:1:actions recruit:sword account:logout nachher 0 1 … … (-2) (-1)Liste kappen Schlüsselname End-OffsetLTRIM player:1:actions 1 2OK Start-Offset
  25. 25. ListeAnwendungsbeispiele Queue (RPUSH + LPOP) Stack (RPUSH + RPOP) Verlauf (letzte Aktionen, letzte Beiträge, Chat-Nachrichten)
  26. 26. Hash Key Value … … name SuperPimp99 player:1 level 12 experience 345 … … assoziative Abbildung: String => String max. 232-1 Schlüssel-Wert-Paare pro Hash
  27. 27. HashBefehle ähnlich wie bei Strings: Attribut(e) schreiben/lesen (HSET, HGET, HMSET, HMGET) alle Attribute lesen (HGETALL) Attribut(e) löschen (HDEL) Anzahl der Attribute bestimmen (HLEN) Inkrementieren (HINCRBY)Anwendungsbeispiele: Objekt-Speicher / Objekt-Cache
  28. 28. Menge (Set) Key Value … … active_users: 34 918 2012-08-17 7 713 291 … … ungeordnete Sammlung von Elementen (Strings) jedes Element höchstens einmal in Set vorhanden max. 232-1 Elemente pro Set
  29. 29. Menge (Set) Key Value … … active_users: 34 918 2012-08-17 291 7 713 291 … …Element(e) hinzufügen Schlüsselname WertSADD active_users:2012-08-17 1231
  30. 30. Menge (Set) Key Value … … active_users: 34 918 2012-08-17 291 7 713 291 … …Element(e) entfernen Schlüsselname WertSREM active_users:2012-08-17 2911
  31. 31. Menge (Set) Key Value … … active_users: 34 918 2012-08-17 291 7 713 … …Überprüfen, ob Element in Set enthalten Schlüsselname WertSISMEMBER active_users:2012-08-17 something0
  32. 32. Menge (Set) Key Value … … active_users: 34 918 2012-08-17 291 7 713 … …Anzahl der Elemente bestimmen SchlüsselnameSCARD active_users:2012-08-175
  33. 33. Menge (Set) Key Value … … active_users: 34 918 2012-08-17 291 7 713 … …Zufälliges Element bestimmen SchlüsselnameSRANDMEMBER active_users:2012-08-17"918"
  34. 34. Menge (Set)Mengenoperationen: Vereinigung (SUNION, SUNIONSTORE) Durchschnitt (SINTER, SINTERSTORE) Differenz (SDIFF, SDIFFSTORE)Anwendungsbeispiele: "Unique"-Zähler Mitgliedschaften (Stamm, Allianz, Freundesliste) Flags für Spieler (Wert vorhanden / nicht vorhanden)
  35. 35. Sortierte Menge (Sorted Set) Key Value … … Score Wert (String) 123 SuperPimp99 ranking:players 456 UltraBasher14 999 PowerPumper 1337 GamerGirl2012 … … wie Set: jedes Element höchstens einmal vorhanden aber definierte Reihenfolge durch SCORE (double) stets aufsteigend sortiert max. 232-1 Elemente pro Sorted Set
  36. 36. Sortierte Menge (Sorted Set) Key Value … … 123 SuperPimp99 456 UltraBasher14 ranking:players 789 MegaFighter 999 PowerPumper 1337 GamerGirl2012 … …Element(e) hinzufügen / updaten Schlüsselname Score WertZADD ranking:players 789 MegaFighter1
  37. 37. Sortierte Menge (Sorted Set) Key Value … … 123 SuperPimp99 ranking:players 456 UltraBasher14 789 MegaFighter 999 PowerPumper 1337 GamerGirl2012 … …Element(e) entfernen Schlüsselname WertZREM ranking:players PowerPumper1
  38. 38. Sortierte Menge (Sorted Set) Key Value … … 123 SuperPimp99 ranking:players 456 UltraBasher14 789 MegaFighter 1337 GamerGirl2012 … …Anzahl der Elemente ermitteln SchlüsselnameZCARD ranking:players4
  39. 39. Sortierte Menge (Sorted Set) Key Value … … 0 123 SuperPimp99 ranking:players 1 456 UltraBasher14 2 789 MegaFighter 3 1337 GamerGirl2012 … …Rang eines Elements bestimmen Achtung! Schlüsselname Wert  aufsteigende ReihenfolgeZRANK ranking:players GamerGirl2012  Rang beginnt bei 03
  40. 40. Sortierte Menge (Sorted Set) Key Value … … 3 123 SuperPimp99 ranking:players 2 456 UltraBasher14 1 789 MegaFighter 0 1337 GamerGirl2012 … …Rang eines Elements bestimmen (absteigend) Schlüsselname WertZREVRANK ranking:players GamerGirl20120
  41. 41. Sortierte Menge (Sorted Set) Key Value … … 3 123 SuperPimp99 ranking:players 2 456 UltraBasher14 1 789 MegaFighter 0 1337 GamerGirl2012 … …Bereich auslesen (absteigend) Schlüsselname End-OffsetZREVRANGE ranking:players 0 2"GamerGirl2012" Start-Offset"MegaFighter""UltraBasher14"
  42. 42. Sortierte Menge (Sorted Set)Anwendungsbeispiele: Live-Ranking sortierte Mitgliedschaften (Allianzmitglieder nach Beitrittsdatum sortiert) Index für Hash-Attribute  Hashes für Spieler-Objekte "player:2": {"name": "Basher", "level": "50"}  Sorted Set als Index für "level"-Attribut "player:levels": {score: 50, value: "2"}  Abfrage: IDs aller Spieler mit Level zwischen 50 und 100, absteigend sortiert nach Level  SQL: SELECT id FROM players WHERE level BETWEEN 50 AND 100 ORDER BY level DESC  Redis: ZREVRANGEBYSCORE player:levels 50 100
  43. 43. BisherProblem: viele Round-Trips = langsam
  44. 44. Lösung: Pipeline Änderung der Abfolge von Senden u. Empfangen  S-E-S-E-S-E vs. S-S-S-E-E-E Implementierung clientseitig Befehlsausführung nicht atomar!
  45. 45. Beispiel: PHP + Predisrequire predis/autoload.php;$config = array( lokal entfernt (LAN) host => localhost, ohne Pipeline 1,86 Sek. 5,13 Sek. port => 6379, database => 0, mit Pipeline 1,60 Sek. 1,48 Sek.);$redis = new PredisClient($config);// ohne Pipeline$start = microtime(true);for ($i=0; $i<10000; $i++) { $redis->set(key . $i, $i);}printf("execution took %.2f secondsn", microtime(true) - $start);// mit Pipeline$start = microtime(true);$redis->pipeline(function($pipe) { for ($i=0; $i<10000; $i++) { $pipe->set(key . $i, $i); }});printf("execution took %.2f secondsn", microtime(true) - $start);
  46. 46. TransaktionenAbfolge: Beispiel: Transaktion starten (MULTI) MULTI Befehle senden OK  werden auf Server gesammelt SET first_key "test 1"  Antwort ist immer "QUEUED" (Ausnahme: Syntaxfehler) QUEUED Transaktion ausführen (EXEC) SET second_key "test 2" oder Transaktion abbrechen QUEUED (DISCARD) SET third_key "test 3" QUEUED EXEC OK OK OK
  47. 47. TransaktionenEigenschaften: Ausführung atomar "alles oder nichts"  bei DISCARD oder Verbindungsabbruch wird nichts ausgeführt  mit EXEC wird alles ausgeführt  Achtung: kein Abbruch/Rollback bei Fehlern!
  48. 48. Scripting Unterstützung ab Redis 2.6 analog zu Stored Procedures Sprache: LUA Scriptausführung:  "on the fly": LUA-Script 1. Parameter EVAL "return redis.call(set, KEYS[1], bar)" 1 foo OK Parameter-Anzahl  speichern und später ausführen: LUA-Script SCRIPT LOAD "return redis.call(set, KEYS[1], bar)" "f8211e1772142e888d2b3eef9fd3894eb1b06b17" SHA1-Hash des Scripts 1. Parameter EVALSHA f8211e1772142e888d2b3eef9fd3894eb1b06b17 1 foo OK Parameter-Anzahl atomar => langsames Script kann Server ausbremsen!
  49. 49. Publish/SubscribePublisher: verschickt Nachrichten an KanäleSubscriber: lauscht auf einem oder mehreren Kanälen empfängt Nachrichten des Publishers
  50. 50. Publish/Subscribe S1 P1 P2 logs.critical S2 P3 S3Channel abonnieren Channel-NameSUBSCRIBE "logs.critical"1
  51. 51. Publish/Subscribe S1 P1 P2 logs.critical S2 P3 S3Channel mit Platzhaltern abonnieren Muster MusterPSUBSCRIBE "logs.*" "chat.*"1
  52. 52. Publish/Subscribe S1 P1 "something happened" P2 logs.critical S2 P3 S3Nachricht senden Channel NachrichtPublish "logs.warning" "something happened"2
  53. 53. Publish/Subscribe S1 P1"something critical happened" "something critical happened" P2 logs.critical S2 P3 S3 Nachricht senden Channel Nachricht Publish "logs.critical" "something critical happened" 3
  54. 54. PersistenzRDB - Dump "point-in-time snapshot" wird erstellt, wenn X Update-Operationen in Y Sekunden erfolgt Standardeinstellungen: save 900 1 Dump, wenn mind. 1 Update in 15 Minuten save 300 10 Dump, wenn mind. 10 Updates in 5 Minuten save 60 10000 Dump, wenn mind. 10.000 Updates in 1 Minute Vorteile:  Einspielen des Backups relativ schnell Nachteile:  Datenverlust kann groß sein  Speichervorgang aufwendig (große Datenmenge)
  55. 55. PersistenzAOF (append-only-file) jeder einzelne Befehl geloggt Wiedereinspielen der Daten durch Ausführung dieser Befehle Schreib-Intervall konfigurierbar:  OS entscheidet (schnell)  jedes Query (langsam, aber sicher)  jede Sekunde (Kompromiss) Vorteile:  relativ sicher, Datenverlust gering Nachteile:  Einspielen des Backups langsam
  56. 56. PersistenzRDB vs. AOF keine Lösung besser oder schlechter als die andere=> Entscheidung: Wie kritisch ist ein Datenverlust? beides auch in Kombination nutzbar
  57. 57. SkalierbarkeitMaster-Slave-Replikation 1 Master, mehrere Slaves Slaves können selbst weitere Slaves besitzen Synchronisierung: Master -> Slave  Slaves können Schreiboperationen ausführen, aber nicht mit Master synchronisieren! einfache Handhabung:  Server als Slave starten: redis-server --slaveof 127.0.0.1 6379  automatische Synchronisierung  Auto-Reconnect bei Verbindungsabbruch
  58. 58. SkalierbarkeitRedis Cluster (noch in Alpha-Phase!) bis zu 4096 Knoten Ziel: lineare Skalierbarkeit Schlüssel werden auf Knoten verteilt ("Consistent Hashing") Redundanz-Faktor konfigurierbar ("Live-Backup")  Jeder Schlüssel existiert auf 1 Master + N Slaves (Slaves = read-only) Fehlertoleranz:  Knoten "pingen" sich gegenseitig  bei Timeout wird Knoten als "nicht verfügbar" markiert (alle Knoten des Clusters werden informiert)  Wenn Knoten wieder online ist, wird er "runtergefahren" (mögliche Dateninkonsistenz)
  59. 59.  http://redis.io http://www.cafebabe.me/2011/05/redis-pipelines-and- transactions.html
  60. 60. Vielen Dankfür die Aufmerksamkeit! Fragen?

×