التخزين المؤقت في Go (Golang): Redis، التخزين في الذاكرة والحلول الأخرى
التخزين المؤقت هو أحد الاستراتيجيات الرئيسية لتحسين الأداء وتقليل الحمل على قواعد البيانات في تطبيقات Go. في هذه المقالة، سنستعرض الأساليب والمكتبات الأساسية لتنفيذ التخزين المؤقت: من الحلول البسيطة في الذاكرة إلى التخزين المؤقت الموزع باستخدام Redis. ستتعرف على متى تختار أي أداة وكيفية تنظيم التخزين المؤقت بشكل صحيح في مشاريع Go.
1. الإمكانيات المدمجة: map و sync.Map
أبسط طريقة للتخزين المؤقت في Go هي استخدام map عادية مع كائن مزامنة (mutex) أو sync.Map الآمنة للاستخدام المتزامن. هذه الأساليب مناسبة للمشاريع الصغيرة أو النماذج الأولية التي لا تتطلب سياسة معقدة لإبطال البيانات المخزنة.
مثال مع sync.Map:
package main
import ( "fmt" "sync")
type Cache struct { data sync.Map}
func (c *Cache) Set(key string, value interface{}) { c.data.Store(key, value)}
func (c *Cache) Get(key string) (interface{}, bool) { return c.data.Load(key)}
func main() { cache := &Cache{} cache.Set("user:1", "Alice") if val, ok := cache.Get("user:1"); ok { fmt.Println("Found:", val) }}الإيجابيات: البساطة، عدم وجود تبعيات.
السلبيات: لا يوجد TTL، لا تنظيف تلقائي، الذاكرة غير محدودة.
2. تخزين مؤقت في الذاكرة مع TTL: freecache
Freecache هي مكتبة سريعة للتخزين المؤقت في الذاكرة مع دعم TTL (وقت حياة السجل). تستخدم بنية مقسمة لتقليل عمليات القفل وإدارة الذاكرة بكفاءة.
التثبيت:
go get github.com/coocood/freecacheمثال على الاستخدام:
package main
import ( "fmt" "github.com/coocood/freecache")
func main() { // إنشاء ذاكرة تخزين مؤقت بحجم 100 ميجابايت cache := freecache.NewCache(100 * 1024 * 1024)
// تعيين قيمة مع TTL لمدة 10 ثوانٍ cache.Set([]byte("mykey"), []byte("myvalue"), 10)
// الحصول على القيمة if val, err := cache.Get([]byte("mykey")); err == nil { fmt.Println("Value:", string(val)) } else { fmt.Println("Key not found or expired") }}الإيجابيات: تنظيف تلقائي بناءً على TTL، استهلاك منخفض لوحدة المعالجة المركزية، دعم كميات كبيرة من البيانات.
السلبيات: مخصص لعملية واحدة فقط (غير موزع).
3. BigCache — بديل لـ freecache
BigCache هي مكتبة أخرى شائعة للتخزين المؤقت في الذاكرة، محسّنة لتخزين عدد كبير من السجلات (الملايين) مع الحد الأدنى من وقت الوصول. تدعم أيضاً TTL والإخلاء التلقائي للبيانات القديمة.
مثال:
package main
import ( "fmt" "github.com/allegro/bigcache/v3" "time")
func main() { config := bigcache.Config{ Shards: 1024, LifeWindow: 10 * time.Minute, CleanWindow: 5 * time.Minute, MaxEntriesInWindow: 1000 * 10 * 60, MaxEntrySize: 500, Verbose: true, }
cache, _ := bigcache.NewBigCache(config) cache.Set("mykey", []byte("bigcache value")) val, _ := cache.Get("mykey") fmt.Println(string(val))}الإيجابيات: أداء عالٍ مع عدد كبير من المفاتيح، تكوين مرن.
السلبيات: مثل freecache — تخزين مؤقت محلي.
4. التخزين المؤقت الموزع مع Redis و go-redis
للأنظمة الموزعة حيث تحتاج مثيلات متعددة من التطبيق إلى تخزين مؤقت موحد، يُستخدم Redis. العميل الأكثر شيوعاً لـ Go هو go-redis (سابقاً go-redis/redis).
التثبيت:
go get github.com/redis/go-redis/v9مثال على التخزين المؤقت الأساسي:
أيضاً في المكتبة
توليد PDF في Swift: إنشاء المستندات لنظامي iOS وmacOS
توليد PDF في JavaScript (Node.js): المكتبات والأدوات
العمل مع التواريخ في Kotlin: المكتبات والأدوات (Kotlinx-datetime, Joda-Time, java.time)
Thymeleaf في Java: دليل شامل مع أمثلة تطبيقية