Vodič za Redis s Redissonom

1. Pregled

Redisson je Redisov klijent za Javu. U ovom ćemo članku istražiti neke od njegovih značajki i pokazati kako to može olakšati izgradnju distribuiranih poslovnih aplikacija.

Redisson predstavlja mrežu podataka u memoriji koji nudi distribuirane Java objekte i usluge iza kojih stoji Redis. Njegov distribuirani model podataka u memoriji omogućuje dijeljenje objekata i usluga domene kroz aplikacije i poslužitelje.

U ovom ćemo članku vidjeti vruće za postavljanje Redissona, razumijevanje njegovog djelovanja i istraživanje nekih objekata i usluga Redissona.

2. Ovisnosti Mavena

Krenimo s uvozom Redisson našem projektu dodavanjem donjeg odjeljka našem pom.xml:

 org.redisson redisson 3.13.1 

Najnoviju verziju ove ovisnosti možete pronaći ovdje.

3. Konfiguracija

Prije nego što započnemo, moramo osigurati da imamo najnoviju verziju postavljanja i pokretanja Redisa. Ako nemate Redis, a koristite Linux ili Macintosh, možete slijediti ovdje navedene podatke kako biste ih postavili. Ako ste korisnik sustava Windows, možete postaviti Redis pomoću ovog neslužbenog porta.

Moramo konfigurirati Redisson za povezivanje s Redisom. Redisson podržava veze sa sljedećim Redisovim konfiguracijama:

  • Pojedinačni čvor
  • Master sa slave čvorovima
  • Čvorovi stražara
  • Skupljeni čvorovi
  • Replicirani čvorovi

Redisson podržava Amazon Web Services (AWS) ElastiCache klaster i Azure Redis Cache za klasterirane i replicirane čvorove.

Spojimo se na jedan primjerak čvora Redis. Ova se instanca izvodi lokalno na zadanom portu, 6379:

RedissonClient klijent = Redisson.create ();

Možete prenijeti različite konfiguracije na Redisson objekt stvoriti metoda. To bi mogle biti konfiguracije za povezivanje s drugim priključkom ili možda za povezivanje s Redis klasterom. Ovaj konfiguracija može biti u Java kodu ili učitana iz vanjske konfiguracijske datoteke.

3.1. Java konfiguracija

Konfigurirajmo Redisson u Java kodu:

Config config = novi Config (); config.useSingleServer () .setAddress ("redis: //127.0.0.1: 6379"); RedissonClient klijent = Redisson.create (config);

Mi navedite Redisson konfiguracije u primjeru a Config objekt a zatim ga proslijedite na stvoriti metoda. Iznad smo Redissonu odredili da se želimo povezati s instancom Redisa s jednim čvorom. Da bismo to učinili, koristili smo Config objekt useSingleServer metoda. Ovo vraća referencu na SingleServerConfig objekt.

The SingleServerConfig objekt ima postavke koje Redisson koristi za povezivanje s instancom Redisa s jednim čvorom. Ovdje koristimo njegovo setAddress metoda za konfiguriranje adresa postavljanje. Ovo postavlja adresu čvora na koji se povezujemo. Neke druge postavke uključuju retryAttempts, vrijeme povezanosti je isteklo i ime klijenta. Te su postavke konfigurirane pomoću odgovarajućih metoda postavljača.

Možemo konfigurirati Redisson za različite Redisove konfiguracije na sličan način koristeći Config sljedeće metode objekta:

  • useSingleServer - za instancu s jednim čvorom. Ovdje potražite postavke za jedan čvor
  • useMasterSlaveServers - za master s slave čvorovima. Ovdje nabavite postavke čvora master-slave
  • useSentinelServers - za sentinel čvorove. Ovdje potražite postavke sentinel čvora
  • useClusterServers - za klasterirane čvorove. Ovdje potražite klasterirane postavke čvora
  • useReplicatedServers - za replicirane čvorove. Ovdje nabavite replicirane postavke čvora

3.2. Konfiguracija datoteke

Redisson može učitati konfiguracije iz vanjskog JSON-a ili YAML-a datoteke:

