Programmering

Sådan bruges Redis til realtidsmåleprogrammer

Roshan Kumar er senior produktchef hos Redis Labs.

Måling er ikke kun et simpelt tælleproblem. Måling forveksles ofte med måling, men det er normalt mere end det. Måling indebærer måling, men som en løbende proces, normalt med det formål at regulere brugen eller strømmen af ​​en ressource over tid. Moderne applikationer indeholder måling på mange forskellige måder, lige fra at tælle mennesker, objekter eller begivenheder til at regulere brugen, kontrollere adgang og tildele kapacitet.

Målerløsninger skal generelt behandle store datamængder, mens de opfylder strenge krav til ydelse. Afhængig af løsningens omfang kan optælling og måling involvere tusinder, hvis ikke millioner af opdateringer til en database hvert sekund. De primære krav til en database for at understøtte en sådan løsning er høj kapacitet til skriveoperationer og lav latenstid (submillisekund) for svar.

Redis, open source in-memory database-platformen, leverer begge disse fordele, samtidig med at det er omkostningseffektivt med hensyn til at bruge minimale hardware-ressourcer. I denne artikel undersøger vi visse funktioner i Redis, der gør det til et godt valg til måling af løsninger, og hvordan vi kan bruge Redis til dette formål. Men lad os først se på et par af de mere almindelige anvendelser af måling.

Almindelige måleapplikationer

Måling er påkrævet i ethvert program, der skal måle brugen af ​​en ressource over tid. Her er fire almindelige scenarier:

  1. Forbrugsbaserede prismodeller. I modsætning til engangs- eller abonnementsbaserede betalingsmodeller tillader forbrugsbaserede prissætningsmodeller kun at betale for faktisk brug. Forbrugere har større fleksibilitet, frihed og omkostningsbesparelser, mens udbydere får større forbrugerretention.

    Implementering af sådanne modeller kan være vanskelig. Undertiden skal målesystemet spore mange anvendelseselementer og mange målinger i en enkelt plan. For eksempel kan en skyudbyder indstille forskellige prisniveauer for CPU-cyklusser, opbevaring, kapacitet, antal noder eller den tid, en tjeneste bruges. Et teleselskab kan indstille forskellige niveauer af det tilladte forbrug i minutter, data eller tekst. Målerløsningen skal håndhæve capping, opladning eller udvidelse af tjenester afhængigt af typen af ​​forbrugsbaseret prisfastsættelse.

  2. Begrænsning af ressourceudnyttelse. Enhver tjeneste på Internettet kan misbruges ved overdreven brug, medmindre denne service er begrænset til sats. Populære tjenester såsom Google AdWords API og Twitter Stream API indeholder takstgrænser af denne grund. Nogle ekstreme tilfælde af misbrug fører til denial of service (DoS). For at forhindre misbrug skal tjenester og løsninger, der er tilgængelige på Internettet, være designet med de rette satsbegrænsende regler. Selv enkle godkendelses- og login-sider skal begrænse antallet af forsøg i et givet tidsinterval.

    Et andet eksempel, hvor begrænsning af ressourceudnyttelse bliver nødvendigt, er når ændrede forretningskrav lægger større belastning på ældre systemer, end de kan understøtte. Takstbegrænsning af opkald til de ældre systemer giver virksomheder mulighed for at tilpasse sig den voksende efterspørgsel uden at skulle udskifte deres ældre systemer.

    Ud over at forhindre misbrug og reducere belastning hjælper god hastighedsbegrænsning også med styringen af ​​bursty trafikscenarier. For eksempel kan en API, der håndhæver en brute force-hastighedsbegrænsende metode, muliggøre 1000 opkald hver time. Uden en trafikformende politik på plads kan en klient ringe til API'en 1000 gange i de første par sekunder af hver time, måske mere end hvad infrastrukturen kan understøtte. Populære hastighedsbegrænsende algoritmer som Token Bucket og Leaky Bucket forhindrer bursts ved ikke kun at begrænse opkaldene, men også distribuere dem over tid.

  3. Ressourcefordeling. Overbelastning og forsinkelser er almindelige scenarier i applikationer, der beskæftiger sig med pakke-routing, jobadministration, trafikbelastning, crowd control, social media messaging, dataindsamling og så videre. Kømodeller tilbyder flere muligheder for at styre køstørrelsen baseret på ankomst- og afgangshastigheden, men det er ikke let at implementere disse modeller i stor skala.

    Efterslæb og overbelastning er konstante bekymringer, når det drejer sig om hurtige datastrømme. Kloge designere er nødt til at definere acceptable kølængdegrænser, mens de både overvåger køpræstation og dynamisk routing baseret på køstørrelser.

  4. Tæller i skala til beslutningstagning i realtid. E-handelswebsteder, spilapplikationer, sociale medier og mobilapps tiltrækker millioner af daglige brugere. Fordi flere øjenkugler giver større indtægter, er det afgørende for forretningen at tælle besøgende og deres handlinger nøjagtigt. Tælling er ligeledes nyttigt til brugstilfælde som f.eks. Gentagelse af fejl, eskalering af problemer, DDoS-angrebsforebyggelse, trafikprofilering, ressourceallokering efter behov og svindelbekæmpelse.

