Interactie met Azure Cache voor Redis met behulp van .NET

Voltooid

Normaal gesproken gebruikt een clienttoepassing een clientbibliotheek om aanvragen te formulieren en opdrachten uit te voeren in een Redis-cache. U kunt rechtstreeks vanuit de Redis-clients pagina een lijst met clientbibliotheken krijgen.

Uitvoeren van opdrachten op de Redis-cache

Een populaire, krachtige Redis-client voor de .NET-taal is StackExchange.Redis. Het pakket is beschikbaar via NuGet en kan worden toegevoegd aan uw .NET-code met behulp van de opdrachtregel of IDE. Hieronder volgen voorbeelden van het gebruik van de client.

Verbinding maken met uw Redis-cache met StackExchange.Redis

Bedenk dat we het adres van de host, poortnummer en een toegangssleutel gebruiken om verbinding te maken met een Redis-server. Azure biedt ook een verbindingsreeks voor sommige Redis-clients die deze gegevens bundelen in één tekenreeks. Het ziet er ongeveer als volgt uit (met de cache-name velden password-here ingevuld met werkelijke waarden):

[cache-name].redis.cache.windows.net:6380,password=[password-here],ssl=True,abortConnect=False

U kunt deze tekenreeks doorgeven aan StackExchange.Redis voor het maken van een verbinding met de server.

U ziet dat er aan het einde nog twee parameters zijn:

  • SSL - zorgt ervoor dat de communicatie is versleuteld.
  • abortConnection - maakt het mogelijk dat een verbinding wordt gemaakt, zelfs als de server op dat moment niet beschikbaar is.

Er zijn verschillende andere optionele parameters die u kunt toevoegen aan de tekenreeks die de clientbibliotheek moet configureren.

Een verbinding maken

Het belangrijkste verbindingsobject in StackExchange.Redis is de StackExchange.Redis.ConnectionMultiplexer klasse. Dit object isoleert het proces van het verbinden met een Redis-server (of een groep servers). Het is geoptimaliseerd voor het efficiënt beheren van verbindingen en bedoeld om bij de hand te worden gehouden terwijl u toegang nodig hebt tot de cache.

U maakt een instantie ConnectionMultiplexer met de statische methode ConnectionMultiplexer.Connect of ConnectionMultiplexer.ConnectAsync, waarbij u ofwel een verbindingsreeks of een ConfigurationOptions-object ingeeft.

Hier volgt een eenvoudig voorbeeld:

using StackExchange.Redis;
...
var connectionString = "[cache-name].redis.cache.windows.net:6380,password=[password-here],ssl=True,abortConnect=False";
var redisConnection = ConnectionMultiplexer.Connect(connectionString);

Zodra u een ConnectionMultiplexerhebt, zijn er drie belangrijke dingen die u mogelijk wilt doen:

  • Toegang tot een Redis-database. Dit is waar we ons hier op richten.
  • Gebruik de functies van uitgever/abonnee van Redis. Dit is buiten het bereik van deze module.
  • Toegang krijgen tot een afzonderlijke server voor onderhoud of bewakingsdoeleinden.

Toegang krijgen tot een Redis-Database

De Redis-database wordt vertegenwoordigd door het type IDatabase. U kunt er een ophalen met behulp van de methode GetDatabase():

IDatabase db = redisConnection.GetDatabase();

Fooi

Het object dat wordt geretourneerd met GetDatabase, is een lichtgewicht object en hoeft niet te worden opgeslagen. Alleen de ConnectionMultiplexer moet actief worden bewaard.

Zodra u een IDatabase-object hebt, kunt u methoden uitvoeren om te communiceren met de cache. Alle methoden hebben synchrone en asynchrone versies die objecten retourneren Task om ze compatibel te maken met de async en await trefwoorden.

Hier volgt een voorbeeld van het opslaan van een sleutel/waarde in de cache:

bool wasSet = db.StringSet("favorite:flavor", "i-love-rocky-road");

De StringSet-methode retourneert een bool waarmee wordt aangegeven of de waarde is ingesteld (true) of niet (false). We kunnen vervolgens de waarde ophalen met de StringGet-methode:

string value = db.StringGet("favorite:flavor");
Console.WriteLine(value); // displays: ""i-love-rocky-road""

Ophalen en instellen van binaire waarden

Denk eraan dat Redis-sleutels en -waarden binair veilig zijn. Dezelfde methoden kunnen worden gebruikt voor het opslaan van binaire gegevens. Er zijn impliciete omzettingsoperators om te werken met type byte[], zodat u op natuurlijke wijze met de gegevens kunt werken:

byte[] key = ...;
byte[] value = ...;

db.StringSet(key, value);
byte[] key = ...;
byte[] value = db.StringGet(key);

StackExchange.Redis vertegenwoordigt sleutels die gebruikmaken van het type RedisKey. Deze klasse bevat impliciete conversies naar en van zowel string als byte[], zodat zowel tekstsleutels als binaire sleutels zonder complicatie kunnen worden gebruikt. Waarden worden vertegenwoordigd door het type RedisValue . Net als bij RedisKey zijn er impliciete conversies waarmee u string of byte[] kunt doorgeven.

