Interagir avec Azure Cache pour Redis à l’aide de .NET

Effectué

En règle générale, une application cliente utilise une bibliothèque de client pour former des requêtes et exécuter des commandes sur un cache Redis. Vous pouvez obtenir une liste des bibliothèques clientes directement à partir de la page des clients Redis.

Exécution des commandes sur le cache Redis

StackExchange.Redis est un client Redis populaire à hautes performances pour le langage .NET. Le package est disponible via NuGet et peut être ajouté à votre code .NET à l’aide de la ligne de commande ou de l’IDE. Voici des exemples d’utilisation du client.

Connexion à votre cache Redis avec StackExchange.Redis

Rappelez-vous que nous utilisons l’adresse d’hôte, le numéro de port et une clé d’accès pour nous connecter à un serveur Redis. Azure propose également une chaîne de connexion pour certains clients Redis, qui regroupe ces données en une seule chaîne. Il ressemble à ce qui suit (les champs cache-name et password-here étant remplis avec des valeurs réelles) :

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

Vous pouvez passer cette chaîne à StackExchange.Redis pour créer une connexion au serveur.

Notez qu’il existe deux paramètres supplémentaires à la fin :

  • SSL -permet de s’assurer que la communication est chiffrée.
  • abortConnection -autorise la création d’une connexion même si le serveur n’est pas disponible à ce moment-là.

Il existe d’autres paramètres facultatifs que vous pouvez ajouter à la chaîne afin de configurer la bibliothèque cliente.

Création d’une connexion

L’objet principal d’une connexion dans StackExchange.Redis est la classe StackExchange.Redis.ConnectionMultiplexer. Cet objet extrait le processus de connexion à un serveur Redis (ou à un groupe de serveurs). Il est optimisé pour gérer efficacement les connexions et il est destiné à être conservé lorsque vous devez accéder au cache.

Vous créez une instance ConnectionMultiplexer à l’aide de la méthode statique ConnectionMultiplexer.Connect ou ConnectionMultiplexer.ConnectAsync, en passant une chaîne de connexion ou un objet ConfigurationOptions.

Voici un exemple simple :

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

Une fois que vous avez un ConnectionMultiplexer, il existe trois éléments principaux que vous pouvez souhaiter effectuer :

  • Accéder à une base de données Redis. C’est ce sur quoi nous nous concentrerons ici.
  • Utiliser les fonctionnalités de serveur de publication/d’abonnement de Redis. Ce n’est pas traité par ce module.
  • Accédez à un serveur individuel à des fins de maintenance ou de surveillance.

Accès à une base de données Redis

La base de données Redis est représentée par le type IDatabase. Vous pouvez en récupérer un à l’aide de la méthode GetDatabase() :

IDatabase db = redisConnection.GetDatabase();

Conseil

L’objet renvoyé à partir de GetDatabase est un objet direct léger qui n’a pas besoin d’être stocké. Seul le ConnectionMultiplexer doit être maintenu actif.

Une fois que vous avez un objet IDatabase, vous pouvez exécuter des méthodes pour interagir avec le cache. Toutes les méthodes ont des versions synchrones et asynchrones qui retournent des objets Task pour les rendre compatibles avec les mots clés async et await.

Voici un exemple de stockage d’une clé-valeur dans le cache :

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

La méthode StringSet retourne un bool indiquant si la valeur a été définie (true) ou non (false). Nous pouvons ensuite récupérer la valeur avec la méthode StringGet :

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

Obtention et définition des valeurs binaires

Rappelez-vous que les valeurs et les clés Redis sont des données binaires sécurisées. Ces mêmes méthodes peuvent être utilisées pour stocker des données binaires. Il existe des opérateurs de conversion implicites pour travailler avec des types byte[] afin que vous puissiez travailler naturellement avec les données :

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

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

StackExchange.Redis représente les clés à l’aide du type RedisKey. Cette classe a des conversions implicites vers et depuis string et byte[], ce qui permet d’utiliser du texte et des clés binaires sans complication. Les valeurs sont représentées par le type RedisValue . Comme avec RedisKey, il existe des conversions implicites en place pour vous permettre de transmettre string ou byte[].

Autres opérations courantes

L’interface IDatabase comprend plusieurs autres méthodes pour travailler avec le cache Redis. Il existe des méthodes pour travailler avec des hachages, des listes, des ensembles et des ensembles ordonnés.

Voici quelques-unes des méthodes les plus courantes qui fonctionnent avec des clés uniques, vous pouvez lire le code source pour l’interface pour voir la liste complète.

Méthode Description
CreateBatch Crée un groupe d’opérations qui seront envoyées au serveur comme une unité unique, mais qui ne seront pas nécessairement traitées comme une unité.
CreateTransaction Crée un groupe d’opérations qui seront envoyées au serveur comme une unité unique et qui seront traitées comme telle par le serveur.
KeyDelete Supprimez la clé/valeur.
KeyExists Indique si une clé donnée existe dans le cache.
KeyExpire Définit un délai d’expiration de durée de vie (TTL) sur une clé.
KeyRename Renomme une clé.
KeyTimeToLive Retourne la durée de vie d’une clé.
KeyType Retourne la représentation sous forme de chaîne du type de la valeur stockée dans la clé. Voici les différents types pouvant être retournés : string, list, set, zset et hash.

Exécution d’autres commandes

L’objet IDatabase comporte une méthode Execute et ExecuteAsync, qui permet de passer des commandes textuelles au serveur Redis. Par exemple :

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

Les méthodes Execute et ExecuteAsync retournent un objet RedisResult qui est un détenteur de données incluant deux propriétés :

  • Type qui retourne un string indiquant le type du résultat - « STRING », « INTEGER », etc.
  • IsNull une valeur true/false pour détecter lorsque le résultat est null.

Vous pouvez ensuite utiliser ToString() sur le RedisResult pour obtenir la valeur renvoyée réelle.

Vous pouvez utiliser Execute pour utiliser les commandes prises en charge. Par exemple, nous pouvons obtenir tous les clients connectés au cache (« CLIENT LIST») :

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

Cela affiche tous les clients connectés :

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

Stockage de valeurs plus complexes

Redis est axé sur les chaînes de binaires sécurisées, mais vous pouvez retirer du cache les graphiques d’objets en les sérialisant au format texte, généralement XML ou JSON. Par exemple, pour nos statistiques éventuellement, nous avons un objet GameStats qui ressemble à :

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"))}";
    }
}

Nous pourrions utiliser la bibliothèque Newtonsoft.Json pour transformer une instance de cet objet en une chaîne :

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);

Nous pouvons la récupérer et la retransformer en un objet en utilisant le processus inverse :

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

Nettoyage de la connexion

Une fois que vous avez terminé avec la connexion Redis, vous pouvez Dispose le ConnectionMultiplexer. Cela entraîne la fermeture de toutes les connexions et l’arrêt de la communication avec le serveur.

redisConnection.Dispose();
redisConnection = null;