Måling design udfordringer

Løsningsarkitekter skal overveje mange parametre, når de bygger en måleapplikation, begyndende med disse fire:

  1. Design kompleksitet. Tælling, sporing og regulering af datamængder - især når de når frem til en høj hastighed - er en skræmmende opgave. Løsningsarkitekter kan håndtere måling ved applikationslaget ved hjælp af programmeringssprogstrukturer. Imidlertid er et sådant design ikke modstandsdygtigt over for fejl eller datatab. Traditionelle diskbaserede databaser er robuste og lover en høj grad af dataholdbarhed under fejl. Men ikke kun lever de ikke den nødvendige ydelse, de øger også kompleksiteten uden de rigtige datastrukturer og værktøjer til at implementere måling.
  2. Reaktionstid. Måling involverer typisk adskillige, konstante opdateringer af tællinger. Netværks- og disklæsnings- / skrivelatens tilføjes, når der behandles et stort antal. Dette kan snebold til at opbygge et stort efterslæb af data, der fører til flere forsinkelser. Den anden kilde til latens er et programdesign, der indlæser måledataene fra en database til programmets hovedhukommelse og skriver tilbage til databasen, når tælleren er opdateret.
  3. Samtidighed og konsistens. Arkitektur af en løsning til at tælle millioner og milliarder af ting kan blive kompleks, når begivenheder fanges i forskellige regioner, og de skal alle sammen på ét sted. Datakonsistens bliver et problem, hvis mange processer eller tråde opdaterer det samme antal samtidigt. Låsningsteknikker undgår konsistensproblemer og leverer konsistens på transaktionsniveau, men bremser løsningen.
  4. Holdbarhed. Måling påvirker indtægtsnumrene, hvilket betyder, at kortvarige databaser ikke er ideelle med hensyn til holdbarhed. En datalager i hukommelsen med holdbarhedsindstillinger er et perfekt valg.

Brug af Redis til måling af applikationer

I de følgende afsnit vil vi undersøge, hvordan man bruger Redis til tællings- og målingsløsninger. Redis har indbyggede datastrukturer, atomiske kommandoer og time-to-live (TTL) -funktioner, der kan bruges til strømmåling. Redis kører på en enkelt tråd. Derfor er alle databaseopdateringerne serialiseret, hvilket gør det muligt for Redis at fungere som et låsefrit datalager. Dette forenkler applikationsdesignet, da udviklere ikke behøver at bruge nogen anstrengelser på at synkronisere trådene eller implementere låsemekanismer for datakonsistens.

Atomic Redis kommandoer til optælling

