Redis#
إن Redis هو أحد أكثر مخازن بنى البيانات في الذاكرة شيوعًا، ويُستخدم عادةً للتخزين المؤقت أو كوسيط رسائل.
هذه المكتبة هي تكامل بين Vapor وRediStack، وهي المُشغّل الأساسي الذي يتواصل مع Redis.
ملاحظة
توفّر RediStack معظم قدرات Redis. نوصي بشدة بالإلمام بتوثيقها.
تُوفَّر الروابط حيثما كان ذلك مناسبًا.
الحزمة#
الخطوة الأولى لاستخدام Redis هي إضافته كتبعية إلى مشروعك في بيان حزمة Swift.
هذا المثال مخصص لحزمة موجودة مسبقًا. للمساعدة في بدء مشروع جديد، راجع دليل البدء الرئيسي.
dependencies: [
// ...
.package(url: "https://github.com/vapor/redis.git", from: "4.0.0")
]
// ...
targets: [
.target(name: "App", dependencies: [
// ...
.product(name: "Redis", package: "redis")
])
]
التهيئة#
يستخدم Vapor استراتيجية تجميع (pooling) لنسخ RedisConnection، وتوجد عدة خيارات لتهيئة الاتصالات الفردية وكذلك التجمّعات نفسها.
الحدّ الأدنى المطلوب لتهيئة Redis هو توفير عنوان URL للاتصال به:
let app = Application()
app.redis.configuration = try RedisConfiguration(hostname: "localhost")
تهيئة Redis#
توثيق واجهة برمجة التطبيقات:
RedisConfiguration
serverAddresses#
إذا كان لديك عدة نقاط نهاية لـ Redis، مثل عنقود من نسخ Redis، فستحتاج إلى إنشاء مجموعة [SocketAddress] لتمريرها في المُهيّئ بدلًا من ذلك.
الطريقة الأكثر شيوعًا لإنشاء SocketAddress هي باستخدام الدالة الساكنة makeAddressResolvingHost(_:port:).
let serverAddresses: [SocketAddress] = [
try .makeAddressResolvingHost("localhost", port: RedisConnection.Configuration.defaultPort)
]
بالنسبة لنقطة نهاية واحدة لـ Redis، قد يكون من الأسهل العمل مع المُهيّئات الميسّرة، إذ ستتولّى إنشاء SocketAddress نيابةً عنك:
password#
إذا كانت نسخة Redis الخاصة بك محمية بكلمة مرور، فستحتاج إلى تمريرها كمعامل password.
سيُصادَق على كل اتصال عند إنشائه باستخدام كلمة المرور.
database#
هذا هو فهرس قاعدة البيانات الذي ترغب في تحديده عند إنشاء كل اتصال.
يوفّر هذا عليك الحاجة إلى إرسال الأمر SELECT إلى Redis بنفسك.
تحذير
لا يُحافظ على تحديد قاعدة البيانات. كن حذرًا عند إرسال الأمر SELECT بنفسك.
خيارات تجمّع الاتصالات#
توثيق واجهة برمجة التطبيقات:
RedisConfiguration.PoolOptions
ملاحظة
تُبرز هنا الخيارات الأكثر تغييرًا شيوعًا فقط. للاطلاع على جميع الخيارات، راجع توثيق واجهة برمجة التطبيقات.
minimumConnectionCount#
هذه هي القيمة التي تحدّد عدد الاتصالات التي تريد أن يحافظ عليها كل تجمّع في جميع الأوقات.
إذا كانت قيمتك 0، فعند فقدان الاتصالات لأي سبب، لن يعيد التجمّع إنشاءها حتى تدعو الحاجة إليها.
يُعرف هذا باتصال “البدء البارد” (cold start)، وينطوي على بعض العبء الإضافي مقارنةً بالحفاظ على حدّ أدنى من عدد الاتصالات.
maximumConnectionCount#
يحدّد هذا الخيار سلوك كيفية الحفاظ على الحدّ الأقصى لعدد الاتصالات.
انظر أيضًا
راجع واجهة برمجة تطبيقات RedisConnectionPoolSize للإلمام بالخيارات المتاحة.
إرسال أمر#
يمكنك إرسال الأوامر باستخدام خاصية .redis على أي نسخة من Application أو Request، مما سيتيح لك الوصول إلى RedisClient.
يمتلك أي RedisClient عدة امتدادات لجميع أوامر Redis المتنوعة.
let value = try app.redis.get("my_key", as: String.self).wait()
print(value)
// Optional("my_value")
// or
let value = try await app.redis.get("my_key", as: String.self)
print(value)
// Optional("my_value")
الأوامر غير المدعومة#
إذا كانت RediStack لا تدعم أمرًا ما بدالة امتداد، فلا يزال بإمكانك إرساله يدويًا.
// each value after the command is the positional argument that Redis expects
try app.redis.send(command: "PING", with: ["hello"])
.map {
print($0)
}
.wait()
// "hello"
// or
let res = try await app.redis.send(command: "PING", with: ["hello"])
print(res)
// "hello"
وضع النشر/الاشتراك (Pub/Sub)#
يدعم Redis القدرة على الدخول في وضع “النشر/الاشتراك” (Pub/Sub) حيث يمكن لاتصال ما الاستماع إلى “قنوات” محددة وتشغيل إغلاقات (closures) محددة عندما تنشر القنوات المشترَك فيها “رسالة” (قيمة بيانات ما).
للاشتراك دورة حياة محددة:
subscribe: يُستدعى مرة واحدة عند بدء الاشتراك لأول مرة
message: يُستدعى 0 مرة أو أكثر عند نشر الرسائل إلى القنوات المشترَك فيها
unsubscribe: يُستدعى مرة واحدة عند انتهاء الاشتراك، إما بناءً على طلب أو بسبب فقدان الاتصال
عند إنشاء اشتراك، يجب أن توفّر على الأقل messageReceiver للتعامل مع جميع الرسائل التي تنشرها القناة المشترَك فيها.
يمكنك اختياريًا توفير RedisSubscriptionChangeHandler لكل من onSubscribe وonUnsubscribe للتعامل مع أحداث دورة الحياة الخاصة بكل منهما.
// creates 2 subscriptions, one for each given channel
app.redis.subscribe
to: "channel_1", "channel_2",
messageReceiver: { channel, message in
switch channel {
case "channel_1": // do something with the message
default: break
}
},
onUnsubscribe: { channel, subscriptionCount in
print("unsubscribed from \(channel)")
print("subscriptions remaining: \(subscriptionCount)")
}