redis methods
INCR
به یک کلید که مقدارش عدد هست یکی پلاس پلاس میکنه ، مثلا تعداد بازدید سایت و یا تعداد رکوعست یه یوزر
n, err := rdb.Incr(ctx, "requests:page_view").Result()
INCRBY
دقیقا مثل بالایی تنها تعداد دلخواه می افزاید
n, err := rdb.IncrBy(ctx, "user:123:score", 5).Result()
EXPIRE
می توان زمان انقضا ست کرد
ok, err := rdb.Expire(ctx, "session:abc", time.Hour).Result()
TTL
زمان باقی مونده برای انقضا رو میده
dur, err := rdb.TTL(ctx, "session:abc").Result() // dur can be -2 (no key) or -1 (no expire) or >=0
HSET / HGET
به صورت کلی نامی که می زاریم بهتره گویای همه چیز باشه و اگر خیلی بلند شد ، بهتره اون رو هش کنیم تا راحت تر فچ بشه
_, _ = rdb.HSet(ctx, "user:123", "name", "Alice", "email", "a@x.com").Result()
name, _ := rdb.HGet(ctx, "user:123", "name").Result()
m, _ := rdb.HGetAll(ctx, "user:123").Result() // map[string]stringtermonology
Cache-Aside
تقریبا همه از این پترن استفاده میکنیم ، به پترنی که در کنار سورس اف تورف از یه کش استفاده کنه و به این صورت که اول کش رو ببینیم اگه نبود از منبع اصلی بگیریم و تو کش بزاریم
- کی باید از کش استفاده کنیم :
زمانی که حجم رید بالا باشه ، میشه نتیجه گرفت که میزان تغییرات کمتر از خواندن است
- کجا نباید استفاده شه؟
زمانی که بیشتر حجم رایت هست ، زمانی که داده به شدت حیاطی است و نباید inconsistancy رخ بده
Cache Decorator (Repo Layer)
یکی از معماری ها و راه های ایمپلمنت کش است و به این صورت که ابتدا لایه ی ریپوزیتوری رو کامل میکنیم ، سپس یه لایه بالاتر از کش استفاده میکنیم و در صورتی که در کش نبود ، از ریپو استفاده میکنیم ، یا اگر Write بود کلید کش رو حذف میکنیم. توجه شود در همین لایه کلید های invalid رو هندل میکنیم به این صورت که اگر در ریپو آپدیت شد ، از کش حذف می کنیم
Observer / Event-Based
cache stampede
فرض کنید همزمان چندین درخواست به کش می رود و کلید مشخصی میخوان و کش در اون لحظه نداره یا واقعا نداره و یا منقضی شده، سپس درخواست ها به سمت منبع اصلی میره در حالی که درخواست ها تکراری هستند
- singleflight
- lock/promise in Redis
- Cache warming / proactive refresh
singleflight
ابزار اینترنال گولنگ برای جلوگیری از کش استمپد
گاهی کلی درخواست تکراری و در زمان خیلی محدود به دیتابیس و یا حتی ردیس و یا تردپارتی میره که داده ی تکراری رو فچ کنه و مطمئنیم تو اون بازه پاسخ ها تکراری هستند ، در این صورت می تونیم به جای استفاده از کش و مدیریت کردن آن از پکیج زیر استفاده کنیم . توضیحات بیشتر توی قسمت سینک گولنگ
Distributed lock/promise in Redis
https://github.com/go-redsync/redsync
TTL jitter
گاهی برنامه زمان اگسپایر رو جوری ست می کنه که در یک زمان نزدیک بیشتر کلید ها منقضی میشن و در نتیجه درخاست های زیادی همزمان به منبع اصلی میره ، برای جلو گیری از این ، عمر کلید های کش رو با متغییر بدیم :
ttl := 60*time.Second + time.Duration(rand.Intn(10))*time.Second
Cache warming / proactive refresh
یه سری داده ها مطمعنیم که خیلی استفاده میشن پس بدون اینکه منتظر باشیم اکسپایر شن ، خودمون پیش دستی می کنیم و اون ها رو رفرش می کنیم
Instrumentation & alerting & Stats
این که آمار داشته باشیم ، ردیس به صورت پیش فرض آمار نمیده و میشه توی پرومتيوس ریخت
- cache_hits
چه تعداد درخواست میره سمت ردیس
- cache_misses
چه تعداد درخواست تو ردیس نیست و میره منبع اصلی
- inflight_requests
چه تعداد درخواست تکراری می ره سمت منبع - رعایت نکردن سینگل فلایت -
- waiters
چه تعداد منتظر و لاک هستن
Key naming
بهترین نام گذاری
service:entity:region:id
مثال :
market:book:BTC-ETH:level