التفاعل مع Azure Cache for Redis باستخدام .NET
عادة ما يستخدم تطبيق العميل مكتبة عميل لتشكيل الطلبات وتنفيذ الأوامر على ذاكرة التخزين المؤقت Redis. يمكنك الحصول على قائمة بمكتبات العملاء مباشرةً من صفحة عملاء Redis.
تنفيذ الأوامر على ذاكرة التخزين المُؤقت لـ Redis
عميل Redis عالي الأداء الشهير للغة .NET هو StackExchange.Redis. تتوفر الحزمة من خلال NuGet ويمكن إضافتها إلى التعليمات البرمجية .NET باستخدام سطر الأوامر أو بيئة التطوير المتكامل (IDE). فيما يلي أمثلة حول كيفية استخدام العميل.
الاتصال بذاكرة التخزين المؤقت لـ Redis باستخدام StackExchange.Redis
تذكّر أننا نستخدم عنوان المضيف ورقم المنفذ ومفتاح الوصول للاتصال بخادم Redis. يقدم Azure أيضا سلسلة الاتصال لبعض عملاء Redis الذين يجمعون هذه البيانات معا في سلسلة واحدة. يبدو شيئا مثل ما يلي (مع cache-name
الحقول و password-here
مليئة بالقيم الحقيقية):
[cache-name].redis.cache.windows.net:6380,password=[password-here],ssl=True,abortConnect=False
يمكنك تمرير هذه السلسلة إلى StackExchange.Redis لإنشاء اتصال الخادم.
لاحظ أن هناك معلمتين إضافيتين في النهاية:
- SSL- يضمن أن يتم تشفير الاتصالات.
- abortConnection- يسمح بإنشاء اتصال حتى إذا كان الخادم غير متوفر في تلك اللحظة.
توجد العديد من المعلمات الاختيارية الأخرى التي يمكنك إلحاقها إلى السلسلة لتكوين مكتبة العميل.
إنشاء اتصال
عنصر الاتصال الرئيسي في StackExchange.Redis هو StackExchange.Redis.ConnectionMultiplexer
الفئة. يلخص هذا العنصر عملية الاتصال إلى خادم Redis (أو مجموعة من الخوادم). تم تحسينه لإدارة الاتصالات بكفاءة بقصد الاحتفاظ به في أثناء الحاجة إلى الوصول إلى ذاكرة التخزين المؤقت.
تقوم بإنشاء ConnectionMultiplexer
مثيل باستخدام ConnectionMultiplexer.Connect
ثابت أوConnectionMultiplexer.ConnectAsync
أسلوب تمرير في سلسلة اتصال أو ConfigurationOptions
عنصر.
إليك مثال بسيط:
using StackExchange.Redis;
...
var connectionString = "[cache-name].redis.cache.windows.net:6380,password=[password-here],ssl=True,abortConnect=False";
var redisConnection = ConnectionMultiplexer.Connect(connectionString);
بمجرد الحصول على ConnectionMultiplexer
، توجد ثلاثة أمور أساسية قد ترغب في تنفيذها:
- الوصول إلى قاعدة بيانات Redis. هذا ما سنركّز عليه هنا.
- الاستفادة من ميزات الناشر/المشترك ل Redis. هذا خارج نطاق هذه الوحدة النمطية.
- الوصول إلى خادم فردي من أجل الصيانة أو المراقبة.
الوصول إلى قاعدة بيانات Redis
يتم تمثيل قاعدة بيانات Redis وفقًا IDatabase
للنوع. يمكنك إجراء استرداد واحد باستخدام GetDatabase()
الأسلوب:
IDatabase db = redisConnection.GetDatabase();
تلميح
العنصر الذي تم إرجاعه من GetDatabase
هو عنصر خفيف، ولا يحتاج إلى التخزين. يحتاج فقط ConnectionMultiplexer
إلى أن يبقى حيًّا
بمجرد أن يكون لديك IDatabase
عنصر، يمكنك تنفيذ أساليب التفاعل مع ذاكرة التخزين المُؤقت. تحتوي جميع الأساليب على إصدارات متزامنة وغير متزامنة تقوم بإرجاع Task
الكائنات لجعلها متوافقة async
مع الكلمات الأساسية و await
.
فيما يلي مثال على تخزين مفتاح/قيمة في ذاكرة التخزين المؤقت:
bool wasSet = db.StringSet("favorite:flavor", "i-love-rocky-road");
يعمل StringSet
الأسلوب على إرجاعbool
والذي يشير إلى ما إذا كانت القيمة قد تم تعيينها (true
) أم لا (false
). يمكننا بعد ذلك استرداد القيمة مع StringGet
الأسلوب:
string value = db.StringGet("favorite:flavor");
Console.WriteLine(value); // displays: ""i-love-rocky-road""
الحصول على القيم الثنائية وإعدادها
تذكّر أن مفاتيح Redis وقيمها آمنة ثنائيًا. يمكن استخدام تلك الأساليب ذاتها لتخزين البيانات الثنائية. توجد عوامل تحويل ضمنية للعمل مع byte[]
الأنواع حتى تتمكن من العمل مع البيانات بشكل طبيعي:
byte[] key = ...;
byte[] value = ...;
db.StringSet(key, value);
byte[] key = ...;
byte[] value = db.StringGet(key);
يمثل StackExchange.Redis المفاتيح باستخدام RedisKey
النوع. يوجد بهذه الفئة تحويلات ضمنية من وإلى string
مع السماح لكل من النص والمفاتيح byte[]
الثنائية باستخدامها دون أي تعقيد. تُمثّل القيم وفقًا للنوع RedisValue
. كما هو الحال مع RedisKey
، توجد تحويلات ضمنية في مكان يتيح لك تمرير string
أو byte[]
.
العمليات الأخرى المشتركة
IDatabase
تتضمن الواجهة عدة أساليب أخرى للعمل مع ذاكرة التخزين المُؤقت لـ Redis. توجد أساليب للعمل مع التجزئة والقوائم والمجموعات وكذلك المجموعات المُرتبة.
نعرض فيما يلي البعض الأكثر شيوعًا منها، والذي يعمل مع مفاتيح واحدة، يمكنك قراءة التعليمات البرمجية للمصدر الخاص بالواجهة لرؤية القائمة الكاملة.
الطريقة | الوصف |
---|---|
CreateBatch |
إنشاء مجموعة من العمليات التي ستُرسل إلى الخادم في شكل وحدة واحدة، ولكن ليس بالضرورة معالجتها في شكل وحدة. |
CreateTransaction |
إنشاء مجموعة من العمليات التي ستُرسل إلى الخادم في شكل وحدة واحدة ومعالجتها على الخادم في شكل وحدة واحدة. |
KeyDelete |
حذف المفتاح/ القيمة. |
KeyExists |
الإرجاع إذا كان المفتاح المُقدم موجودًا في ذاكرة التخزين المُؤقت. |
KeyExpire |
تعيين مدة البقاء (TTL) الخاصة بانتهاء الصلاحية على أحد المفاتيح. |
KeyRename |
إعادة تسمية المفتاح. |
KeyTimeToLive |
إرجاع مدة البقاء (TTL) للمفتاح. |
KeyType |
إرجاع تمثيل السلسلة من نوع القيمة المُخزنة في المفتاح. تشمل الأنواع المختلفة التي يمكن إرجاعها ما يلي: سلسلة وقائمة ومجموعة «zset» والتجزئة. |
تنفيذ أوامر أخرى
IDatabase
يحتوي الكائن على Execute
أسلوب و ExecuteAsync
الذي يمكن استخدامه لتمرير الأوامر النصية إلى خادم Redis. على سبيل المثال:
var result = db.Execute("ping");
Console.WriteLine(result.ToString()); // displays: "PONG"
ترجع Execute
الأساليب و ExecuteAsync
كائنا RedisResult
هو صاحب بيانات يتضمن خاصيتين:
Type
الذي يرجعstring
يشير إلى نوع النتيجة - "STRING" و"INTEGER" وما إلى ذلك.IsNull
قيمة صحيحة/ خاطئة للكشف عن متى تكون النتيجةnull
.
ومن ثم يمكنك استخدام ToString()
للحصول على قيمة RedisResult
الإرجاع الفعلي.
يمكنك استخدام Execute
لتنفيذ أي أوامر مدعومة- على سبيل المثال، يمكننا الحصول على كل العملاء المتصلين بذاكرة التخزين المُؤقت ("قائمة العملاء"):
var result = await db.ExecuteAsync("client", "list");
Console.WriteLine($"Type = {result.Type}\r\nResult = {result}");
هذا مخرج للعملاء المتصلين:
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
تخزين قيم أكثر تعقيدًا
يُعد Redis موجهًا للسلاسل الآمنة الثنائية، ولكن يمكنك التخزين المُؤقت بعيدًا عن الرسوم البيانية للعنصر من خلال وضعهم في تسلسل من أجل تنسيق نصي - عادة XML أو JSON. على سبيل المثال، ربما بالنسبة لإحصائياتنا، لدينا كائن GameStats
يبدو كما يلي:
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.Jsعلى المكتبة لتشغيل مثيل هذا العنصر في سلسلة:
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);
يمكننا استرداده وتحويله مرة أخرى إلى عنصر باستخدام عملية عكسية:
var result = db.StringGet("event:2019-local-game");
var stat = Newtonsoft.Json.JsonConvert.DeserializeObject<GameStat>(result.ToString());
Console.WriteLine(stat.Sport); // displays "Soccer"
تنظيف الاتصال
بمجرد الانتهاء من اتصال Redis، يمكنك Dispose
ConnectionMultiplexer
. يؤدي ذلك إلى إغلاق كافة الاتصالات وإيقاف الاتصال بالخادم.
redisConnection.Dispose();
redisConnection = null;