Config config = Config.fromJSON (nova datoteka ("singleNodeConfig.json")); RedissonClient klijent = Redisson.create (config);

The Config objekt odJSON metoda može učitati konfiguracije iz niza, datoteke, ulaznog toka ili URL-a.

Evo uzorka konfiguracije u singleNodeConfig.json datoteka:

{"singleServerConfig": {"idleConnectionTimeout": 10000, "connectTimeout": 10000, "timeout": 3000, "retryAttempts": 3, "retryInterval": 1500, "password": null, "subscriptionPerConnection": 5, "clientName ": null," address ":" redis: //127.0.0.1: 6379 "," subscriptionConnectionMinimumIdleSize ": 1," subscriptionConnectionPoolSize ": 50," connectionMinimumIdleSize ": 10," connectionPoolSize ": 64," database ": 0, "dnsMonitoringInterval": 5000}, "niti": 0, "nettyThreads": 0, "codec": null}

Evo odgovarajuće YAML konfiguracijske datoteke:

singleServerConfig: idleConnectionTimeout: 10000 connectTimeout: 10000 timeout: 3000 retryAttempts: 3 retryInterval: 1500 password: null subscriptionPerConnection: 5 clientName: null address: "redis: //127.0.0.1: 6379" subscriptionConnectionMinimumIdleSize: subscriptionConnectionMinimumIdleSize: connection 64 baza podataka: 0 dnsMonitoringInterval: 5000 niti: 0 nettyThreads: 0 kodek:! {} 

Na sličan način možemo konfigurirati druge konfiguracije Redisa iz datoteke koristeći postavke svojstvene toj konfiguraciji. Za referencu, ovdje su njihovi formati datoteka JSON i YAML:

  • Format jednog čvora
  • Master sa slave čvorovima - format
  • Čvorovi stražara - format
  • Skupljeni čvorovi - format
  • Replicirani čvorovi - format

Za spremanje Java konfiguracije u JSON ili YAML format možemo koristiti toJSON ili doYAML metode Config objekt:

Config config = novi Config (); // ... ovdje u Java Stringu konfiguriramo više postavki jsonFormat = config.toJSON (); Niz yamlFormat = config.toYAML ();

Sad kad znamo kako konfigurirati Redisson, pogledajmo kako Redisson izvršava operacije.

4. Operacija

Redisson podržava sinkrona, asinkrona i reaktivna sučelja. Operacije nad njima sučelja su zaštićena od niti.

Svi entiteti (objekti, zbirke, brave i usluge) koje generira a RedissonClient imaju sinkrone i asinkrone metode. Sinkrone metode nose asinkrone varijante. Te metode obično nose isto ime metode kao i njihove sinkrone inačice dodane uz "Async". Pogledajmo sinkronu metodu RAtomicLong objekt:

RedissonClient klijent = Redisson.create (); RAtomicLong myLong = client.getAtomicLong ('myLong'); 

Asinkrona varijanta sinkrone compareAndSet metoda bi bila:

RFuture isSet = myLong.compareAndSetAsync (6, 27);

Asinkrona varijanta metode vraća RFuture objekt. Možemo postaviti slušatelje na ovaj objekt da vraćaju rezultat kad postane dostupan:

