Úvod do Jedisu - knižnica klientov Java Redis

1. Prehľad

Tento článok je úvod do Jedisu, klientská knižnica v Jave pre Redis - populárne úložisko dátových štruktúr v pamäti, ktoré môže pretrvávať aj na disku. Je poháňaný dátovou štruktúrou založenou na úložisku kľúčov na uchovanie údajov a možno ho použiť ako databázu, medzipamäť, sprostredkovateľa správ atď.

Najskôr vysvetlíme, v akých situáciách je Jedis užitočný a o čo ide.

V nasledujúcich častiach sa venujeme rôznym dátovým štruktúram a vysvetľujeme transakcie, pipeline a funkciu publikovania / prihlásenia na odber. Na záver sme zhrnuli združovanie pripojení a klaster Redis.

2. Prečo Jedis?

Redis uvádza zoznam najznámejších knižníc klientov na ich oficiálnych stránkach. Existuje niekoľko alternatív k Jedisom, ale iba dve ďalšie sú v súčasnosti hodné odporúčania hviezdy, šalátu a Redissona.

Títo dvaja klienti majú niektoré jedinečné funkcie, ako je bezpečnosť vlákien, transparentné spracovanie opätovného pripojenia a asynchrónne API, ktoré všetky funkcie Jedisu chýbajú.

Je však malý a podstatne rýchlejší ako ostatné dva. Okrem toho je to klientská knižnica, ktorú si vybrali vývojári Spring Framework, a má najväčšiu komunitu zo všetkých troch.

3. Závislosti Maven

Začnime vyhlásením jedinej závislosti, ktorú budeme v pom.xml:

 redis.clients jedis 2.8.1 

Ak hľadáte najnovšiu verziu knižnice, pozrite sa na túto stránku.

4. Znova inštalujte

Budete si musieť nainštalovať a spustiť jednu z najnovších verzií Redis. Momentálne používame najnovšiu stabilnú verziu (3.2.1), ale akákoľvek verzia 3.x by mala byť v poriadku.

Nájdete tu viac informácií o Redis pre Linux a Macintosh, majú veľmi podobné základné kroky inštalácie. Windows nie sú oficiálne podporované, ale tento port je dobre udržiavaný.

Potom sa môžeme priamo ponoriť a pripojiť sa k nej z nášho kódu Java:

Jedis jedis = nový Jedis ();

Predvolený konštruktor bude fungovať dobre, pokiaľ ste službu nespustili na inom ako predvolenom porte alebo na vzdialenom počítači. V takom prípade ho môžete nakonfigurovať správne tak, že do konštruktora zadáte správne hodnoty ako parametre.

5. Redis dátové štruktúry

Väčšina natívnych operačných príkazov je podporovaná a pohodlne zvyčajne zdieľajú rovnaký názov metódy.

5.1. Struny

Reťazce sú najzákladnejším druhom hodnoty Redis, užitočné napríklad v prípade, že potrebujete zachovať jednoduché dátové typy kľúč - hodnota:

jedis.set ("udalosti / mesto / rim", "32,15,223,828"); String cachedResponse = jedis.get ("events / city / rome");

Premenná cachedResponse udrží hodnotu 32,15,223,828. Spolu s podporou vypršania platnosti, o ktorej bude reč neskôr, môže fungovať ako bleskurýchla a ľahko použiteľná vrstva vyrovnávacej pamäte pre požiadavky HTTP prijaté z vašej webovej aplikácie a ďalšie požiadavky na ukladanie do pamäte cache.

5.2. Zoznamy

Zoznamy Redis sú jednoducho zoznamy reťazcov zoradené podľa poradia vloženia a robia z nich ideálny nástroj na implementáciu napríklad front správ:

jedis.lpush ("queue # tasks", "firstTask"); jedis.lpush ("queue # tasks", "secondTask"); String task = jedis.rpop ("front # úloh");

Premenná úloha udrží hodnotu firstTask. Pamätajte, že môžete serializovať akýkoľvek objekt a zachovať ho ako reťazec, takže správy vo fronte môžu v prípade potreby obsahovať zložitejšie údaje.

5.3. Sady

Sady Redis sú neusporiadanou kolekciou reťazcov, ktoré sa hodia, keď chcete vylúčiť opakovaných členov:

jedis.sadd ("prezývky", "prezývka # 1"); jedis.sadd ("prezývky", "prezývka # 2"); jedis.sadd ("prezývky", "prezývka # 1"); Nastaviť prezývky = jedis.smembers ("prezývky"); boolean existuje = jedis.sismember ("prezývky", "prezývka # 1");

Sada Java prezývky bude mať veľkosť 2, druhý prírastok prezývka # 1 bol ignorovaný. Tiež existuje premenná bude mať hodnotu pravda, metóda sismember umožňuje rýchlo skontrolovať existenciu konkrétneho člena.

