Obsah
1. Využití Redisu z jazyka Clojure pomocí knihovny Carmine
2. Překlad a instalace Redisu verze 6.2 (6.2.6)
3. Spuštění Redisu a kontrola připojení z CLI klienta
4. Klient pro systém Redis naprogramovaný v jazyce Clojure
5. Připojení k Redisu, poslání zprávy PING a obdržení zprávy PONG
6. Pomocné makro wcar* vytvořené pro každé připojení k Redisu
7. Alternativní způsob definice připojení k Redisu
8. Podporované datové typy, s nimiž Redis pracuje
9. Práce s řetězci uloženými do databáze
10. Uložení řetězce a zpětné přečtení řetězce realizované v Clojure
12. Manipulace s číselnými hodnotami iniciovaná z Clojure
13. Uložení strukturovaných dat do Redisu: síla kombinace Redis+Clojure
15. Manipulace se seznamy uloženými v Redisu z Clojure
17. Repositář s demonstračními příklady
18. Předchozí články o systému Redis
19. Odkazy na předchozí části seriálu o programovacím jazyku Clojure
1. Využití Redisu z jazyka Clojure pomocí knihovny Carmine
V dnešním článku, který je součástí seriálu o programovacím jazyku Clojure se seznámíme se způsobem využití systému Redis v aplikacích vyvinutých právě v Clojure. Jak již bylo zmíněno v perexu, použijeme pro tento účel knihovnu Carmine. O tom, proč je někdy vhodné zkombinovat možnosti nabízené jazykem Clojure se systémem Redis, jsme se již taktéž ve stručnosti zmínili – plně se zde využije schopnost zpracování složitě strukturovaných dat v Clojure s flexibilitou a rychlostí Redisu.
2. Překlad a instalace Redisu verze 6.2 (6.2.6)
Redis může být na některých systémech již nainstalován. To, jaká verze serveru je aktuálně nainstalována, lze zjistit následujícím příkazem:
$ redis-server --version
Na mnoha systémech nalezneme stále verzi 4.x (kterou v dnešním článku nelze využít) nebo 5.0.x, což je ostatně i případ mnou používaného systému Fedora 32:
Redis server v=5.0.9 sha=00000000:0 malloc=jemalloc-5.1.0 bits=64 build=699c550ace009f13
V případě, že se v repositářích vaší distribuce z nějakého důvodu nenachází novější verze Redisu, lze ji přeložit a nainstalovat přímo ze zdrojových kódů. To ve skutečnosti není nic složitého, protože závislosti Redisu jsou pouze minimální: základní knihovna glibc a volitelně též knihovna jemalloc (její použití je však možné zakázat, což může mít vliv na rychlost práce s pamětí, popř. na požadavky na větší množství virtuální paměti).
Poslední stabilní verzí Redisu je verze 6.2.6, takže se ji pokusíme nainstalovat. Stažení zdrojových kódů Redisu 6.2.6:
$ wget https://download.redis.io/releases/redis-6.2.6.tar.gz --2022-01-24 19:53:49-- https://download.redis.io/releases/redis-6.2.6.tar.gz Resolving download.redis.io (download.redis.io)... 45.60.123.1 Connecting to download.redis.io (download.redis.io)|45.60.123.1|:443... connected. HTTP request sent, awaiting response... 200 OK Length: 2476542 (2,4M) [application/octet-stream] Saving to: ‘redis-6.2.6.tar.gz’ redis-6.2.6.tar.gz 100%[===================>] 2,36M 3,47MB/s in 0,7s 2022-01-24 19:53:50 (3,47 MB/s) - ‘redis-6.2.6.tar.gz’ saved [2476542/2476542]
Rozbalení tarballu:
$ tar xvfz redis-6.2.6.tar.gz
Překlad a instalace (pro jednoduchost se nepoužívá knihovna jmalloc):
$ cd redis-6.0.10 $ make distclean; make MALLOC=libc; make $ make install
Kontrola, jaká verze Redisu je nyní k dispozici:
$ redis-server --version Redis server v=6.2.6 sha=00000000:0 malloc=jemalloc-5.1.0 bits=64 build=eaea6515c6f672a7
3. Spuštění Redisu a kontrola připojení z CLI klienta
V dalších kapitolách se předpokládá, že se klienti budou připojovat k běžícímu serveru Redisu, a to na standardním portu 6379. Chování serveru, volba úložiště dat, jeho dostupnost i mimo lokální síť atd. jsou pochopitelně plně konfigurovatelné. O několika důležitých konfiguračních volbách jsme se již zmínili v tomto textu (ovšem určeném ještě pro Redis 4.x). Samotný server se spouští příkazem redis-server:
$ redis-server
Po spuštění by se měla vypsat informace o verzi Redisu, použitém konfiguračním souboru (ve výpisu níže není konfigurační soubor specifikován) a především o portu, ke kterému je možné se připojit z klientů:
26769:C 24 Jan 2022 19:57:44.333 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo 26769:C 24 Jan 2022 19:57:44.333 # Redis version=6.2.6, bits=64, commit=00000000, modified=0, pid=26769, just started 26769:C 24 Jan 2022 19:57:44.333 # Warning: no config file specified, using the default config. In order to specify a config file use ./redis-server /path/to/redis.conf 26769:M 24 Jan 2022 19:57:44.334 # You requested maxclients of 10000 requiring at least 10032 max file descriptors. 26769:M 24 Jan 2022 19:57:44.334 # Server can't set maximum open files to 10032 because of OS error: Operation not permitted. 26769:M 24 Jan 2022 19:57:44.334 # Current maximum open files is 4096. maxclients has been reduced to 4064 to compensate for low ulimit. If you need higher maxclients increase 'ulimit -n'. 26769:M 24 Jan 2022 19:57:44.334 * monotonic clock: POSIX clock_gettime _._ _.-``__ ''-._ _.-`` `. `_. ''-._ Redis 6.2.6 (00000000/0) 64 bit .-`` .-```. ```\/ _.,_ ''-._ ( ' , .-` | `, ) Running in standalone mode |`-._`-...-` __...-.``-._|'` _.-'| Port: 6379 | `-._ `._ / _.-' | PID: 26769 `-._ `-._ `-./ _.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | https://redis.io `-._ `-._`-.__.-'_.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | `-._ `-._`-.__.-'_.-' _.-' `-._ `-.__.-' _.-' `-._ _.-' `-.__.-' 26769:M 24 Jan 2022 19:57:44.334 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128. 26769:M 24 Jan 2022 19:57:44.334 # Server initialized 26769:M 24 Jan 2022 19:57:44.334 # 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. 26769:M 24 Jan 2022 19:57:44.334 * Loading RDB produced by version 6.2.6 26769:M 24 Jan 2022 19:57:44.334 * RDB age 57 seconds 26769:M 24 Jan 2022 19:57:44.334 * RDB memory usage when created 0.51 Mb 26769:M 24 Jan 2022 19:57:44.334 # Done loading RDB, keys loaded: 0, keys expired: 0. 26769:M 24 Jan 2022 19:57:44.334 * DB loaded from disk: 0.000 seconds 26769:M 24 Jan 2022 19:57:44.334 * Ready to accept connections
V případě, že je server spuštěn v samostatném terminálu, je ho možné ukončit buď klávesovou zkratkou Ctrl+C nebo (jak je to běžné) příkazem kill:
^C 26769:signal-handler (1611248833) Received SIGINT scheduling shutdown... 26769:M 24 Jan 2022 20:07:13.469 # User requested shutdown... 26769:M 24 Jan 2022 20:07:13.469 * Saving the final RDB snapshot before exiting. 26769:M 24 Jan 2022 20:07:13.471 * DB saved on disk 26769:M 24 Jan 2022 20:07:13.471 # Redis is now ready to exit, bye bye...
Nyní se k serveru zkusíme připojit ze standardního klienta:
$ redis-cli
Prakticky ihned by se měla objevit výzva:
127.0.0.1:6379>
Vyzkoušíme základní komunikaci příkazem PING. Server by měl odpovědět zprávou PONG:
127.0.0.1:6379> PING PONG
Vypsat si můžeme i konfiguraci serveru, a to konkrétně příkazem INFO:
127.0.0.1:6379> INFO # Server redis_version:6.2.6 redis_git_sha1:00000000 redis_git_dirty:0 redis_build_id:eaea6515c6f672a7 redis_mode:standalone arch_bits:64 multiplexing_api:epoll atomicvar_api:c11-builtin gcc_version:7.3.1 process_id:7714 process_supervised:no ... ... ... 127.0.0.1:6379>
4. Klient pro systém Redis naprogramovaný v jazyce Clojure
Nyní si ukažme, jakým způsobem je možné naprogramovat jednoduchého klienta pro systém Redis, a to s využitím programovacího jazyka Clojure a knihovny Carmine. Nejprve je nutné vytvořit nový projekt v Clojure. Pro tento účel využijeme systém Leiningen (i když novější verze Clojure se již mnohdy bez Leiningenu obejdou):
$ lein new app carmine1 Generating a project called carmine1 based on the 'app' template.
Výše uvedený příkaz vytvoří projekt v adresáři nazvaném „carmine1“, v němž se mj. nachází i projektový soubor „project.clj“:
$ cat project.clj (defproject carmine1 "0.1.0-SNAPSHOT" :description "FIXME: write description" :url "http://example.com/FIXME" :license {:name "EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0" :url "https://www.eclipse.org/legal/epl-2.0/"} :dependencies [[org.clojure/clojure "1.10.1"]] :main ^:skip-aot carmine1.core :target-path "target/%s" :profiles {:uberjar {:aot :all :jvm-opts ["-Dclojure.compiler.direct-linking=true"]}})
Tento projektový soubor je zapotřebí upravit – přidat do něj závislost na knihovně Carmine. Viz zvýrazněný řádek:
(defproject carmine1 "0.1.0-SNAPSHOT" :description "FIXME: write description" :url "http://example.com/FIXME" :license {:name "EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0" :url "https://www.eclipse.org/legal/epl-2.0/"} :dependencies [[org.clojure/clojure "1.10.1"] [com.taoensso/carmine "3.1.0"]] :main ^:skip-aot carmine1.core :target-path "target/%s" :profiles {:uberjar {:aot :all :jvm-opts ["-Dclojure.compiler.direct-linking=true"]}})
Nyní můžeme přistoupit k dalšímu kroku, a to konkrétně ke stažení všech balíčků, na nichž tento projekt závisí. Kromě první knihovny (Carmine) se jedná o tranzitivní závislosti:
$ lein deps Retrieving com/taoensso/carmine/3.1.0/carmine-3.1.0.pom from clojars Retrieving com/taoensso/encore/3.9.2/encore-3.9.2.pom from clojars Retrieving com/taoensso/truss/1.6.0/truss-1.6.0.pom from clojars Retrieving com/taoensso/timbre/5.1.0/timbre-5.1.0.pom from clojars Retrieving com/taoensso/encore/3.4.0/encore-3.4.0.pom from clojars Retrieving io/aviso/pretty/0.1.37/pretty-0.1.37.pom from clojars Retrieving com/taoensso/nippy/3.1.1/nippy-3.1.1.pom from clojars Retrieving org/clojure/tools.reader/1.3.4/tools.reader-1.3.4.pom from central Retrieving org/iq80/snappy/snappy/0.4/snappy-0.4.pom from central Retrieving org/tukaani/xz/1.8/xz-1.8.pom from central Retrieving org/lz4/lz4-java/1.7.1/lz4-java-1.7.1.pom from central Retrieving org/apache/commons/commons-pool2/2.9.0/commons-pool2-2.9.0.pom from central Retrieving org/apache/commons/commons-parent/52/commons-parent-52.pom from central Retrieving org/apache/apache/23/apache-23.pom from central Retrieving commons-codec/commons-codec/1.15/commons-codec-1.15.pom from central Retrieving org/iq80/snappy/snappy/0.4/snappy-0.4.jar from central Retrieving org/tukaani/xz/1.8/xz-1.8.jar from central Retrieving org/lz4/lz4-java/1.7.1/lz4-java-1.7.1.jar from central Retrieving commons-codec/commons-codec/1.15/commons-codec-1.15.jar from central Retrieving org/apache/commons/commons-pool2/2.9.0/commons-pool2-2.9.0.jar from central Retrieving com/taoensso/encore/3.9.2/encore-3.9.2.jar from clojars Retrieving com/taoensso/timbre/5.1.0/timbre-5.1.0.jar from clojars Retrieving com/taoensso/nippy/3.1.1/nippy-3.1.1.jar from clojars Retrieving com/taoensso/truss/1.6.0/truss-1.6.0.jar from clojars Retrieving com/taoensso/carmine/3.1.0/carmine-3.1.0.jar from clojars
5. Připojení k Redisu, poslání zprávy PING a obdržení zprávy PONG
Ukažme si nyní, jak by mohl vypadat program napsaný v jazyku Clojure, který se po svém spuštění připojí k Redisu, pošle mu zprávu PING a zobrazí odpověď, což by měla být zpráva PONG (to jsme si ostatně ukázali ve druhé kapitole). Nejprve je nutné provést import knihovny Carmine:
(ns carmine1.core (:require [taoensso.carmine :as carmine)]))
V případě, že budeme chtít k některým symbolům (funkcím, makrům) přistupovat bez uvedení jména balíčku, můžeme tyto symboly korektně označit. Často budeme používat symbol wcar:
(ns carmine1.core (:require [taoensso.carmine :as carmine :refer (wcar)]))
Následně vytvoříme datovou strukturu (mapu) s informacemi o připojení k Redisu. Specifikovat je nutné především adresu a port, nepovinně též jméno a heslo, parametry SSL atd.:
(def redis-connection { :pool {} :spec { :host "127.0.0.1" :port 6379}})
A konečně můžeme začít komunikovat s Redisem. Použijeme přitom makro wcar (viz http://ptaoussanis.github.io/carmine/taoensso.carmine.html#var-wcar), kterému se předá jak informace o připojení, tak i příkaz, který se pošle na server. Zde se konkrétně jedná o příkaz PING. Makro wcar vrátí odpověď či odpovědi serveru, které vytiskneme:
(println (carmine/wcar redis-connection (carmine/ping)))
Úplný zdrojový kód dnešního prvního demonstračního příkladu vypadá následovně:
(ns carmine1.core (:require [taoensso.carmine :as carmine :refer (wcar)])) (def redis-connection { :pool {} :spec { :host "127.0.0.1" :port 6379}}) (defn -main [& args] (println "Pinging Redis") (println (carmine/wcar redis-connection (carmine/ping))) (println "Done"))
Spuštění příkladu (za předpokladu, že je Redis spuštěný):
$ lein run Pinging Redis PONG Done
6. Pomocné makro wcar* vytvořené pro každé připojení k Redisu
Neustálé předávaní mapy redis-connection do makra carmine/wcar pouze zbytečně prodlužuje zdrojový kód. Můžeme si však vypomoci – buď vytvořením uzávěru nebo deklarací nového makra, které tento parametr do carmine/wcar předá automaticky, a to nezávisle na počtu dalších parametrů. Toto makro, které je převzato z oficiální dokumentace, může vypadat následovně:
(defmacro wcar* [& body] `(carmine/wcar redis-connection ~@body))
Použití tohoto makra je jednoduché:
(println (wcar* (carmine/ping)))
Opět si ukažme úplný zdrojový kód dnešního druhého demonstračního příkladu:
(ns carmine2.core (:require [taoensso.carmine :as carmine :refer (wcar)])) (def redis-connection { :pool {} :spec { :host "127.0.0.1" :port 6379}}) (defmacro wcar* [& body] `(carmine/wcar redis-connection ~@body)) (defn -main [& args] (println "Pinging Redis") (println (wcar* (carmine/ping))) (println "Done"))
Po spuštění tohoto příkladu by se měly zobrazit stejné informace, jako v případě příkladu předchozího:
$ lein run Pinging Redis PONG Done
7. Alternativní způsob definice připojení k Redisu
Kromě specifikace adresy a portu, na kterém naslouchá Redis server, v samostatných atributech:
(def redis-connection { :pool {} :spec { :host "127.0.0.1" :port 6379}})
Je možné připojení určit i jediným řetězcem – URL:
(def redis-connection { :pool {} :spec { :uri "redis://localhost:6379"}})
Nebo se jménem:
(def redis-connection { :pool {} :spec { :uri "redis://localhost@127.0.0.1:6379"}})
Alternativně je možné v URL zadat i přihlašovací jméno a heslo:
(def redis-connection { :pool {} :spec { :uri "redis://jméno:heslo@127.0.0.1:6379"}})
Zbytek programu může zůstat stejný, jako tomu bylo v předchozích dvou demonstračních příkladech:
(ns carmine3.core (:require [taoensso.carmine :as carmine :refer (wcar)])) (def redis-connection { :pool {} :spec { :uri "redis://localhost@127.0.0.1:6379"}}) (defmacro wcar* [&am; body] `(carmine/wcar redis-connection ~@body)) (defn -main [& args] (println "Pinging Redis") (println (wcar* (carmine/ping))) (println "Done"))
Zprávy zobrazené po spuštění:
$ lein run Pinging Redis PONG Done
8. Podporované datové typy, s nimiž Redis pracuje
Při ukládání a zpracování dat ukládaných do Redisu je možné data reprezentovat několika datovými typy. Jména jednotlivých podporovaných typů jsou vypsána v tabulce pod tímto odstavcem a v navazujících kapitolách si řekneme o vybraných typech některé bližší informace (zaměřené spíše na jejich praktické použití, a to i s ohledem na jazyk Clojure):
Jméno | Stručná charakteristika |
---|---|
string | řetězce, které lze ovšem využít i pro práci s celými čísly i čísly s plovoucí řádovou čárkou |
list | seznamy, ve skutečnosti se s nimi pracuje jako se zásobníkem a frontou (podle zvolené sémantiky operací) |
set | množiny, je zaručena unikátnost prvků |
sorted set | množiny, v nichž jsou jednotlivé prvky ohodnoceny skórem |
hash | mapy (též asociativní pole) |
bitmap (bit array) | pole bitů, interně mapovány na řetězce |
HyperLogLogs (HLL) | datová struktura používaná pro zjištění počtu unikátních prvků (s určitou chybou, ovšem s malou spotřebou paměti) |
9. Práce s řetězci uloženými do databáze
Základním datovým typem, který se v Redisu používá, jsou řetězce. Ve skutečnosti se jedná o sekvenci bajtů známé délky, které nejsou žádným způsobem interpretovány. Díky tomu, že je délka řetězce uložena ve zvláštním atributu, nemusí Redis používat například znak s kódem 0 pro ukončení řetězce a tudíž se i tento znak může bez problému v řetězci vyskytovat. Maximální délka řetězce je v současné verzi Redisu 512 MB, což v praxi znamená, že se řetězce mohou použít například pro uložení dokumentů, strukturovaných dat reprezentovaných ve formátech JSON, XML, YAML atd. atd.
Mezi základní příkazy pro práci s řetězci patří nám již známé příkazu set a get. Ovšem řetězce lze i modifikovat příkazem append a můžeme získat délku řetězce pomocí strlen:
127.0.0.1:6379> set z "" OK 127.0.0.1:6379> append z "Hello" (integer) 5 127.0.0.1:6379> append z " " (integer) 6 127.0.0.1:6379> append z "world!" (integer) 12 127.0.0.1:6379> get z "Hello world!" 127.0.0.1:6379> strlen z (integer) 12
Tyto základní operace je pochopitelně možné realizovat i z Clojure, což si ukážeme v následující kapitole.
10. Uložení řetězce a zpětné přečtení řetězce realizované v Clojure
Obdobou příkazu set ukázaného v předchozí kapitole je funkce carmine/set, které se v tom nejjednodušším případě předává pouze klíč a hodnota:
(carmine/set "klíč" "hodnota")))
Tato funkce se však musí volat v rámci makra wcar, které příkaz pošle do Redisu a vrátí výsledky. A my makro wcar máme obalené ve vlastním makru wcar*, takže:
(wcar* (carmine/set "klíč" "hodnota")))
Podobným způsobem je možné přečíst řetězec uložený pod známým klíčem:
(wcar* (carmine/get "klíč")))
Obě operace lze dokonce provést v rámci jedné sekvence příkazů poslaných Redisu:
(wcar* (carmine/set "klíč" "hodnota"))) (carmine/get "klíč")))
V takovém případě se vrátí seznam výsledků pro jednotlivé vykonané příkazy.
Opět se podívejme na úplný tvar zdrojového kódu příkladu:
(ns carmine4.core (:require [taoensso.carmine :as carmine :refer (wcar)])) (def redis-connection { :pool {} :spec { :uri "redis://localhost@127.0.0.1:6379"}}) (defmacro wcar* [& body] `(carmine/wcar redis-connection ~@body)) (defn -main [& args] (println "Storing data") (println (wcar* (carmine/set "klíč" "hodnota"))) (println "Done") (println "Retrieving data") (println (wcar* (carmine/get "klíč"))) (println "Done"))
Pokusme se tento příklad spustit a získat výsledky:
$ lein run Storing data OK Done Retrieving data hodnota Done
11. Řetězce či čísla?
Zajímavé je, že i když Redis neobsahuje přímou podporu pro datový typ „celé číslo“, nabízí svým uživatelům několik operací určených pro atomickou změnu numerických hodnot reprezentovaných řetězcem v běžném dekadickém formátu. Pro zvýšení hodnoty o jedničku se používá operace INCR, opakem je pochopitelně funkce DECR. V případě, že budeme potřebovat zvýšit nebo snížit uloženou hodnotu o krok odlišný od jedničky, je možné pro tento účel použít operaci pojmenovanou příhodně INCRBY. Podívejme se na příklady (spouštěné přímo z redis-cli:
127.0.0.1:6379> set x 0 OK 127.0.0.1:6379> INCR x (integer) 1 127.0.0.1:6379> get x "1" 127.0.0.1:6379> INCRBY x 100 (integer) 101 127.0.0.1:6379> get x "101" 127.0.0.1:6379> DECR x (integer) 100 127.0.0.1:6379> get x "100"
Podobná operace nazvaná INCRBYFLOAT slouží pro změnu hodnoty čísla s desetinnou tečkou (opět ovšem uloženého formou běžného řetězce). Příklad na interpretaci řetězce jako čísla s plovoucí řádovou čárkou:
127.0.0.1:6379> set y 0.5 OK 127.0.0.1:6379> INCRBYFLOAT y 0.3 "0.8" 127.0.0.1:6379> get y "0.8"
Řetězec „0.8“ ovšem již není možné považovat za reprezentaci celého čísla:
127.0.0.1:6379> incr y (error) ERR value is not an integer or out of range
127.0.0.1:6379> type x string 127.0.0.1:6379> type y string 127.0.0.1:6379> type z string
12. Manipulace s číselnými hodnotami iniciovaná z Clojure
V knihovně Carmine nalezneme obdobu všech výše zmíněných příkazů:
Příkaz Redisu | Funkce/makro v Carmine |
---|---|
INCR | incr |
INCRBY | incrby |
DECR | decr |
DECRBY | decrby |
INCRBYFLOAT | incrbyfloat |
Jejich použití je snadné, jak je to ostatně patrné i z vypsaného zdrojového kódu:
(ns carmine5.core (:require [taoensso.carmine :as carmine :refer (wcar)])) (def redis-connection { :pool {} :spec { :uri "redis://localhost@127.0.0.1:6379"}}) (defmacro wcar* [& body] `(carmine/wcar redis-connection ~@body)) (defn -main [& args] (println "Storing integer value") (println (wcar* (carmine/set "counter" 1))) (println "Done") (println "Retrieving integer value") (println (wcar* (carmine/get "counter"))) (println "Done") (println "Increasing and retrieving new integer value") (println (wcar* (carmine/incr "counter") (carmine/get "counter"))) (println "Done"))
$ lein run Storing integer value OK Done Retrieving integer value 1 Done Increasing and retrieving new integer value [2 2] Done
13. Uložení strukturovaných dat do Redisu: síla kombinace Redis+Clojure
Programovací jazyk Clojure je skvělý v těch oblastech, v nichž je nutné manipulovat se strukturovanými daty. A tato data je mnohdy zapotřebí ukládat do databáze. Jak však postupovat ve chvíli, kdy pracujeme (například) se složitější mapou, která navíc obsahuje hodnoty různých typů (popř. dokonce strukturované klíče)? Tato mapa může vypadat například takto:
{ :boolean true :nil-value nil :text "Hello world!" :list '(1 2 3) :vector [1 2 3] :a-set #{1 2 3 4} :map {:name "foo" :surname "bar" } }
Povšimněte si, že mapa jako své prvky obsahuje hodnoty různých datových typů Clojure, a to i typů, s nimiž Redis nedokáže přímo pracovat. Ve skutečnosti je mapa (či hodnota jakéhokoli jiného datového typu) interně serializována takovým způsobem, aby ji bylo možné uložit jako řetězec. Pro serializaci (a pochopitelně i zpětnou deserializaci) se používá knihovna nippy, s níž se na Rootu setkáváme poprvé. Ovšem z hlediska programátora používajícího knihovnu Carmine je vše provedeno automaticky – serializací a deserializací se vůbec nemusí zabývat. To je ostatně patrné i při pohledu na další demonstrační příklad, který vlastně provádí naprosto stejnou operaci jako příklad ukládající a čtoucí řetězec:
(ns carmine6.core (:require [taoensso.carmine :as carmine :refer (wcar)] [clojure.pprint :as pprint])) (def redis-connection { :pool {} :spec { :uri "redis://localhost@127.0.0.1:6379"}}) (defmacro wcar* [& body] `(carmine/wcar redis-connection ~@body)) (def data { :boolean true :nil-value nil :text "Hello world!" :list '(1 2 3) :vector [1 2 3] :a-set #{1 2 3 4} :map {:name "foo" :surname "bar" }}) (defn -main [& args] (println "Storing data structure") (println (wcar* (carmine/set "value" data))) (println "Done") (println "Retrieving data structure") (pprint/pprint (wcar* (carmine/get "value"))) (println "Done"))
Příklad po svém spuštění skutečně mapu nejprve zapíše a poté ji přečte zpět:
$ lein run Storing data structure OK Done Retrieving data structure {:boolean true, :nil-value nil, :text "Hello world!", :list (1 2 3), :vector [1 2 3], :a-set #{1 4 3 2}, :map {:name "foo", :surname "bar"}} Done
Zajímavé bude zjistit, jak je vlastně tato datová struktura v Redisu uložena. Pro tento účel použijeme přímo redis-cli:
$ redis-cli 127.0.0.1:6379> get value "\x00>NPY\x00p\aj\aboolean\bj\tnil-value\x03j\x04texti\x0cHello world!j\x04list\x19p\x02j\x04line*\x00\x00\x00\x15j\x06column*\x00\x00\x00\x18$\x03d\x01d\x02d\x03j\x06vectorrd\x01d\x02d\x03j\x05a-seto\x04d\x01d\x04d\x03d\x02j\x03mapp\x02j\x04namei\x03fooj\asurnamei\x03bar"
Takto vypadají binární data serializovaná výše zmíněnou knihovnou nippy.
14. Seznamy
Dalším datovým typem, který se v Redisu velmi často používá, jsou seznamy (list). Tento název je ovšem poněkud nepřesný, protože seznamy je možné využít například i pro implementaci fronty (queue), zásobníku (stack), běžného pole (array) nebo dokonce obousměrné fronty (deque). Počet prvků zapisovaných do seznamu může dosahovat prakticky neomezené hodnoty, konkrétně lze do jediného seznamu uložit 232-1 prvků. Mezi základní operace pro práci se seznamy patří:
Příkaz | Význam |
---|---|
lpush | přidání prvku na začátek seznamu |
rpush | přidání prvku na konec seznamu |
lpop | přečtení prvního prvku ze seznamu s jeho odstraněním |
rpop | přečtení posledního prvku ze seznamu s jeho odstraněním |
lset | změna hodnoty prvku na určeném indexu v seznamu |
lindex | přečtení prvku se zadaným indexem |
linsert | přidání prvku na určený index seznamu (s posunem dalších prvků) |
llen | přečtení délky seznamu |
Podívejme se nyní na několik příkladů spouštěných z klienta redis-cli. Seznam uložený pod klíčem „l“ se automaticky vytvoří hned prvním příkazem:
127.0.0.1:6379> lpush l 3 (integer) 1 127.0.0.1:6379> lpush l 2 (integer) 2 127.0.0.1:6379> lpush l 1 (integer) 3 127.0.0.1:6379> llen l (integer) 3 127.0.0.1:6379> rpush l 1 (integer) 4 127.0.0.1:6379> rpush l 2 (integer) 5 127.0.0.1:6379> rpush l 3 (integer) 6 127.0.0.1:6379> llen l (integer) 6
Typ hodnoty uložené pod klíčem „l“:
127.0.0.1:6379> type l list
Seznam nelze přečíst operací get:
127.0.0.1:6379> get l (error) WRONGTYPE Operation against a key holding the wrong kind of value
Čtení prvků ze začátku i konce seznamu s jejich postupným odstraňováním:
127.0.0.1:6379> lpop l "1" 127.0.0.1:6379> lpop l "2" 127.0.0.1:6379> lpop l "3" 127.0.0.1:6379> lpop l "1" 127.0.0.1:6379> lpop l "2" 127.0.0.1:6379> lpop l "3"
Pokus o přečtení hodnoty z prázdného seznamu:
127.0.0.1:6379> lpop l (nil)
15. Manipulace se seznamy uloženými v Redisu z Clojure
Výše uvedené operace lpush, lop, llen atd. je pochopitelně možné využít i v programovacím jazyku Clojure, protože tyto operace jsou podporovány knihovnou Carmine:
Příkaz Redisu | Funkce/makro v Carmine |
---|---|
LPUSH | lpush |
RPUSH | rpush |
LPOP | lpop |
RPOP | rpop |
LSET | lset |
LINDEX | lindex |
LINSERT | linsert |
LLEN | llen |
Některé příkazy z předchozí tabulky budou otestovány v dnes již posledním demonstračním příkladu. Povšimněte si, že všechny příkazy jsou volány v rámci makra wcar* a tudíž budou do Redisu poslány v jediném bloku. Návratové hodnoty budou získány taktéž v jediném bloku, zpracovány a vráceny formou seznamu:
(ns carmine7.core (:require [taoensso.carmine :as carmine :refer (wcar)])) (def redis-connection { :pool {} :spec { :uri "redis://localhost@127.0.0.1:6379"}}) (defmacro wcar* [& body] `(carmine/wcar redis-connection ~@body)) (defn -main [& args] (println "Working with list") (println (wcar* (carmine/llen "a-list") (carmine/lpush "a-list" "first") (carmine/llen "a-list") (carmine/lpush "a-list" "second") (carmine/llen "a-list") (carmine/lpop "a-list") (carmine/llen "a-list") (carmine/lpop "a-list") (carmine/llen "a-list") (carmine/lpop "a-list") (carmine/llen "a-list"))) (println "Done"))
Po spuštění tohoto příkladu dostaneme jako výsledek seznam s jedenácti hodnotami:
Working with list [0 1 1 2 2 second 1 first 0 nil 0] Done
Tyto hodnoty postupně odpovídají volaným příkazům, takže si je můžeme snadno rozkódovat:
Příkaz | Hodnota vrácená tímto příkazem | Poznámka |
---|---|---|
(carmine/llen „a-list“) | 0 | seznam je na začátku prázdný |
(carmine/lpush „a-list“ „first“) | 1 | vložení prvního prvku, vrací se délka seznamu po vložení |
(carmine/llen „a-list“) | 1 | počet prvků v seznamu je nyní roven jedné |
(carmine/lpush „a-list“ „second“) | 2 | vložení druhého prvku, vrací se délka seznamu po vložení |
(carmine/llen „a-list“) | 2 | počet prvků v seznamu je nyní roven dvěma |
(carmine/lpop „a-list“) | second | přečtení hodnoty posledního prvku s jeho odstraněním ze seznamu |
(carmine/llen „a-list“) | 1 | počet prvků v seznamu je nyní roven jedné |
(carmine/lpop „a-list“) | first | přečtení hodnoty posledního prvku s jeho odstraněním ze seznamu |
(carmine/llen „a-list“) | 0 | seznam je nyní prázdný |
(carmine/lpop „a-list“) | nil | seznam je prázdný → nevrátila se žádná hodnota |
(carmine/llen „a-list“) | 0 | seznam je stále prázdný |
16. Kam dál?
Redis se nepoužívá pouze ve funkci velmi rychlé databáze, ale velmi často se setkáme s tím, že je ústřední součástí message brokeru popř. je přímo použit pro realizaci fronty zpráv nebo pro streaming. A právě s tímto konceptem se seznámíme v navazující části tohoto článku.
17. Repositář s demonstračními příklady
Všechny výše popsané demonstrační příklady byly uloženy do repositáře dostupného na adrese https://github.com/tisnik/clojure-examples/. V tabulce umístěné pod tímto odstavcem jsou uvedeny odkazy na tyto příklady (vždy se přitom jedná o plnohodnotný projekt vyžadující jak Clojure, tak i Leiningen):
# | Projekt | Popis projektu | Cesta |
---|---|---|---|
1 | carmine1 | připojení k Redisu, poslání zprávy PING a obdržení zprávy PONG | https://github.com/tisnik/clojure-examples/tree/master/carmine1 |
2 | carmine2 | pomocné makro wcar* vytvořené pro každé připojení k Redisu | https://github.com/tisnik/clojure-examples/tree/master/carmine2 |
3 | carmine3 | alternativní způsob definice připojení k Redisu | https://github.com/tisnik/clojure-examples/tree/master/carmine3 |
4 | carmine4 | uložení řetězce a zpětné přečtení řetězce realizované v Clojure | https://github.com/tisnik/clojure-examples/tree/master/carmine4 |
5 | carmine5 | využití příkazu incr | https://github.com/tisnik/clojure-examples/tree/master/carmine5 |
6 | carmine6 | uložení strukturovaných dat do Redisu | https://github.com/tisnik/clojure-examples/tree/master/carmine6 |
7 | carmine7 | manipulace se seznamy uloženými v Redisu | https://github.com/tisnik/clojure-examples/tree/master/carmine7 |
18. Předchozí články o systému Redis
Se systémem Redis jsme se již na stránkách Rootu setkali, a to dokonce několikrát. Buď jsme si popisovali přímo přístup k Redisu z různých programovacích jazyků (což je konkrétně případ všech dále zmíněných článků zaměřených na jazyky Python a Go) nebo byl Redis použit ve funkci databáze resp. perzistentního úložiště různými message brokery (Celery, RQ, apod.). Poslední dva články pak popisují problematiku proudů v systému Redis:
- Databáze Redis (nejenom) pro vývojáře používající Python
https://www.root.cz/clanky/databaze-redis-nejenom-pro-vyvojare-pouzivajici-python/ - Databáze Redis (nejenom) pro vývojáře používající Python (dokončení)
https://www.root.cz/clanky/databaze-redis-nejenom-pro-vyvojare-pouzivajici-python-dokonceni/ - Použití databáze Redis v aplikacích naprogramovaných v Go
https://www.root.cz/clanky/pouziti-databaze-redis-v-aplikacich-naprogramovanych-v-go/ - Použití databáze Redis v aplikacích naprogramovaných v Go (2)
https://www.root.cz/clanky/pouziti-databaze-redis-v-aplikacich-naprogramovanych-v-go-2/ - Použití nástroje RQ (Redis Queue) pro správu úloh zpracovávaných na pozadí
https://www.root.cz/clanky/pouziti-nastroje-rq-redis-queue-pro-spravu-uloh-zpracovavanych-na-pozadi/ - Proudy (streams) podporované systémem Redis
https://www.root.cz/clanky/proudy-streams-podporovane-systemem-redis/ - Proudy (streams) podporované systémem Redis (dokončení)
https://www.root.cz/clanky/proudy-streams-podporovane-systemem-redis-dokonceni/
19. Odkazy na předchozí části seriálu o programovacím jazyku Clojure
- Clojure 1: Úvod
http://www.root.cz/clanky/clojure-aneb-jazyk-umoznujici-tvorbu-bezpecnych-vicevlaknovych-aplikaci-pro-jvm/ - Clojure 2: Symboly, kolekce atd.
http://www.root.cz/clanky/clojure-aneb-jazyk-umoznujici-tvorbu-bezpecnych-vicevlaknovych-aplikaci-pro-jvm-2-cast/ - Clojure 3: Funkcionální programování
http://www.root.cz/clanky/clojure-aneb-jazyk-umoznujici-tvorbu-bezpecnych-vicevlaknovych-aplikaci-pro-jvm-3-cast-funkcionalni-programovani/ - Clojure 4: Kolekce, sekvence a lazy sekvence
http://www.root.cz/clanky/clojure-aneb-jazyk-umoznujici-tvorbu-bezpecnych-vicevlaknovych-aplikaci-pro-jvm-4-cast-kolekce-sekvence-a-lazy-sekvence/ - Clojure 5: Sekvence, lazy sekvence a paralelní programy
http://www.root.cz/clanky/clojure-a-bezpecne-aplikace-pro-jvm-sekvence-lazy-sekvence-a-paralelni-programy/ - Clojure 6: Podpora pro paralelní programování
http://www.root.cz/clanky/programovaci-jazyk-clojure-6-futures-nejsou-jen-financni-derivaty/ - Clojure 7: Další funkce pro paralelní programování
http://www.root.cz/clanky/programovaci-jazyk-clojure-7-dalsi-podpurne-prostredky-pro-paralelni-programovani/ - Clojure 8: Identity, stavy, neměnné hodnoty a reference
http://www.root.cz/clanky/programovaci-jazyk-clojure-8-identity-stavy-nemenne-hodnoty-a-referencni-typy/ - Clojure 9: Validátory, pozorovatelé a kooperace s Javou
http://www.root.cz/clanky/programovaci-jazyk-clojure-9-validatory-pozorovatele-a-kooperace-mezi-clojure-a-javou/ - Clojure 10: Kooperace mezi Clojure a Javou
http://www.root.cz/clanky/programovaci-jazyk-clojure-10-kooperace-mezi-clojure-a-javou-pokracovani/ - Clojure 11: Generátorová notace seznamu/list comprehension
http://www.root.cz/clanky/programovaci-jazyk-clojure-11-generatorova-notace-seznamu-list-comprehension/ - Clojure 12: Překlad programů z Clojure do bajtkódu JVM I:
http://www.root.cz/clanky/programovaci-jazyk-clojure-12-preklad-programu-z-clojure-do-bajtkodu-jvm/ - Clojure 13: Překlad programů z Clojure do bajtkódu JVM II:
http://www.root.cz/clanky/programovaci-jazyk-clojure-13-preklad-programu-z-clojure-do-bajtkodu-jvm-pokracovani/ - Clojure 14: Základy práce se systémem maker
http://www.root.cz/clanky/programovaci-jazyk-clojure-14-zaklady-prace-se-systemem-maker/ - Clojure 15: Tvorba uživatelských maker
http://www.root.cz/clanky/programovaci-jazyk-clojure-15-tvorba-uzivatelskych-maker/ - Programovací jazyk Clojure – triky při práci s řetězci
http://www.root.cz/clanky/programovaci-jazyk-clojure-triky-pri-praci-s-retezci/ - Programovací jazyk Clojure – triky při práci s kolekcemi
http://www.root.cz/clanky/programovaci-jazyk-clojure-triky-pri-praci-s-kolekcemi/ - Programovací jazyk Clojure – práce s mapami a množinami
http://www.root.cz/clanky/programovaci-jazyk-clojure-prace-s-mapami-a-mnozinami/ - Programovací jazyk Clojure – základy zpracování XML
http://www.root.cz/clanky/programovaci-jazyk-clojure-zaklady-zpracovani-xml/ - Programovací jazyk Clojure – testování s využitím knihovny Expectations
http://www.root.cz/clanky/programovaci-jazyk-clojure-testovani-s-vyuzitim-knihovny-expectations/ - Programovací jazyk Clojure – některé užitečné triky použitelné (nejenom) v testech
http://www.root.cz/clanky/programovaci-jazyk-clojure-nektere-uzitecne-triky-pouzitelne-nejenom-v-testech/ - Enlive – výkonný šablonovací systém pro jazyk Clojure
http://www.root.cz/clanky/enlive-vykonny-sablonovaci-system-pro-jazyk-clojure/ - Nástroj Leiningen a programovací jazyk Clojure: tvorba vlastních knihoven pro veřejný repositář Clojars
http://www.root.cz/clanky/nastroj-leiningen-a-programovaci-jazyk-clojure-tvorba-vlastnich-knihoven-pro-verejny-repositar-clojars/ - Novinky v Clojure verze 1.8.0
http://www.root.cz/clanky/novinky-v-clojure-verze-1–8–0/ - Asynchronní programování v Clojure s využitím knihovny core.async
http://www.root.cz/clanky/asynchronni-programovani-v-clojure-s-vyuzitim-knihovny-core-async/ - Asynchronní programování v Clojure s využitím knihovny core.async (pokračování)
http://www.root.cz/clanky/asynchronni-programovani-v-clojure-s-vyuzitim-knihovny-core-async-pokracovani/ - Asynchronní programování v Clojure s využitím knihovny core.async (dokončení)
http://www.root.cz/clanky/asynchronni-programovani-v-clojure-s-vyuzitim-knihovny-core-async-dokonceni/ - Vytváříme IRC bota v programovacím jazyce Clojure
http://www.root.cz/clanky/vytvarime-irc-bota-v-programovacim-jazyce-clojure/ - Gorilla REPL: interaktivní prostředí pro programovací jazyk Clojure
https://www.root.cz/clanky/gorilla-repl-interaktivni-prostredi-pro-programovaci-jazyk-clojure/ - Multimetody v Clojure aneb polymorfismus bez použití OOP
https://www.root.cz/clanky/multimetody-v-clojure-aneb-polymorfismus-bez-pouziti-oop/ - Práce s externími Java archivy v programovacím jazyku Clojure
https://www.root.cz/clanky/prace-s-externimi-java-archivy-v-programovacim-jazyku-clojure/ - Clojure 16: Složitější uživatelská makra
http://www.root.cz/clanky/programovaci-jazyk-clojure-16-slozitejsi-uzivatelska-makra/ - Clojure 17: Využití standardních maker v praxi
http://www.root.cz/clanky/programovaci-jazyk-clojure-17-vyuziti-standardnich-maker-v-praxi/ - Clojure 18: Základní techniky optimalizace aplikací
http://www.root.cz/clanky/programovaci-jazyk-clojure-18-zakladni-techniky-optimalizace-aplikaci/ - Clojure 19: Vývojová prostředí pro Clojure
http://www.root.cz/clanky/programovaci-jazyk-clojure-19-vyvojova-prostredi-pro-clojure/ - Clojure 20: Vývojová prostředí pro Clojure (Vim s REPL)
http://www.root.cz/clanky/programovaci-jazyk-clojure-20-vyvojova-prostredi-pro-clojure-integrace-vimu-s-repl/ - Clojure 21: ClojureScript aneb překlad Clojure do JS
http://www.root.cz/clanky/programovaci-jazyk-clojure-21-clojurescript-aneb-preklad-clojure-do-javascriptu/ - Leiningen: nástroj pro správu projektů napsaných v Clojure
http://www.root.cz/clanky/leiningen-nastroj-pro-spravu-projektu-napsanych-v-clojure/ - Leiningen: nástroj pro správu projektů napsaných v Clojure (2)
http://www.root.cz/clanky/leiningen-nastroj-pro-spravu-projektu-napsanych-v-clojure-2/ - Leiningen: nástroj pro správu projektů napsaných v Clojure (3)
http://www.root.cz/clanky/leiningen-nastroj-pro-spravu-projektu-napsanych-v-clojure-3/ - Leiningen: nástroj pro správu projektů napsaných v Clojure (4)
http://www.root.cz/clanky/leiningen-nastroj-pro-spravu-projektu-napsanych-v-clojure-4/ - Leiningen: nástroj pro správu projektů napsaných v Clojure (5)
http://www.root.cz/clanky/leiningen-nastroj-pro-spravu-projektu-napsanych-v-clojure-5/ - Leiningen: nástroj pro správu projektů napsaných v Clojure (6)
http://www.root.cz/clanky/leiningen-nastroj-pro-spravu-projektu-napsanych-v-clojure-6/ - Programovací jazyk Clojure a databáze (1.část)
http://www.root.cz/clanky/programovaci-jazyk-clojure-a-databaze-1-cast/ - Pluginy pro Leiningen
http://www.root.cz/clanky/leiningen-nastroj-pro-spravu-projektu-napsanych-v-clojure-pluginy-pro-leiningen/ - Programovací jazyk Clojure a knihovny pro práci s vektory a maticemi
http://www.root.cz/clanky/programovaci-jazyk-clojure-a-knihovny-pro-praci-s-vektory-a-maticemi/ - Programovací jazyk Clojure a knihovny pro práci s vektory a maticemi (2)
http://www.root.cz/clanky/programovaci-jazyk-clojure-a-knihovny-pro-praci-s-vektory-a-maticemi-2/ - Programovací jazyk Clojure: syntéza procedurálních textur s využitím knihovny Clisk
http://www.root.cz/clanky/programovaci-jazyk-clojure-synteza-proceduralnich-textur-s-vyuzitim-knihovny-clisk/ - Programovací jazyk Clojure: syntéza procedurálních textur s využitím knihovny Clisk (2)
http://www.root.cz/clanky/programovaci-jazyk-clojure-synteza-proceduralnich-textur-s-vyuzitim-knihovny-clisk-2/ - Seesaw: knihovna pro snadnou tvorbu GUI v jazyce Clojure
http://www.root.cz/clanky/seesaw-knihovna-pro-snadnou-tvorbu-gui-v-jazyce-clojure/ - Seesaw: knihovna pro snadnou tvorbu GUI v azyce Clojure (2)
http://www.root.cz/clanky/seesaw-knihovna-pro-snadnou-tvorbu-gui-v-jazyce-clojure-2/ - Seesaw: knihovna pro snadnou tvorbu GUI v jazyce Clojure (3)
http://www.root.cz/clanky/seesaw-knihovna-pro-snadnou-tvorbu-gui-v-jazyce-clojure-3/ - Programovací jazyk Clojure a práce s Gitem
http://www.root.cz/clanky/programovaci-jazyk-clojure-a-prace-s-gitem/ - Programovací jazyk Clojure a práce s Gitem (2)
http://www.root.cz/clanky/programovaci-jazyk-clojure-a-prace-s-gitem-2/ - Programovací jazyk Clojure: syntéza procedurálních textur s využitím knihovny Clisk (dokončení)
http://www.root.cz/clanky/programovaci-jazyk-clojure-synteza-proceduralnich-textur-s-vyuzitim-knihovny-clisk-dokonceni/ - Pixie: lehký skriptovací jazyk s „kouzelnými“ schopnostmi
https://www.root.cz/clanky/pixie-lehky-skriptovaci-jazyk-s-kouzelnymi-schopnostmi/ - Programovací jazyk Pixie: funkce ze základní knihovny a použití FFI
https://www.root.cz/clanky/programovaci-jazyk-pixie-funkce-ze-zakladni-knihovny-a-pouziti-ffi/ - Novinky v Clojure verze 1.9.0
https://www.root.cz/clanky/novinky-v-clojure-verze-1–9–0/ - Validace dat s využitím knihovny spec v Clojure 1.9.0
https://www.root.cz/clanky/validace-dat-s-vyuzitim-knihovny-spec-v-clojure-1–9–0/ - Použití jazyka Gherkin při tvorbě testovacích scénářů pro aplikace psané v Clojure
https://www.root.cz/clanky/pouziti-jazyka-gherkin-pri-tvorbe-testovacich-scenaru-pro-aplikace-psane-v-nbsp-clojure/ - Použití jazyka Gherkin při tvorbě testovacích scénářů pro aplikace psané v Clojure (2)
https://www.root.cz/clanky/pouziti-jazyka-gherkin-pri-tvorbe-testovacich-scenaru-pro-aplikace-psane-v-nbsp-clojure-2/ - Incanter: prostředí pro statistické výpočty s grafickým výstupem založené na Clojure
https://www.root.cz/clanky/incanter-prostredi-pro-statisticke-vypocty-s-grafickym-vystupem-zalozene-na-clojure/ - Incanter: operace s maticemi
https://www.root.cz/clanky/incanter-operace-s-maticemi/ - Interpret programovacího jazyka Clojure integrovaný do Jupyter Notebooku
https://www.root.cz/clanky/interpret-programovaciho-jazyka-clojure-integrovany-do-jupyter-notebooku/ - Babashka: interpret Clojure určený pro rychlé spouštění utilit z příkazového řádku
https://www.root.cz/clanky/babashka-interpret-clojure-urceny-pro-rychle-spousteni-utilit-z-prikazoveho-radku/ - Pokročilý streaming založený na Apache Kafce, jazyku Clojure a knihovně Jackdaw
https://www.root.cz/clanky/pokrocily-streaming-zalozeny-na-apache-kafce-jazyku-clojure-a-knihovne-jackdaw/ - Pokročilý streaming založený na Apache Kafce, jazyku Clojure a knihovně Jackdaw (2. část)
https://www.root.cz/clanky/pokrocily-streaming-zalozeny-na-apache-kafce-jazyku-clojure-a-knihovne-jackdaw-2-cast/ - Pokročilý streaming založený na projektu Apache Kafka, jazyku Clojure a knihovně Jackdaw (streamy a kolony)
https://www.root.cz/clanky/pokrocily-streaming-zalozeny-na-projektu-apache-kafka-jazyku-clojure-a-knihovne-jackdaw-streamy-a-kolony/ - Řídicí struktury využitelné v programovacím jazyku Clojure
https://www.root.cz/clanky/ridici-struktury-vyuzitelne-v-programovacim-jazyku-clojure/ - Řídicí struktury využitelné v programovacím jazyku Clojure (dokončení)
https://www.root.cz/clanky/ridici-struktury-vyuzitelne-v-programovacim-jazyku-clojure-dokonceni/ - Formát EDN: extensible data notation
https://www.root.cz/clanky/format-edn-extensible-data-notation/ - Formát EDN: extensible data notation (dokončení)
https://www.root.cz/clanky/format-edn-extensible-data-notation-dokonceni/ - Čtyři různé podoby datové struktury map v programovacím jazyku Clojure
https://www.root.cz/clanky/ctyri-ruzne-podoby-datove-struktury-map-v-programovacim-jazyku-clojure/ - Programová tvorba diagramů v jazyku Clojure s využitím knihovny Rhizome
https://www.root.cz/clanky/programova-tvorba-diagramu-v-jazyku-clojure-s-vyuzitim-knihovny-rhizome/
20. Odkazy na Internetu
- Carmine: a pure-Clojure Redis client & message queue
https://github.com/ptaoussanis/carmine - Redis streams and Clojure
https://tirkarthi.github.io/programming/2018/08/17/redis-streams-clojure.html - Clojure Redis using Carmine
https://clojure.tgenedavis.com/clojure-redis-using-carmine/ - Clojure with a Touch of Redis
https://clojure.tgenedavis.com/2020–07–04/clojure-with-a-touch-of-redis/ - Clojure Redis: Get and Set
https://clojure.tgenedavis.com/2020–07–07/clojure-redis-get-and-set/ - Clojure Redis Pub/Sub with Carmine
https://clojure.tgenedavis.com/2020–10–17/clojure-redis-pub-sub-with-carmine/ - Redis and Clojure (založeno na odlišné knihovně)
https://devender.me/2010/06/13/redis-and-clojure/ - Disque, an in-memory, distributed job queue
https://github.com/antirez/disque - Scripting Redis with Lua
https://redislabs.com/ebook/part-3-next-steps/chapter-11-scripting-redis-with-lua/ - Redis Lua script for atomic operations and cache stampede
https://engineering.linecorp.com/en/blog/redis-lua-scripting-atomic-processing-cache/ - Příkaz pro spuštění skriptu v jazyce Lua: EVAL script numkeys key [key …] arg [arg …]
https://redis.io/commands/eval - Redis Lua scripts debugger
https://redis.io/topics/ldb - Repositář projektu s Redis klientem pro jazyk Go
https://github.com/go-redis/redis - Stránky programovacího jazyka Lua
https://www.lua.org/ - Programovací jazyk Lua
https://www.palmknihy.cz/ucebnice-odborna-literatura/programovaci-jazyk-lua-12651 - Programming in Lua
https://www.lua.org/pil/ - Redis Lua Scripts – Itamar Haber
https://www.youtube.com/watch?v=eReTl8NhHCs - Building Databases with Redis Tutorial: Lua Script | packtpub.com
https://www.youtube.com/watch?v=mMfGNsAr7Bg - Repositář projektu redis-luajit (fork)
https://github.com/coleifer/redis-luajit - Type-safe Redis client for Go
https://redis.uptrace.dev/ - Dokumentace k balíčku redis
https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc - godis – redis client implement by golang, inspired by jedis.
https://github.com/piaohao/godis - How to Use Redis Go Client go-redis/redis with GoLang
https://kb.objectrocket.com/redis/how-to-use-redis-go-client-go-redis-redis-with-golang-592 - Adventures in message queues
http://antirez.com/news/88 - redeo
https://github.com/bsm/redeo - First-in, first-out queues
https://redislabs.com/ebook/part-2-core-concepts/chapter-6-application-components-in-redis/6–4-task-queues/6–4–1-first-in-first-out-queues/ - Stránky projektu Redis
https://redis.io/ - Introduction to Redis
https://redis.io/topics/introduction - Try Redis
http://try.redis.io/ - Redis tutorial, April 2010 (starší, ale pěkně udělaný)
https://static.simonwillison.net/static/2010/redis-tutorial/ - Redis: key-value databáze v paměti i na disku
https://www.zdrojak.cz/clanky/redis-key-value-databaze-v-pameti-i-na-disku/ - Praktický úvod do Redis (1): vaše distribuovaná NoSQL cache
http://www.cloudsvet.cz/?p=253 - Praktický úvod do Redis (2): transakce
http://www.cloudsvet.cz/?p=256 - Praktický úvod do Redis (3): cluster
http://www.cloudsvet.cz/?p=258