Redis giver kommandoer til at øge værdier uden krav om at læse dem til programmets hovedhukommelse.

KommandoBeskrivelse
INCR nøgleForøg heltalværdien af ​​en nøgle én
INCRBY nøgleforøgelseForøg en nøgles heltal med det givne tal
INCRBYFLOAT nøgleforøgelseForøg floatværdien af ​​en nøgle med det givne beløb
DECR nøgleReducer en nøgles heltalsværdi en
FORKLARING nøglenedgangReducer heltalets værdi for en nøgle med det givne tal
HINCRBY forøgelse af nøglefeltForøg helhedsværdien af ​​et hash-felt med det givne tal
HINCRBYFLOAT forøgelse af nøglefeltForøg floatværdien af ​​et hashfelt med det givne beløb

Redis gemmer heltal som et base-10 64-bit underskrevet heltal. Derfor er den maksimale grænse for et heltal et meget stort tal: 263 - 1 = 9.223.372.036.854.775.807.

Indbygget time-to-live (TTL) på Redis-taster

En af de mest almindelige brugssager ved måling er at spore brugen mod tiden og begrænse ressourcer, når tiden løber ud. I Redis kan man indstille en time-to-live-værdi for tasterne. Redis deaktiverer automatisk tasterne efter en indstillet timeout. Den følgende tabel viser en række metoder til udløb af nøgler.

KommandoBeskrivelse
UDLØBE nøglesekunderIndstil en nøgles tid til at leve i sekunder
UDLØB nøgle tidsstempelIndstil udløbet for en nøgle som et Unix-tidsstempel
PEXPIRE nøgle millisekunderIndstil en nøgles tid til at leve i millisekunder
PEXPIREAT nøgle tidsstempelIndstil udløbet for en nøgle som et UNIX-tidsstempel i millisekunder
SÆT nøgleværdi [EX sekunder] [PX millisekunder]Sæt strengværdi til en nøgle sammen med den valgfri tid til at leve

Meddelelserne nedenfor giver dig tid til at leve på tasterne i sekunder og millisekunder.

KommandoBeskrivelse
TTL nøgleFå tid til at leve for en nøgle
PTTL nøgleFå tid til at leve for en nøgle i millisekunder

Redis datastrukturer og kommandoer for effektiv optælling

Redis er elsket for sine datastrukturer som lister, sæt, sorterede sæt, bindestreg og hyperloglogs. Mange flere kan tilføjes via Redis-modulerne API.

Redis Labs

Redis-datastrukturer leveres med indbyggede kommandoer, der er optimeret til at udføre med maksimal effektivitet i hukommelsen (lige hvor dataene er gemt). Nogle datastrukturer hjælper dig med at udrette meget mere end optælling af objekter. For eksempel garanterer Set-datastrukturen, at alle elementer er unikke.

Sorted Set går et skridt videre ved at sikre, at kun unikke elementer føjes til sættet og giver dig mulighed for at bestille elementerne baseret på en score. Ordning af dine elementer efter tid i en sorteret sæt datastruktur, for eksempel, tilbyder dig en tidsseriedatabase. Ved hjælp af Redis-kommandoer kan du få dine elementer i en bestemt rækkefølge eller slette emner, som du ikke har brug for mere.

Hyperloglog er en anden speciel datastruktur, der estimerer antallet af millioner af unikke genstande uden at skulle gemme objekterne selv eller påvirke hukommelsen.

DatastrukturKommandoBeskrivelse
ListeLLEN nøgleFå længden af ​​en liste
SætSCARD nøgleFå antallet af medlemmer i et sæt (kardinalitet)
Sorteret sætZCARD nøgleFå antallet af medlemmer i et sorteret sæt
Sorteret sætZLEXCOUNT tast min. maksTæl antallet af medlemmer i et sorteret sæt mellem et givet leksikografisk interval
HashHLEN nøgleFå antallet af felter i en hash
HyperloglogPFCOUNT nøgleFå den omtrentlige kardinalitet af det sæt, der observeres af Hyperloglog-datastrukturen
BitmapBITCOUNT tast [start slut]Tæller sæt bit i en streng

