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]string

termonology

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