Andere algemene bewerkingen

De interface IDatabase bevat verschillende methoden om met de Redis-cache te werken. Er zijn methoden om te werken met hashes, lijsten, sets en gesorteerde sets.

Hier volgen enkele van de meer algemene die met enkele sleutels werken. U kunt de broncode lezen voor de interface om de volledige lijst te zien.

Methode Omschrijving
CreateBatch Hiermee maakt u een groep van bewerkingen die als één eenheid naar de server worden verzonden, maar niet per se als een eenheid wordt verwerkt.
CreateTransaction Hiermee maakt u een groep van bewerkingen die als één eenheid naar de server worden verzonden en op de server als één eenheid wordt verwerkt.
KeyDelete De sleutel/waarde verwijderen.
KeyExists Retourneert of de opgegeven sleutel in de cache bestaat.
KeyExpire Stelt een time-to-live (TTL) verlooptijd op een sleutel.
KeyRename Verandert de naam van een sleutel.
KeyTimeToLive Retourneert de TTL-waarde van een sleutel.
KeyType Retourneert de tekenreeksweergave van het type van de waarde die bij de sleutel is opgeslagen. De verschillende typen die kunnen worden geretourneerd, zijn: string, lijsten, zset en hash-instellen.

Andere opdrachten uitvoeren

Het IDatabase object heeft een Execute en ExecuteAsync methode die kan worden gebruikt om tekstuele opdrachten door te geven aan de Redis-server. Bijvoorbeeld:

var result = db.Execute("ping");
Console.WriteLine(result.ToString()); // displays: "PONG"

De Execute en ExecuteAsync methoden retourneren een RedisResult object dat een gegevenshouder is die twee eigenschappen bevat:

  • Type die een string waarde retourneert die het type van het resultaat aangeeft: 'TEKENREEKS', 'GEHEEL GETAL', enzovoort.
  • IsNull een waar/onwaar-waarde om te detecteren wanneer het resultaat null is.

Vervolgens kunt u ToString() op de RedisResult gebruiken om de werkelijke geretourneerde waarde te krijgen.

U kunt Execute gebruiken om ondersteunde opdrachten uit te voeren - we kunnen bijvoorbeeld clients krijgen die zijn verbonden met de cache ('CLIENT LIST'):

var result = await db.ExecuteAsync("client", "list");
Console.WriteLine($"Type = {result.Type}\r\nResult = {result}");

Dit zou alle verbonden clients uitvoeren:

Type = BulkString
Result = id=9469 addr=16.183.122.154:54961 fd=18 name=DESKTOP-AAAAAA age=0 idle=0 flags=N db=0 sub=1 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 ow=0 owmem=0 events=r cmd=subscribe numops=5
id=9470 addr=16.183.122.155:54967 fd=13 name=DESKTOP-BBBBBB age=0 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 ow=0 owmem=0 events=r cmd=client numops=17

Meer complexe waarden opslaan

Redis is gericht op binaire veilige tekenreeksen, maar u kunt objectgrafieken in de cache uitzetten door ze te serialiseren naar een tekstuele indeling, doorgaans XML of JSON. Misschien hebben we voor onze statistieken een GameStats object dat er als volgt uitziet:

public class GameStat
{
    public string Id { get; set; }
    public string Sport { get; set; }
    public DateTimeOffset DatePlayed { get; set; }
    public string Game { get; set; }
    public IReadOnlyList<string> Teams { get; set; }
    public IReadOnlyList<(string team, int score)> Results { get; set; }

    public GameStat(string sport, DateTimeOffset datePlayed, string game, string[] teams, IEnumerable<(string team, int score)> results)
    {
        Id = Guid.NewGuid().ToString();
        Sport = sport;
        DatePlayed = datePlayed;
        Game = game;
        Teams = teams.ToList();
        Results = results.ToList();
    }

    public override string ToString()
    {
        return $"{Sport} {Game} played on {DatePlayed.Date.ToShortDateString()} - " +
               $"{String.Join(',', Teams)}\r\n\t" + 
               $"{String.Join('\t', Results.Select(r => $"{r.team } - {r.score}\r\n"))}";
    }
}

We gebruiken de Newtonsoft.Json-bibliotheek om een exemplaar van dit object in een tekenreeks te veranderen:

var stat = new GameStat("Soccer", new DateTime(2019, 7, 16), "Local Game", 
                new[] { "Team 1", "Team 2" },
                new[] { ("Team 1", 2), ("Team 2", 1) });

string serializedValue = Newtonsoft.Json.JsonConvert.SerializeObject(stat);
bool added = db.StringSet("event:1950-world-cup", serializedValue);

We kunnen het ophalen en weer in een object zetten met behulp van het omgekeerde proces:

var result = db.StringGet("event:2019-local-game");
var stat = Newtonsoft.Json.JsonConvert.DeserializeObject<GameStat>(result.ToString());
Console.WriteLine(stat.Sport); // displays "Soccer"

Opschonen van de verbinding

Zodra u klaar bent met de Redis-verbinding, kunt Dispose u de ConnectionMultiplexer. Hiermee sluit u alle verbindingen en sluit u de communicatie met de server af.

redisConnection.Dispose();
redisConnection = null;