Introduksjon til Jedis - Java Redis Client Library

1. Oversikt

Denne artikkelen er en introduksjon til Jedis, et klientbibliotek i Java for Redis - den populære datastrukturbutikken i minnet som også kan fortsette på disken. Den drives av en keystore-basert datastruktur for å vedvare data og kan brukes som en database, cache, meldingsmegler, etc.

Først skal vi forklare i hvilke situasjoner Jedis er nyttig og hva det handler om.

I de påfølgende delene utdyper vi de ulike datastrukturene og forklarer transaksjoner, rørledninger og publiser / abonner-funksjonen. Vi avslutter med tilkoblingssamling og Redis Cluster.

2. Hvorfor Jedis?

Redis lister opp de mest kjente klientbibliotekene på deres offisielle side. Det er flere alternativer til Jedis, men bare to til er verdig deres anbefaling stjerne, salat og Redisson.

Disse to klientene har noen unike funksjoner som trådsikkerhet, gjennomsiktig håndtering av tilkobling og en asynkron API, som alle funksjonene Jedis mangler.

Den er imidlertid liten og betydelig raskere enn de to andre. Dessuten er det klientbiblioteket som Spring Framework-utviklerne velger, og det har det største samfunnet av alle tre.

3. Maven-avhengigheter

La oss starte med å erklære den eneste avhengigheten vi trenger i pom.xml:

 redis.clients jedis 2.8.1 

Hvis du leter etter den nyeste versjonen av biblioteket, kan du sjekke ut denne siden.

4. Redis-installasjon

Du må installere og fyre opp en av de nyeste versjonene av Redis. Vi kjører den siste stabile versjonen for øyeblikket (3.2.1), men alle innlegg 3.x-versjoner bør være i orden.

Finn her mer informasjon om Redis for Linux og Macintosh, de har veldig like grunnleggende installasjonstrinn. Windows støttes ikke offisielt, men denne porten er godt vedlikeholdt.

Etter det kan vi direkte dykke inn og koble til den fra Java-koden vår:

Jedis jedis = nye Jedis ();

Standardkonstruktøren fungerer helt fint med mindre du har startet tjenesten på en ikke-standardport eller en ekstern maskin, i så fall kan du konfigurere den riktig ved å sende de riktige verdiene som parametere til konstruktøren.

5. Redis datastrukturer

De fleste av de opprinnelige operasjonskommandoene støttes, og praktisk nok deler de normalt det samme metodenavnet.

5.1. Strenger

Strenger er den mest grunnleggende typen Redis-verdi, nyttig når du trenger å vedvare enkle nøkkelverdidatatyper:

jedis.set ("hendelser / by / roma", "32,15,223,828"); Streng cachedResponse = jedis.get ("events / city / Roma");

Variabelen cachedResponse vil holde verdien 32,15,223,828. Sammen med utløpsstøtte, diskutert senere, kan det fungere som lynraskt og enkelt å bruke hurtiglagerlag for HTTP-forespørsler mottatt på webapplikasjonen og andre behov for hurtigbufring.

5.2. Lister

Redis-lister er ganske enkelt lister over strenger, sortert etter innsettingsrekkefølge og gjør det til et ideelt verktøy for å implementere for eksempel meldingskøer:

jedis.lpush ("kø # oppgaver", "første oppgave"); jedis.lpush ("kø # oppgaver", "secondTask"); Strengoppgave = jedis.rpop ("kø # oppgaver");

Variabelen oppgave vil holde verdien første oppgave. Husk at du kan serieisere ethvert objekt og vedvare det som en streng, slik at meldinger i køen kan ha mer komplekse data når det er nødvendig.

5.3. Settene

Redis-sett er en uordnet samling av strenger som er nyttige når du vil ekskludere gjentatte medlemmer:

jedis.sadd ("kallenavn", "kallenavn # 1"); jedis.sadd ("kallenavn", "kallenavn # 2"); jedis.sadd ("kallenavn", "kallenavn # 1"); Sett kallenavn = jedis.smembers ("kallenavn"); boolsk eksisterer = jedis.sismember ("kallenavn", "kallenavn # 1");

Java-settet kallenavn vil ha størrelsen 2, det andre tillegget av kallenavn # 1 ble ignorert. Også, den eksisterer variabel vil ha verdien ekte, metoden sismember lar deg raskt sjekke om det finnes et bestemt medlem.