Redis vedholdenhed og replikering i hukommelsen

Måling af anvendelsestilfælde som betalinger involverer lagring og opdatering af oplysninger, der er kritiske for virksomheder. Tab af data har en direkte indvirkning på omsætningen. Det kan også ødelægge faktureringsoptegnelser, som ofte er et krav til overholdelse eller styring.

Du kan indstille konsistens og holdbarhed i Redis baseret på dine datakrav. Hvis du har brug for en permanent dokumentation for dine måledata, kan du opnå holdbarhed gennem Redis's persistensfunktioner. Redis understøtter AOF (kun append-fil), som kopierer skrivekommandoer til disken, når de sker, og snapshotting, som tager dataene, som de findes på et øjeblik, og skriver dem til disken.

Indbygget låsfri Redis-arkitektur

Redis-behandling er enkeltgevindet; dette sikrer dataintegritet, da alle skrivekommandoer automatisk serialiseres. Denne arkitektur aflaster udviklerne og arkitekterne fra byrden ved at synkronisere tråde i et multitrådet miljø.

I tilfælde af en populær mobilapplikation til forbrugere har tusindvis og undertiden millioner af brugere muligvis adgang til applikationen samtidigt. Lad os sige, at applikationen måler den brugte tid, og to eller flere brugere kan dele minutter samtidigt. De parallelle tråde kan opdatere det samme objekt uden at pålægge den ekstra byrde at sikre dataintegritet. Dette reducerer kompleksiteten af ​​applikationsdesignet, samtidig med at det sikres hastighed og effektivitet.

Redis måleeksempelimplementeringer

Lad os se på prøvekode. Flere af nedenstående scenarier ville kræve meget komplekse implementeringer, hvis den anvendte database ikke var Redis.

Blokering af flere loginforsøg

For at forhindre uautoriseret adgang til konti blokerer websteder undertiden brugere fra at foretage flere loginforsøg inden for en fastsat tidsperiode. I dette eksempel begrænser vi brugerne fra at foretage mere end tre loginforsøg på en time ved hjælp af enkel nøgle-til-live-funktionalitet.

Nøglen til at holde antallet af loginforsøg:

bruger_login_forsøg:

Trin:

Få det aktuelle antal forsøg:

GET bruger_login_forsøg:

Hvis null, skal du indstille nøglen med udløbstiden i sekunder (1 time = 3600 sekunder):

SET bruger_login_forsøg: 1 3600

Hvis ikke null, og hvis antallet er større end 3, så kast en fejl:

Hvis ikke null, og hvis optællingen er mindre end eller lig med 3, øges antallet:

INCR bruger_login_forsøg:

Ved et vellykket loginforsøg kan nøglen slettes som følger:

DEL bruger_login_forsøg:

Betal når du går

Redis Hash-datastrukturen giver nemme kommandoer til at spore brug og fakturering. I dette eksempel antager vi, at hver kunde har deres faktureringsdata gemt i en Hash, som vist nedenfor:

kunde_fakturering:

brug

koste

     .

     .

Antag at hver enhed koster to cent, og brugeren indtog 20 enheder. Kommandoerne til at opdatere brugen og fakturering er:

hincrby-kunde: brug 20

hincrbyfloat-kunde: omkostning .40

Som du måske har bemærket, kan din applikation opdatere oplysningerne i databasen uden at kræve, at den indlæser data fra databasen i sin egen hukommelse. Derudover kan du ændre et individuelt felt af et Hash-objekt uden at læse hele objektet.

Bemærk: Formålet med dette eksempel er at vise, hvordan du bruger hincrby og hincrbyfloat kommandoer. I et godt design undgår du at gemme overflødige oplysninger som både brug og omkostninger.

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