.NET kullanarak Redis için Azure Cache ile etkileşim kurma

Tamamlandı

Genellikle, bir istemci uygulaması istekleri oluşturmak ve Redis önbelleğinde komut yürütmek için bir istemci kitaplığı kullanır. İstemci kitaplığı listesine Redis istemcileri sayfasından ulaşabilirsiniz.

Redis önbelleğinde komut yürütme

.NET dili için yüksek performanslı popüler Redis istemcilerinden biri StackExchange.Redis'dir. Paket NuGet üzerinden alınabilir ve komut satırı veya IDE kullanılarak .NET kodunuza eklenebilir. aşağıda istemcinin nasıl kullanılacağına ilişkin örnekler verilmiştir.

StackExchange.Redis ile Redis önbelleğinize bağlanma

Hatırlarsanız bir Redis sunucusuna bağlanmak için ana bilgisayar adresini, bağlantı noktası numarasını ve bir erişim anahtarını kullanıyorduk. Azure ayrıca bazı Redis istemcileri için bu verileri tek bir dizede bir araya getiren bir bağlantı dizesi sunar. Aşağıdakine cache-name benzer (ve password-here alanları gerçek değerlerle doldurulmuş şekilde):

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

Bu dizeyi StackExchange.Redis istemcisine ileterek sunucu bağlantısı oluşturabilirsiniz.

Sonunda iki parametre daha olduğuna dikkat edin:

  • ssl - İletişimin şifrelenmesini sağlar.
  • abortConnection - Sunucu kullanılabilir durumda olmasa da bir bağlantı oluşturulmasını sağlar.

İstemci kitaplığını yapılandırmak için dizeye ekleyebileceğiniz farklı birçok isteğe bağlı parametre vardır.

Bağlantı oluşturma

StackExchange.Redis istemcisindeki ana bağlantı nesnesi StackExchange.Redis.ConnectionMultiplexer sınıfıdır. Bu nesne Redis sunucusuna (veya sunucu grubuna) bağlanma işlemini soyutlar. Bağlantıları verimli bir şekilde yönetmek için iyileştirilmiştir ve önbelleğe erişmeniz gerektiğinde elinizin altında olmasını sağlar.

ConnectionMultiplexer örneğini oluşturmak için statik ConnectionMultiplexer.Connect veya ConnectionMultiplexer.ConnectAsync metodunu kullanır ve bir bağlantı dizesi veya ConfigurationOptions nesnesi iletirsiniz.

İşte basit bir örnek:

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

bir ConnectionMultiplexersahip olduktan sonra, yapmak isteyebileceğiniz üç birincil şey vardır:

  • Bir Redis veritabanına erişme. Burada bu işleme odaklanacağız.
  • Redis'in yayımcı/abone özelliklerinden faydalanın. Bu işlem, bu modülün kapsamı dışındadır.
  • Bakım veya izleme amacıyla bir sunucuya erişme.

Bir Redis veritabanına erişme

Redis veritabanı IDatabase türüyle gösterilir. Almak için GetDatabase() yöntemini kullanabilirsiniz:

IDatabase db = redisConnection.GetDatabase();

Bahşiş

GetDatabase ile döndürülen nesne küçük bir nesnedir ve depolanması gerekmez. Yalnızca ConnectionMultiplexer nesnesinin canlı tutulması gerekir.

IDatabase nesnesine sahip olduğunuzda önbellekle etkileşim kurmak için gerekli yöntemleri yürütebilirsiniz. Tüm yöntemlerin ve anahtar sözcükleriyle async uyumlu hale getirmek için nesneleri döndüren Task zaman uyumlu ve await zaman uyumsuz sürümleri vardır.

Aşağıda önbellekte anahtar/değer depolama örneği verilmiştir:

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

StringSet yöntemi değerin ayarlanıp (true) ayarlanmadığını (false) belirten bir bool döndürür. Ardından değeri StringGet metoduyla alabiliriz:

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