5.4. Hashes

Redis Hashes kartlegger mellom String felt og String verdier:

jedis.hset ("bruker nr. 1", "navn", "Peter"); jedis.hset ("bruker nr. 1", "jobb", "politiker"); Strengnavn = jedis.hget ("bruker nr. 1", "navn"); Kartfelt = jedis.hgetAll ("bruker nr. 1"); Strengjobb = fields.get ("jobb");

Som du kan se, er hashes en veldig praktisk datatype når du vil ha tilgang til objektets egenskaper individuelt, siden du ikke trenger å hente hele objektet.

5.5. Sorterte sett

Sorterte sett er som et sett der hvert medlem har en tilhørende rangering som brukes til å sortere dem:

Kartpoeng = nytt HashMap (); scores.put ("PlayerOne", 3000.0); scores.put ("PlayerTwo", 1500.0); scores.put ("PlayerThree", 8200.0); scores.entrySet (). forEach (playerScore -> {jedis.zadd (key, playerScore.getValue (), playerScore.getKey ());}); String player = jedis.zrevrange ("ranking", 0, 1) .iterator (). Neste (); lang rang = jedis.zrevrank ("rangering", "PlayerOne");

Variabelen spiller vil holde verdien SpillerTre fordi vi henter topp 1-spilleren og han er den med høyest poengsum. De rang variabel vil ha verdien 1 fordi PlayerOne er den andre i rangeringen og rangeringen er nullbasert.

6. Transaksjoner

Transaksjoner garanterer atomisitet og trådsikkerhetsoperasjoner, noe som betyr at forespørsler fra andre klienter aldri vil bli håndtert samtidig under Redis-transaksjoner:

String friendsPrefix = "venner #"; String userOneId = "4352523"; String userTwoId = "5552321"; Transaksjon t = jedis.multi (); t.sadd (friendsPrefix + userOneId, userTwoId); t.sadd (friendsPrefix + userTwoId, userOneId); f.eksec ();

Du kan til og med gjøre en transaksjonsuksess avhengig av en bestemt nøkkel ved å "se" den rett før du starter din Transaksjon:

jedis.watch ("venner # slettet #" + userOneId);

Hvis verdien på denne nøkkelen endres før transaksjonen utføres, vil ikke transaksjonen fullføres.

7. Rørledning

Når vi må sende flere kommandoer, kan vi pakke dem sammen i en forespørsel og lagre tilkoblingsomkostninger ved hjelp av rørledninger, det er egentlig en nettverksoptimalisering. Så lenge operasjonene er gjensidig uavhengige, kan vi dra nytte av denne teknikken:

String userOneId = "4352523"; String userTwoId = "4849888"; Rørledning p = jedis.pipelined (); p.sadd ("søkte #" + userOneId, "paris"); p.zadd ("rangering", 126, userOneId); p.zadd ("rangering", 325, userTwoId); Svar pipeExists = p.sismember ("søkte #" + userOneId, "paris"); Respons pipeRanking = p.zrange ("rangering", 0, -1); p.sync (); Streng eksisterer = pipeExists.get (); Sett rangering = pipeRanking.get ();

Legg merke til at vi ikke får direkte tilgang til kommandosvarene, i stedet får vi en Respons forekomst hvorfra vi kan be om det underliggende svaret etter at rørledningen er synkronisert.

8. Publiser / Abonner

Vi kan bruke funksjonaliteten Redis messaging megler til å sende meldinger mellom de forskjellige komponentene i systemet vårt. Forsikre deg om at abonnent- og utgivertrådene ikke deler den samme Jedis-forbindelsen.

8.1. Abonnent

Abonner og hør på meldinger sendt til en kanal:

