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

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

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

ابدأ الدورة

التخزين المؤقت في Rust: Redis وحلول فعالة أخرى



في التطوير الحديث عالي التحميل بلغة Rust، يلعب التخزين المؤقت دورًا رئيسيًا. فهو يسمح بتقليل الحمل على قواعد البيانات، وتسريع استجابات API، وتحسين العمل مع العمليات الحسابية المكلفة. في هذه المقالة، سنستعرض المكتبات الرئيسية للتخزين المؤقت في نظام Rust البيئي: من Redis القوي إلى الحلول خفيفة الوزن في الذاكرة.



1. Redis عبر الكريت redis-rs



redis-rs هي المكتبة الرئيسية والأكثر نضجًا للعمل مع Redis في Rust. وهي تدعم العمليات غير المتزامنة (عبر tokio أو async-std)، والتجميع (clustering)، و pub/sub، وجميع أنواع بيانات Redis الشائعة.



التثبيت

[dependencies]redis = { version = "0.25", features = ["tokio-comp"] }tokio = { version = "1", features = ["full"] }


مثال أساسي: تخزين مؤقت للسلاسل النصية

use redis::AsyncCommands;

#[tokio::main]async fn main() -> redis::RedisResult<()> { let client = redis::Client::open("redis://127.0.0.1:6379/")?; let mut con = client.get_multiplexed_async_connection().await?;

// تعيين ذاكرة تخزين مؤقت مع TTL لمدة 60 ثانية let _: () = con.set_ex("user:123", "{\\"name\\":\\"Alice\\"}", 60).await?;

// الحصول على القيمة let cached: String = con.get("user:123").await?; println!("البيانات المخزنة مؤقتًا: {}", cached);

// التحقق من وجود المفتاح let exists: bool = con.exists("user:123").await?; println!("المفتاح موجود: {}", exists);

Ok(())}


تسلسل الهياكل المعقدة

للتخزين المؤقت لهياكل البيانات، استخدم serde مع redis:

use serde::{Serialize, Deserialize};use redis::AsyncCommands;

#[derive(Debug, Serialize, Deserialize)]struct User { id: u32, name: String, email: String,}

async fn cache_user(con: &mut redis::aio::MultiplexedConnection, user: &User) { let json = serde_json::to_string(user).unwrap(); let _: () = con.set_ex(format!("user:{}", user.id), json, 300).await.unwrap();}

async fn get_cached_user(con: &mut redis::aio::MultiplexedConnection, id: u32) -> Option<User> { let json: Option<String> = con.get(format!("user:{}", id)).await.unwrap(); json.and_then(|data| serde_json::from_str(&data).ok())}


2. التخزين المؤقت في الذاكرة: الكريت moka



Moka هي مكتبة عالية الأداء للتخزين المؤقت في الذاكرة، مستوحاة من Caffeine (Java). وهي مثالية للسيناريوهات التي لا تتطلب خادمًا خارجيًا، بل تحتاج إلى أقصى سرعة.



ميزات moka:

  • الإزالة التلقائية بناءً على الوقت (TTL, TTI) والحجم
  • المزامنة غير المتزامنة (التحديث في الخلفية)
  • آمنة للاستخدام متعدد الخيوط (Arc + RwLock)
  • دعم سياسات الوزن (weighted cache)


مثال: ذاكرة تخزين مؤقت مع TTL وحد للحجم

use moka::sync::Cache;use std::time::Duration;

fn main() { // إنشاء ذاكرة تخزين مؤقت بسعة 1000 عنصر مع TTL لمدة 10 دقائق let cache: Cache<String, String> = Cache::builder() .max_capacity(1000) .time_to_live(Duration::from_secs(600)) .build();

// الإدراج والاسترجاع cache.insert("key1".to_string(), "value1".to_string()); if let Some(v) = cache.get("key1") { println!("القيمة: {}", v); }}


النسخة غير المتزامنة (moka::future::Cache)

use moka::future::Cache;

#[tokio::main]async fn main() { let cache: Cache<u64, String> = Cache::new(10_000);

// إدراج غير متزامن cache.insert(42, "Hello async".to_string()).await;

// استرجاع غير متزامن if let Some(val) = cache.get(&42).await { println!("{}", val); }}


3. التخزين المؤقت التصريحي: الكريت <

توصيات