isSet.handle ((rezultat, iznimka) -> {// ovdje obrađujemo rezultat ili iznimku.});

Da bismo generirali reaktivne objekte, trebali bismo koristiti RedissonReactiveClient:

RedissonReactiveClient klijent = Redisson.createReactive (); RAtomicLongReactive myLong = client.getAtomicLong ("myLong"); Izdavač isSetPublisher = myLong.compareAndSet (5, 28);

Ova metoda vraća reaktivne objekte na temelju Standarda reaktivnih tokova za Javu 9.

Istražimo neke od distribuiranih objekata koje nudi Redisson.

5. Predmeti

Pojedinačna instanca a Redisson objekt je serializiran i pohranjen u bilo kojem od dostupnih Redisovih čvorova koji podržavaju Redisson. Ti bi se objekti mogli distribuirati u klasteru kroz više čvorova i može im se pristupiti jednom aplikacijom ili više aplikacija / poslužitelja.

Ovi distribuirani objekti slijede specifikacije iz java.util.concurrent.atomic paket. Podržavaju atomske operacije bez zaključavanja, bez niti i atomske operacije na objektima pohranjenim u Redisu. Dosljednost podataka između aplikacija / poslužitelja osigurana je jer se vrijednosti ne ažuriraju dok druga aplikacija čita objekt.

Predmeti Redisson vezani su za Redis tipke. Ovim tipkama možemo upravljati putem RKeys sučelje. A zatim pristupamo našim Redisson objektima pomoću ovih tipki.

Postoji nekoliko opcija koje možemo koristiti za dobivanje Redis tipki.

Sve tipke možemo jednostavno dobiti:

RKeys tipke = client.getKeys ();

Alternativno, možemo izdvojiti samo imena:

Iterable allKeys = keys.getKeys ();

I na kraju, uspijevamo dobiti tipke koje odgovaraju uzorku:

Iterable keysByPattern = keys.getKeysByPattern ('key *')

Sučelje RKeys također omogućuje brisanje ključeva, brisanje ključeva prema uzorku i druge korisne operacije temeljene na ključevima koje bismo mogli koristiti za upravljanje ključevima i objektima.

Distribuirani objekti koje pruža Redisson uključuju:

  • ObjectHolder
  • BinaryStreamHolder
  • Geoprostorni držač
  • BitSet
  • AtomicLong
  • AtomicDouble
  • Tema
  • BloomFilter
  • HyperLogLog

Pogledajmo tri od ovih predmeta: ObjectHolder, AtomicLong, i Tema.

5.1. Nosač predmeta

Koju zastupa RBucket klase, ovaj objekt može sadržavati bilo koju vrstu objekta. Ovaj objekt ima maksimalnu veličinu od 512 MB:

RBucket kanta = client.getBucket ("knjiga"); bucket.set (nova knjiga ()); Knjiga glavne knjige = kanta.get ();

The RBucket objekt može izvoditi atomske operacije kao što su compareAndSet igetAndSet na objektima koje drži.

5.2. AtomicLong

Koju zastupa RAtomicLong klase, ovaj objekt jako podsjeća na java.util.concurrent.atomic.AtomicLong razreda i predstavlja a dugo vrijednost koja se može ažurirati atomski:

RAtomicLong atomicLong = client.getAtomicLong ("myAtomicLong"); atomicLong.set (5); atomicLong.incrementAndGet ();

5.3. Tema

The Tema objekt podržava Redisov mehanizam "objavi i pretplati se". Da biste preslušali objavljene poruke:

RTopic subscribeTopic = client.getTopic ("baeldung"); subscribeTopic.addListener (CustomMessage.class, (channel, customMessage) -> future.complete (customMessage.getMessage ()));

Iznad, Tema je registriran za preslušavanje poruka s kanala "baeldung". Zatim u temu dodamo slušatelja za obradu dolaznih poruka s tog kanala. Na kanal možemo dodati više slušatelja.

Objavimo poruke na kanalu “baeldung”:

RTopic objavitiTopic = client.getTopic ("baeldung"); long clientsReceivedMessage = objaviteTopic.publish (nova CustomMessage ("Ovo je poruka"));

Ovo se može objaviti iz druge aplikacije ili poslužitelja. The CustomMessage objekt će primiti slušatelj i obraditi kako je definirano u onMessage metoda.

Ovdje možemo saznati više o ostalim objektima Redissona.

6. Zbirke

S kolekcijama Redisson radimo na isti način kao i s predmetima.

Distribuirane kolekcije koje pruža Redisson uključuju:

  • Karta
  • Multimap
  • Postavi
  • SortedSet
  • ScoredSortedSet
  • LexSortedSet
  • Popis
  • Red
  • Deque
  • BlockingQueue
  • BoundedBlockingQueue
  • BlockingDeque
  • BlockingFairQueue
  • Odgođeni red
  • PriorityQueue
  • PriorityDeque

Pogledajmo tri od ovih kolekcija: Karta, Postavi, i Popis.

6.1. Karta

Karte temeljene na Redissonu implementiraju java.util.concurrent.ConcurrentMap i java.util.Map sučelja. Redisson ima četiri implementacije mape. Ovi su RMap, RMapCache, RLocalCachedMap i RClusteredMap.

Stvorimo kartu s Redissonom:

RMap karta = client.getMap ("knjiga"); Knjiga novaLedger = map.put ("123", nova knjiga ()); karta

RMapCache podržava deložaciju unosa karte. RLocalCachedMap omogućuje lokalno predmemoriranje unosa na karti. RClusteredMap omogućuje razdvajanje podataka s jedne karte na glavnim čvorovima Redis klastera.

Ovdje možemo saznati više o kartama Redisson.

6.2. Postavi

Na temelju Redissona Postavi provodi java.util.Set sučelje.

Redisson ih ima tri Postavi implementacije, RSet, RSetCache, i RClusteredSet sa sličnom funkcionalnošću kao i njihovi kolege s karata.

Stvorimo a Postavi s Redissonom:

RSet ledgerSet = client.getSet ("ledgerSet"); ledgerSet.add (nova knjiga ());

Ovdje možemo saznati više o Redisson setovima.

6.3. Popis

Na temelju Redissona Popisi provesti java.util.Popis sučelje.

Stvorimo a Popis s Redissonom:

RList ledgerList = client.getList ("ledgerList"); ledgerList.add (nova knjiga ());

Ovdje možemo saznati više o ostalim Redisson kolekcijama.

7. Brave i sinkronizatori

Redissonova raspodijeljene brave omogućuju sinkronizaciju niti preko aplikacija / poslužitelja. Redissonov popis brava i sinkronizatora uključuje:

  • Zaključaj
  • FairLock
  • MultiLock
  • ReadWriteLock
  • Semafor
  • PermitExpirableSemaphore
  • CountDownLatch

Pogledajmo Zaključaj i MultiLock.

7.1. Zaključaj

Redissonova Zaključaj provodi java.util.concurrent.locks.Lock sučelje.

Primijenimo bravu, predstavljenu znakom RLock razred:

RLock zaključavanje = client.getLock ("zaključavanje"); lock.lock (); // izvodimo neke duge operacije ... lock.unlock ();

7.2. MultiLock

Redissonova RedissonMultiLock grupe višestruke RLock predmete i tretira ih kao jednu bravu:

RLock lock1 = clientInstance1.getLock ("lock1"); RLock lock2 = clientInstance2.getLock ("lock2"); RLock lock3 = clientInstance3.getLock ("lock3"); RedissonMultiLock brava = nova RedissonMultiLock (brava1, brava2, brava3); lock.lock (); // izvodimo dugotrajnu operaciju ... lock.unlock ();

Ovdje možemo saznati više o drugim bravama.

8. Usluge

Redisson izlaže 4 vrste distribuiranih usluga. Ovi su: Daljinska usluga, Usluga objekata uživo, Služba izvršitelja i Služba zakazanih izvršitelja. Pogledajmo Remote Service i Live Object Service.

8.1. Daljinska usluga

Ova usluga pruža Javno pozivanje Java metode olakšano od Redisa. Udaljena usluga Redisson sastoji se od implementacije na strani poslužitelja (radnička instanca) i klijenta. Implementacija na strani poslužitelja izvršava udaljenu metodu koju je pozvao klijent. Pozivi s udaljene usluge mogu biti sinkroni ili asinkroni.

Na strani poslužitelja registrira sučelje za daljinsko pozivanje:

RRemoteService remoteService = client.getRemoteService (); LedgerServiceImpl ledgerServiceImpl = novo LedgerServiceImpl (); remoteService.register (LedgerServiceInterface.class, ledgerServiceImpl);

Klijentska strana poziva metodu registriranog udaljenog sučelja:

RRemoteService remoteService = client.getRemoteService (); LedgerServiceInterface ledgerService = remoteService.get (LedgerServiceInterface.class); Unosi na popisu = ledgerService.getEntries (10);

Ovdje možemo saznati više o daljinskim uslugama.

8.2. Usluga objekata uživo

Redisson Live Objects proširuju koncept standardnih Java objekata kojima se moglo pristupiti samo s jednog JVM-a na poboljšani Java objekti koji se mogu dijeliti između različitih JVM-ova na različitim strojevima. To se postiže preslikavanjem polja objekta u Redisov heš. Ovo mapiranje izrađuje se kroz vrijeme izrade proxy klase. Dobivači i postavljači polja preslikavaju se u naredbe Redis hget / hset.

Redisson Live Objekti podržavaju pristup atomskom polju kao rezultat Redisove jednonitne prirode.

Stvaranje objekta uživo je jednostavno:

@REntity javna klasa LedgerLiveObject {@RId privatni naziv niza; // geteri i postavljači ...}

Svoje predavanje bilježimo s @REntity i jedinstveno ili identifikacijsko polje sa @Osloboditi. Nakon što to učinimo, možemo koristiti naš objekt uživo u našoj aplikaciji:

Usluga RLiveObjectService = client.getLiveObjectService (); LedgerLiveObject knjiga = novi LedgerLiveObject (); ledger.setName ("knjiga1"); knjiga = usluga.persist (knjiga);

Stvaramo svoj živi objekt poput standardnih Java objekata koristeći novi ključna riječ. Tada koristimo primjerak RLiveObjectService za spremanje objekta u Redis koristeći njegov ustrajati metoda.

Ako je objekt prethodno zadržan na Redisu, možemo ga preuzeti:

LedgerLiveObject returnLedger = service.get (LedgerLiveObject.class, "ledger1");

Koristimo RLiveObjectService kako bismo dobili naš objekt uživo pomoću polja označenog s @Osloboditi.

Ovdje možemo pronaći više o objektima Redisson Live Objects, a ovdje su opisane i druge usluge Redisson.

9. Cjevovod

Redisson podupire cjevovod. Više operacija može se grupirati kao jedna atomska operacija. To je olakšano RBatch razred. Više naredbi se agregira protiv RBatch instance objekta prije nego što se izvrše:

RBatch batch = client.createBatch (); batch.getMap ("ledgerMap"). fastPutAsync ("1", "2"); batch.getMap ("ledgerMap"). putAsync ("2", "5"); BatchResult batchResult = batch.execute ();

10. Skriptiranje

Redisson podržava LUA skriptiranje. Možemo izvršiti LUA skripte protiv Redisa:

client.getBucket ("foo"). set ("bar"); Rezultat niza = client.getScript (). Eval (Mode.READ_ONLY, "return redis.call ('get', 'foo')", RScript.ReturnType.VALUE);

11. Klijent niske razine

Moguće je da bismo možda željeli izvoditi Redisove operacije koje još nije podržao Redisson. Redisson nudi klijenta niske razine koji omogućuje izvršavanje izvornih Redis naredbi:

RedisClientConfig redisClientConfig = novi RedisClientConfig (); redisClientConfig.setAddress ("localhost", 6379); RedisClient klijent = RedisClient.create (redisClientConfig); RedisConnection conn = client.connect (); conn.sync (StringCodec.INSTANCE, RedisCommands.SET, "test", 0); conn.closeAsync (); client.shutdown ();

Klijent niske razine također podržava asinkrone operacije.

12. Zaključak

Ovaj je članak predstavio Redisson i neke značajke koje ga čine idealnim za razvoj distribuiranih aplikacija. Istražili smo njegove distribuirane predmete, kolekcije, brave i usluge. Također smo istražili neke druge njegove značajke poput cjevovoda, skriptiranja i klijenta niske razine.

Redisson također pruža integraciju s drugim okvirima kao što su JCache API, Spring Cache, Hibernate Cache i Spring Sessions. Ovdje možemo saznati više o njegovoj integraciji s drugim okvirima.

Uzorke koda možete pronaći u projektu GitHub.