Jedis jSubscriber = nye Jedis (); jSubscriber.subscribe (new JedisPubSub () {@Override public void onMessage (Strengkanal, Strengmelding) {// håndter melding}}, "kanal");

Abonner er en blokkeringsmetode, du må avslutte abonnementet på JedisPubSub eksplisitt. Vi har overstyrt onMessage metoden, men det er mange flere nyttige metoder tilgjengelig for å overstyre.

8.2. Forlegger

Send så bare meldinger til den samme kanalen fra forlagets tråd:

Jedis jPublisher = nye Jedis (); jPublisher.publish ("kanal", "testmelding");

9. Tilkoblingsbasseng

Det er viktig å vite at måten vi har håndtert vår Jedis-instans på, er naiv. I et virkelig scenario vil du ikke bruke en enkelt forekomst i et miljø med flere tråder, ettersom en enkelt forekomst ikke er trådsikker.

Heldigvis kan vi enkelt lage et basseng med forbindelser til Redis slik at vi kan bruke det på forespørsel, et basseng som er trådsikkert og pålitelig så lenge du returnerer ressursen til bassenget når du er ferdig med det.

La oss lage JedisPool:

endelig JedisPoolConfig poolConfig = buildPoolConfig (); JedisPool jedisPool = ny 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.setTimeBetweenEvictionRunsMillis (Duration.ofSeconds (30) .toMillis ()); poolConfig.setNumTestsPerEvictionRun (3); poolConfig.setBlockWhenExhausted (true); retur bassengConfig; }

Siden bassengforekomsten er trådsikker, kan du lagre den et sted statisk, men du bør ta vare på å ødelegge bassenget for å unngå lekkasjer når applikasjonen avsluttes.

Nå kan vi bruke bassenget vårt hvor som helst i applikasjonen når det er nødvendig:

prøv (Jedis jedis = jedisPool.getResource ()) {// gjør operasjoner med jedis resource}

Vi brukte Java try-with-resources-setningen for å unngå å måtte lukke Jedis-ressursen manuelt, men hvis du ikke kan bruke denne setningen, kan du også lukke ressursen manuelt i endelig klausul.

Forsikre deg om at du bruker et basseng som vi har beskrevet i søknaden din, hvis du ikke vil møte ubehagelige problemer med flere tråder. Du kan åpenbart leke med bassengkonfigurasjonsparametrene for å tilpasse det til det beste oppsettet i systemet ditt.

10. Redis-klynge

Denne Redis-implementeringen gir enkel skalerbarhet og høy tilgjengelighet. Vi oppfordrer deg til å lese deres offisielle spesifikasjon hvis du ikke er kjent med den. Vi vil ikke dekke Redis-klyngeoppsett siden det er litt utenfor omfanget for denne artikkelen, men du bør ikke ha noen problemer med å gjøre det når du er ferdig med dokumentasjonen.

Når vi har klart det, kan vi begynne å bruke det fra applikasjonen vår:

prøv (JedisCluster jedisCluster = ny JedisCluster (ny HostAndPort ("localhost", 6379))) {// bruk jedisCluster-ressursen som om det var en normal Jedis-ressurs} fangst (IOException e) {}

Vi trenger bare å oppgi vert- og portdetaljer fra en av hovedforekomster, det vil automatisk oppdage resten av forekomsten i klyngen.

Dette er absolutt en veldig kraftig funksjon, men det er ikke en sølvkule. Når du bruker Redis Cluster, kan du ikke utføre transaksjoner eller bruke rørledninger, to viktige funksjoner som mange applikasjoner er avhengige av for å sikre dataintegritet.

Transaksjoner er deaktivert fordi nøkler i et gruppert miljø vil være vedvarende i flere tilfeller. Operasjonens atomicitet og trådsikkerhet kan ikke garanteres for operasjoner som involverer kommandokjøring i forskjellige tilfeller.

Noen avanserte strategier for nøkkeloppretting vil sikre at data som er interessante for deg å bli vedvarende i samme tilfelle, blir vedvarende på den måten. I teorien bør det gjøre det mulig for deg å utføre transaksjoner med vellykket bruk av en av de underliggende Jedis-forekomster av Redis-klyngen.

Dessverre kan du foreløpig ikke finne ut i hvilken Redis-forekomst en bestemt nøkkel er lagret ved hjelp av Jedis (som faktisk støttes av Redis), så du vet ikke hvilke av forekomster du må utføre transaksjonsoperasjonen. Hvis du er interessert i dette, kan du finne mer informasjon her.

11. Konklusjon

De aller fleste funksjonene fra Redis er allerede tilgjengelige i Jedis, og utviklingen går videre i et godt tempo.

Det gir deg muligheten til å integrere en kraftig lagringsmotor i minnet i applikasjonen din med lite problemer, bare ikke glem å sette opp tilkoblingssamling for å unngå trådsikkerhetsproblemer.

Du kan finne kodeeksempler i GitHub-prosjektet.


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