التخزين المؤقت في Go: Redis وMemcached والحلول المدمجة

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

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

ابدأ الدورة

التخزين المؤقت في Go: Redis وMemcached والحلول المدمجة



التخزين المؤقت هو أحد الأدوات الرئيسية لتحسين أداء تطبيقات الويب والخدمات المصغرة. في Go (Golang) توجد عدة طرق: من هياكل البيانات المدمجة البسيطة إلى الأنظمة الموزعة القوية مثل Redis وMemcached. في هذه المقالة سنستعرض الخيارات الرئيسية للتخزين المؤقت، ومزاياها وعيوبها، مع تقديم أمثلة عملية على الكود.



لماذا نحتاج التخزين المؤقت في Go؟

تشتهر Go بسرعتها وكفاءتها، ولكن حتى فيها توجد غالباً نقاط اختناق: استعلامات بطيئة لقاعدة البيانات، واجهات برمجة تطبيقات خارجية، أو عمليات حسابية ثقيلة. التخزين المؤقت يتيح:

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

يعتمد اختيار الحل المناسب على بنية التطبيق: تطبيق متكامل أو خدمات مصغرة، متطلبات تناسق البيانات، حجم التخزين المؤقت والميزانية.



التخزين المؤقت المدمج في Go

للسيناريوهات البسيطة (مثل تخزين البيانات مؤقتاً ضمن عملية واحدة) تناسب الأدوات المدمجة في Go. لا تتطلب تثبيت خدمات خارجية وهي مثالية للتطبيقات الصغيرة.



1. sync.Map

sync.Map هي خريطة آمنة للاستخدام المتزامن من المكتبة القياسية لـ Go. مناسبة للتخزين المؤقت الذي نادراً ما يتم تحديثه ويُقرأ بكثرة. مثال:

package main

import ( "fmt" "sync")

func main() { var cache sync.Map

// حفظ البيانات cache.Store("user_1", "Alice") cache.Store("user_2", "Bob")

// قراءة البيانات if val, ok := cache.Load("user_1"); ok { fmt.Println("Found:", val) }

// حذف cache.Delete("user_2")}

المزايا: البساطة، لا تبعيات خارجية، آمن للاستخدام المتزامن. العيوب: لا يوجد TTL (مدة الصلاحية)، لا تنظيف تلقائي، مقيد بعملية واحدة.



2. حزمة go-cache

المكتبة الشهيرة github.com/patrickmn/go-cache تضيف دعم TTL والتنظيف التلقائي. مثال:

package main

import ( "fmt" "time" "github.com/patrickmn/go-cache")

func main() { // إنشاء تخزين مؤقت بمدة صلاحية 5 دقائق وتنظيف كل 10 دقائق c := cache.New(5*time.Minute, 10*time.Minute)

// حفظ مع TTL c.Set("session_token", "abc123", cache.DefaultExpiration)

// استرجاع token, found := c.Get("session_token") if found { fmt.Println("Token:", token) }

// حذف c.Delete("session_token")}

المزايا: TTL، سهولة التكامل، تنظيف تلقائي. العيوب: البيانات مخزنة في ذاكرة عملية واحدة، غير مناسبة للأنظمة الموزعة.



Redis: التخزين المؤقت الموزع لـ Go

Redis هو الحل الأكثر شيوعاً للتخزين المؤقت في Go. يعمل كخادم منفصل، ويدعم هياكل بيانات معقدة (سلاسل، تجزئات، قوائم، مجموعات) وله دعم ممتاز في Go عبر برنامج التشغيل go-redis.



الاتصال والعمليات الأساسية

package main

import ( "context" "fmt" "github.com/redis/go-redis/v9")

func main() { ctx := context.Background()

// الاتصال بـ Redis rdb := redis.NewClient(&redis.Options{ Addr: "localhost:6379", Password: "", // بدون كلمة مرور DB: 0, })

// حفظ سلسلة مع TTL (ساعة واحدة) err := rdb.Set(ctx, "key", "value", 3600*time.Second).Err() if err != nil { panic(err) }

// قراءة val, err := rdb.Get(ctx, "key").Result() if err != nil { fmt.Println("Key not found") } else { fmt.Println("Value:", val) }

// حذف rdb.Del(ctx, "key")}

المدونات

توصيات الكتب