5.4. Hashes

Redis Hashes mapujú medzi String polia a String hodnoty:

jedis.hset ("užívateľ # 1", "meno", "Peter"); jedis.hset ("užívateľ č. 1", "práca", "politik"); Názov reťazca = jedis.hget ("užívateľ # 1", "meno"); Mapové polia = jedis.hgetAll ("užívateľ č. 1"); Reťazec job = fields.get ("job");

Ako vidíte, hashy sú veľmi pohodlným údajovým typom, ak chcete pristupovať k vlastnostiam objektu individuálne, pretože nemusíte načítať celý objekt.

5.5. Zoradené sady

Zoradené množiny sú ako množina, v ktorej má každý člen priradené hodnotenie, ktoré sa používa na ich triedenie:

Skóre mapy = nová HashMap (); score.put („PlayerOne“, 3000,0); score.put („PlayerTwo“, 1500,0); score.put („PlayerThree“, 8200,0); score.entrySet (). forEach (playerScore -> {jedis.zadd (key, playerScore.getValue (), playerScore.getKey ());}); Reťazec player = jedis.zrevrange ("hodnotenie", 0, 1) .iterator (). Next (); long rank = jedis.zrevrank ("hodnotenie", "PlayerOne");

Premenná prehrávač udrží hodnotu HráčTri pretože získavame najlepšieho 1 hráča a je to ten, ktorý má najvyššie skóre. The hodnosť premenná bude mať hodnotu 1, pretože PlayerOne je druhý v poradí a poradie je založené na nule.

6. Transakcie

Transakcie zaručujú operácie atomicity a bezpečnosti vlákien, čo znamená, že počas transakcií Redis nebudú nikdy súčasne spracovávané požiadavky od iných klientov:

String friendsPrefix = "friends #"; Reťazec userOneId = "4352523"; Reťazec userTwoId = "5552321"; Transakcia t = jedis.multi (); t.sadd (friendsPrefix + userOneId, userTwoId); t.sadd (friendsPrefix + userTwoId, userOneId); t.exec ();

Úspešnosť transakcie môžete dokonca závisieť od konkrétneho kľúča tak, že ho budete „sledovať“ tesne pred vytvorením inštancie Transakcia:

jedis.watch ("friends # deleted #" + userOneId);

Ak sa hodnota tohto kľúča zmení pred vykonaním transakcie, transakcia nebude dokončená úspešne.

7. Pipelineovanie

Keď musíme poslať viac príkazov, môžeme ich zbaliť do jednej žiadosti a ušetriť réžiu spojenia pomocou plynovodov, ide v podstate o optimalizáciu siete. Pokiaľ sú operácie vzájomne nezávislé, môžeme túto techniku ​​využiť:

Reťazec userOneId = "4352523"; Reťazec userTwoId = "4849888"; Potrubie p = jedis.pipelined (); p.sadd ("hľadané #" + userOneId, "paris"); p.zadd ("hodnotenie", 126, userOneId); p.zadd ("hodnotenie", 325, userTwoId); Odpoveď pipeExists = p.sismember ("searched #" + userOneId, "paris"); Odozva pipeRanking = p.zrange ("hodnotenie", 0, -1); p.sync (); Reťazec existuje = pipeExists.get (); Nastaviť hodnotenie = pipeRanking.get ();

Všimnite si, že nedostávame priamy prístup k odpovediam na príkazy, namiesto toho dostaneme a Odozva inštancia, z ktorej môžeme po synchronizácii plynovodu požadovať základnú odpoveď.

8. Publikovať / Prihlásiť sa na odber

Funkciu sprostredkovateľa správ Redis môžeme použiť na odosielanie správ medzi rôznymi komponentmi nášho systému. Skontrolujte, či vlákna odberateľa a vydavateľa nezdieľajú rovnaké pripojenie Jedis.

8.1. Predplatiteľ

Prihláste sa na odber a počúvajte správy odoslané na kanál:

