التخزين المؤقت في Kotlin: Redis وMemcached والحلول المضمنة

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

مقدمة: لماذا يعتبر التخزين المؤقت أمرًا حاسمًا لتطبيقات Kotlin عالية التحميل

\n

في التطوير الحديث باستخدام Kotlin، خاصة في مجال الخدمات المصغرة وتطبيقات الواجهة الخلفية، يُعد الأداء مطلبًا رئيسيًا. يسمح التخزين المؤقت بتقليل وقت الاستجابة بشكل جذري، وتخفيف الحمل على قواعد البيانات وواجهات API الخارجية، بالإضافة إلى تقليل تكاليف البنية التحتية. على المستوى المتقدم، لا يجب على المطور مجرد تطبيق التخزين المؤقت، بل اختيار الاستراتيجية المثلى بناءً على السيناريو: التخزين المؤقت الموزع (Redis, Memcached) أو الحلول في الذاكرة (Caffeine, Guava). في هذه المقالة، سنستعرض التقنيات المتقدمة للعمل مع التخزين المؤقت في Kotlin، بما في ذلك التكامل مع coroutines، وضبط TTL، وأنماط الإبطال.

\n\n

1. Redis في Kotlin: العمل المتقدم مع Lettuce وRedisson

\n

1.1. التخزين المؤقت غير المتزامن مع Lettuce

\n

مكتبة Lettuce هي المعيار الفعلي للعمل مع Redis من Kotlin بفضل دعمها الكامل للتدفقات التفاعلية وغير المتزامنة. على المستوى المتقدم، من المهم استخدام واجهة Suspendable عبر coroutines.

\n
import io.lettuce.core.RedisClient\nimport io.lettuce.core.api.coroutines\nimport kotlinx.coroutines.flow.Flow\nimport kotlinx.coroutines.flow.map\n\nclass RedisCache(private val client: RedisClient) {\n    private val connection = client.connect()\n    private val commands = connection.coroutines() // واجهة برمجة تطبيقات coroutines\n\n    suspend fun get(key: String): String? = commands.get(key)\n\n    suspend fun set(key: String, value: String, ttlSeconds: Long = 60) {\n        commands.setex(key, ttlSeconds, value)\n    }\n\n    suspend fun invalidate(pattern: String) {\n        val keys = commands.keys(pattern)\n        if (keys.isNotEmpty()) commands.del(*keys.toTypedArray())\n    }\n}
\n

نصيحة متقدمة: استخدم SCAN بدلاً من KEYS في بيئة الإنتاج لتجنب حظر Redis على مجموعات البيانات الكبيرة.

\n\n

1.2. Redisson: الأقفال الموزعة والتخزين المؤقت بطبقة محلية

\n

يقدم Redisson واجهة برمجة تطبيقات ذات مستوى أعلى، بما في ذلك الأقفال الموزعة والتخزين المؤقت ثنائي المستوى (Redis + Caffeine محلي). هذا مثالي للسيناريوهات التي يكون فيها اتساق البيانات أمرًا بالغ الأهمية.

\n
import org.redisson.Redisson\nimport org.redisson.config.Config\nimport org.redisson.api.RLocalCachedMap\n\nclass RedissonCache {\n    private val config = Config().apply {\n        useSingleServer().address = "redis://localhost:6379"\n    }\n    private val client = Redisson.create(config)\n\n    fun getCachedMap<K, V>(name: String): RLocalCachedMap<K, V> {\n        return client.getLocalCachedMap(name, LocalCachedMapOptions.defaults())\n    }\n}
\n\n

2. Memcached في Kotlin: بروتوكول خفيف وسرعة عالية

\n

2.1. الاتصال عبر xmemcached

\n

يظل Memcached خيارًا ممتازًا للتخزين المؤقت البسيط للمفتاح والقيمة دون الحاجة إلى الثبات. توفر مكتبة xmemcached أداءً عاليًا ودعمًا للبروتوكول النصي/الثنائي.

\n
import net.rubyeye.xmemcached.MemcachedClientBuilder\nimport net.rubyeye.xmemcached.XMemcachedClient\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.withContext\n\nclass MemcachedCache(private val client: XMemcachedClient) {\n    suspend fun get(key: String): Any? = withContext(Dispatchers.IO) {\n        client.get(key)\n    }\n\n    suspend fun set(key: String, value: Any, ttl: Int = 3600) = withContext(Dispatchers.IO) {\n        client.set(key, ttl, value)\n    }\n}
\n

هام: لا يدعم Memcached هياكل البيانات المعقدة، لذا استخدم Redis أو التسلسل إلى JSON للقوائم أو التجزئات.

\n\n

2.2. التحسين باستخدام البروتوكول الثنائي

\n

على المستوى المتقدم، قم بتفعيل البروتوكول الثنائي لتقليل النفقات العامة لتحليل الأوامر:

\n
val builder = Memcach                

المدونات

توصيات الكتب