İkili değerleri alma ve ayarlama

Redis anahtarlarının ve değerlerinin güvenli ikili olduğunu hatırlayın. Aynı yöntemler ikili verileri depolamak için de kullanılabilir. byte[] türleriyle çalışmak için örtük dönüştürme işleçleri olduğundan verilerle normal bir şekilde çalışabilirsiniz:

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

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

StackExchange.Redis, anahtarları RedisKey türünü kullanarak temsil eder. Bu sınıf string ve byte[] için örtük dönüştürmelere sahiptir ve bu sayede hem metin hem de ikili anahtarların sorunsuz bir şekilde kullanılmasını sağlar. Değerler RedisValue türüyle gösterilir. RedisKey örneğinde olduğu gibi string veya byte[] iletmenizi sağlayan örtük dönüştürmeler vardır.

Diğer yaygın işlemler

IDatabase arabiriminde Redis önbelleğiyle çalışırken kullanabileceğiniz farklı birçok yöntem vardır. Bu metotları kullanarak karmalar, listeler, kümeler ve sıralı kümelerle çalışabilirsiniz.

Tek anahtarla çalışan yaygın örneklerin bazıları burada verilmiştir. Listenin tamamı için arabirim kaynak kodunu okuyabilirsiniz.

Yöntem Açıklama
CreateBatch Sunucuya tek bir birim olarak gönderilen ancak birim olarak işlenmeyen bir işlem grubu oluşturur.
CreateTransaction Sunucuya tek bir birim olarak gönderilen ve tek bir birim olarak işlenen bir işlem grubu oluşturur.
KeyDelete Anahtar/değer çiftini siler.
KeyExists Verilen anahtarın önbellekte olup olmadığını döndürür.
KeyExpire Anahtar için bir yaşam süresi (TTL) belirler.
KeyRename Bir anahtarı yeniden adlandırır.
KeyTimeToLive Bir anahtarın TTL değerini döndürür.
KeyType Anahtarda depolanan değer türünün dize temsilini döndürür. Döndürülebilecek türler: string, list, set, zset ve hash.

Diğer komutları çalıştırma

nesnesi, IDatabase Redis sunucusuna metin komutlarını geçirmek için kullanılabilecek bir Execute ve ExecuteAsync yöntemine sahiptir. Örnek:

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

ve yöntemleri, Execute iki özellik içeren bir veri sahibi olan bir nesne döndürürRedisResult:ExecuteAsync

  • Type sonucun türünü belirten bir string döndürür: "STRING", "INTEGER", vb.
  • IsNull, sonucun null olduğunu tespit eden bir true/false değeridir.

Ardından RedisResult üzerinde ToString() kullanarak döndürülen gerçek değeri alabilirsiniz.

Execute kullanarak desteklenen komutları gerçekleştirebilirsiniz. Örneğin önbelleğe bağlı tüm istemcileri alabilirsiniz ("CLIENT LIST"):

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

Bu durumda bağlı tüm istemciler listelenir:

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

Daha karmaşık değerlerini depolama

Redis, güvenli ikili değerlere odaklanır ancak genellikle XML veya JSON olmak üzere metin biçimine serileştirerek nesne grafiklerini önbelleğe alabilirsiniz. Örneğin, istatistiklerimiz için aşağıdakine benzer bir GameStats nesnemiz olabilir:

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

Newtonsoft.Json kitaplığını kullanarak bu nesnenin örneğini dizeye dönüştürebiliriz:

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

Tersine işlem uygulayarak bunu alıp tekrar bir nesneye dönüştürebiliriz:

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

Bağlantıyı temizleme

Redis bağlantısıyla işiniz bittiğinde, öğesini kullanabilirsiniz DisposeConnectionMultiplexer. Bu işlem tüm bağlantıları kapatır ve sunucuyla iletişimi kapatır.

redisConnection.Dispose();
redisConnection = null;