Jedis jSubscriber = nový Jedis (); jSubscriber.subscribe (new JedisPubSub () {@Override public void onMessage (String channel, String message) {// handle message}}, "channel");

Prihlásiť sa na odber je metóda blokovania, budete sa musieť odhlásiť z JedisPub výslovne. Prekonali sme onMessage existuje oveľa viac užitočných metód na prepísanie.

8.2. Vydavateľ

Potom jednoducho pošlite správy na ten istý kanál z vlákna vydavateľa:

Jedis jPublisher = nový Jedis (); jPublisher.publish ("kanál", "testovacia správa");

9. Združovanie pripojení

Je dôležité vedieť, že spôsob, akým sa zaoberáme našou inštanciou Jedis, je naivný. V scenári reálneho sveta nechcete používať jednu inštanciu v prostredí s viacerými vláknami, pretože jedna inštancia nie je bezpečná pre vlákna.

Našťastie môžeme ľahko vytvoriť skupinu pripojení k Redis, aby sme ju mohli na požiadanie znova použiť, fond, ktorý je bezpečný pre vlákna a spoľahlivý, pokiaľ zdroj do fondu vrátite, keď s ním skončíte.

Vytvorme JedisBool:

final JedisPoolConfig poolConfig = buildPoolConfig (); JedisPool jedisPool = nový JedisPool (poolConfig, "localhost"); private JedisPoolConfig buildPoolConfig () {final JedisPoolConfig poolConfig = new JedisPoolConfig (); poolConfig.setMaxTotal (128); poolConfig.setMaxIdle (128); poolConfig.setMinIdle (16); poolConfig.setTestOnBorrow (true); poolConfig.setTestOnReturn (true); poolConfig.setTestWhileIdle (true); poolConfig.setMinEvictableIdleTimeMillis (Duration.ofSeconds (60) .toMillis ()); poolConfig.setTimeB BetweenEvictionRunsMillis (Duration.ofSeconds (30) .toMillis ()); poolConfig.setNumTestsPerEvictionRun (3); poolConfig.setBlockWhenExhausted (true); return poolConfig; }

Pretože inštancia fondu je bezpečná pre vlákna, môžete ju niekde staticky uložiť, mali by ste sa však postarať o zničenie fondu, aby ste predišli únikom údajov pri vypínaní aplikácie.

Teraz môžeme v prípade potreby využiť náš fond odkiaľkoľvek v aplikácii:

try (Jedis jedis = jedisPool.getResource ()) {// robiť operácie so zdrojom jedis}

Použili sme príkaz Java try-with-resources, aby sme nemuseli manuálne zatvárať prostriedok Jedis, ale ak nemôžete tento príkaz použiť, môžete prostriedok zavrieť aj manuálne v konečne doložka.

Ak nechcete čeliť nepríjemným problémom s viacerými vláknami, určite používajte fond, ako sme to opísali vo vašej aplikácii. Je zrejmé, že môžete hrať s konfiguračnými parametrami fondu, aby ste ho prispôsobili najlepšiemu nastaveniu vo vašom systéme.

10. Klaster Redis

Táto implementácia Redis poskytuje ľahkú škálovateľnosť a vysokú dostupnosť. Ak vám nie sú známe, odporúčame vám prečítať si ich oficiálnu špecifikáciu. Nebudeme sa zaoberať nastavením klastra Redis, pretože to trochu presahuje rámec tohto článku, ale po dokončení jeho dokumentácie by ste s tým nemali mať problémy.

Keď to máme pripravené, môžeme ich začať používať z našej aplikácie:

try (JedisCluster jedisCluster = new JedisCluster (new HostAndPort ("localhost", 6379))) {// use the jedisCluster resource as if it was a normal Jedis resource} catch (IOException e) {}

Potrebujeme poskytnúť iba podrobnosti o hostiteľovi a porte z jednej z našich hlavných inštancií, ostatné inštancie v klastri automaticky objaví.

Toto je určite veľmi výkonná funkcia, ale nejde o striebornú guľku. Pri používaní klastra Redis Cluster nemôžete vykonávať transakcie ani používať kanály, čo sú dve dôležité funkcie, na ktoré sa veľa aplikácií spolieha pri zabezpečovaní integrity údajov.

Transakcie sú zakázané, pretože v klastrovanom prostredí budú kľúče pretrvávať vo viacerých inštanciách. Atomicitu operácie a bezpečnosť vlákna nie je možné zaručiť pre operácie, ktoré zahŕňajú vykonávanie príkazov v rôznych inštanciách.

Niektoré pokročilé stratégie vytvárania kľúčov zabezpečia, aby sa údaje, ktoré sú pre vás zaujímavé, aby sa v nich uchovali, uchovali rovnako. Teoreticky by vám to malo umožniť úspešné vykonávanie transakcií pomocou jednej zo základných inštancií Jedis v klastri Redis.

Bohužiaľ v súčasnosti nemôžete zistiť, v ktorej inštancii Redis je konkrétny kľúč uložený pomocou Jedis (ktorý Redis v skutočnosti natívne podporuje), takže neviete, v ktorých inštanciách musíte transakciu vykonať. Ak vás to zaujíma, ďalšie informácie nájdete tu.

11. Záver

Drvivá väčšina funkcií z Redisu je už k dispozícii v Jedis a jeho vývoj sa pohybuje v dobrom tempe.

Dáva vám možnosť integrovať do svojej aplikácie výkonný pamäťový modul v pamäti s veľmi malými problémami. Nezabudnite však nastaviť združovanie pripojení, aby ste sa vyhli problémom s bezpečnosťou vlákien.

Ukážky kódu nájdete v projekte GitHub.


$config[zx-auto] not found$config[zx-overlay] not found