التخزين المؤقت في Go (Golang): Redis، التخزين المؤقت الجماعي والتخزين المؤقت في الذاكرة

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

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

ابدأ الدورة

التخزين المؤقت في Go (Golang): Redis وحلول أخرى



التخزين المؤقت هو أحد الأدوات الرئيسية لتحسين أداء تطبيقات Go. فهو يسمح بتقليل وقت الاستجابة، وتخفيف الحمل على قواعد البيانات وواجهات API الخارجية. في هذه المقالة، سنستعرض الأساليب الرئيسية للتخزين المؤقت في Go: استخدام Redis كمخزن خارجي، التخزين المؤقت المدمج في الذاكرة، والتخزين المؤقت الجماعي باستخدام مكتبة groupcache.



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

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

  • تقليل التأخير في الاستعلامات المتكررة.
  • تقليل الحمل على قواعد البيانات وواجهات API الخارجية.
  • زيادة سعة الخادم.
  • تخفيف الأحمال الذروة.


2. Redis — التخزين المؤقت الموزع

Redis هو الحل الأكثر شيوعًا للتخزين المؤقت الخارجي في Go. يعمل كمخزن في الذاكرة مع دعم TTL، والثبات، وهياكل البيانات المعقدة.



ربط Redis في Go

للعمل مع Redis في Go، غالبًا ما تُستخدم مكتبة go-redis. التثبيت:

go get github.com/redis/go-redis/v9


مثال: تخزين مؤقت بسيط مع TTL

package main

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

var ctx = context.Background()

func main() { rdb := redis.NewClient(&redis.Options{ Addr: "localhost:6379", })

// تعيين قيمة مع TTL لمدة 10 ثوانٍ err := rdb.Set(ctx, "user:42", `{"name":"Alice"}`, 10*time.Second).Err() if err != nil { panic(err) }

// الحصول على القيمة val, err := rdb.Get(ctx, "user:42").Result() if err != nil { fmt.Println("خطأ في التخزين المؤقت") } else { fmt.Println("إصابة التخزين المؤقت:", val) }}


استراتيجيات إبطال التخزين المؤقت في Redis

  • TTL (Time To Live) — الحذف التلقائي بعد انتهاء الوقت.
  • الإبطال الكسول (Lazy-invalidation) — مسح التخزين المؤقت عند تحديث البيانات.
  • الحذف حسب المفتاح — استدعاء DEL لمفتاح معين.
  • نمط "Cache-Aside" — يدير التطبيق التخزين المؤقت بنفسه: يتحقق أولاً من Redis، وعند الخطأ يقوم بتحميل البيانات من قاعدة البيانات ويحفظها في التخزين المؤقت.


3. التخزين المؤقت في الذاكرة في Go

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



تخزين مؤقت بسيط في الذاكرة باستخدام sync.Map

package main

import ( "fmt" "sync" "time")

type CacheItem struct { Value interface{} Expiration int64}

type Cache struct { items sync.Map}

func (c *Cache) Set(key string, value interface{}, ttl time.Duration) { c.items.Store(key, CacheItem{ Value: value, Expiration: time.Now().Add(ttl).UnixNano(), })}

func (c *Cache) Get(key string) (interface{}, bool) { item, found := c.items.Load(key) if !found { return nil, false } cacheItem := item.(CacheItem) if time.Now().UnixNano() > cacheItem.Expiration { c.items.Delete(key) return nil, false } return cacheItem.Value, true}

func main() { cache := &Cache{} cache.Set("key1", "value1", 5*time.Second) val, ok := cache.Get("key1") if ok { fmt.Println("تم العثور على:", val) }}


مكتبة freecache

freecache — مكتبة عالية الأداء للتخزين المؤقت في الذاكرة مع دعم TTL واستهلاك منخفض للذاكرة. التثبيت:

go get github.com/coocood/freecache
cache := freecache.NewCache(100 * 1024 * 1024) // 100 MBcache.Set([]by                    

توصيات