معماری ذخیره سازی: Redis، Memcached
معماری ذخیره سازی: Redis، Memcached
1) چه زمانی و چرا کش
اهداف: کاهش زمان تاخیر، بارگیری DB/PSP/API های خارجی و کاهش قله.
لایه های حافظه پنهان اغلب چند سطحی هستند: درون فرایند (L1) → سطح سرویس (Redis/Memcached L2) → لبه/CDN. حافظه پنهان داخلی سرعت خواندن را افزایش می دهد، L2 برای خدمات رایج است، لبه برای محتوای عمومی است.
2) Redis در مقابل Memcached - مختصر
قانون: اگر به ساختارهای داده پیچیده، پایداری، pub/sub/streams/scripts نیاز دارید، Redis را بگیرید. اگر لایه کش فوق العاده ساده، سریع و ارزان KV بدون دوام Memcached باشد.
3) الگوهای ذخیره سازی
3. 1 کش کنار (تنبل)
این برنامه از حافظه پنهان → miss → خوانده شده از پایگاه داده → آن را در حافظه پنهان با TTL قرار می دهد.
کنترل TTL ساده، استقلال کش. − «طوفان» ممکن است در صورت عدم موفقیت.
3. 2 خوانده شده از طریق
مشتری/پروکسی خود را از مبدا در دست می گیرد و آن را در کش قرار می دهد.
منطق متمرکز. − زیرساخت پیچیده تر.
3. 3 نوشتن از طریق/نوشتن پشت
Write-through: نوشتن اول در حافظه پنهان، سپس در پایگاه داده.
Write-behind: نوشتن در صف، فلش ناهمزمان در پایگاه داده (از دست دادن بالقوه هنگام خراب شدن - شما نیاز به ورود به سیستم).
3. 4 دو لایه (L1 + L2)
L1 (در حال پردازش) با TTL کوتاه و نرم TTL، L2 (Redis/Memcached) - "حقیقت حافظه پنهان. "معلولیت از طریق میخانه/زیر.
4) TTL، طوفان و سازگاری
TTL-تنظیم نزدیک به فرکانس تغییر داده ها. برای کلید های داغ، استفاده از TTL (jitter) تصادفی: 'ttl = پایه ± رند (0.. پایه 0. 1) '- جریانهای خروجی همزمان را حذف می کند.
Dogpile (گله رعد آسا): محافظت از دست:- Singleflight: تنها یک فرآیند بیش از حد ارزش دارد (نگاه کنید به مثال Lua).
- Soft-TTL + تازه کردن پس زمینه: پس از 'soft _ ttl'، آن را قدیمی و به روز رسانی با پس زمینه.
- سمافور/قفل: 'کلید تنظیم: مقدار قفل NX PX = 2000'.
- Near-stale: 'stale-while-revalidate' برای API های پاسخ (بخش 8 را ببینید).
5) کلید، فضای نام، سریال سازی
5. 1 نام کلیدی
الگو: '{domain}: {entity}: {id}: {field}'
مثال ها:- 'کاربر: مشخصات: 42' کاتالوگ: محصول: 1001: v2 'psp: نرخ: 2025-11-03'
اضافه کردن یک نسخه طرح (': v2') - این تسهیل ناتوانی جمعی.
5. 2 Neimspaces از طریق «نسخه فضایی»
کلید «ns: catalog = 17» را نگه دارید. کلید های واقعی: 'کاتالوگ: 17: محصول: 1001'. برای ناتوانی دایرکتوری جهانی، به سادگی «ns: catalog» را افزایش دهید.
5. 3 سریال سازی/فشرده سازی
JSON راحت اما سنگین است. از MessagePack/CBOR استفاده کنید.
فعال کردن فشرده سازی (LZ4/ZSTD) برای بارهای بزرگ (> 1-2 KB). در Redis - در سمت مشتری.
6) کلید های داغ و sharding
کلید های داغ: مانیتور بالا N توسط ضربه/خانم/بایت. برای کلیدهای بسیار داغ:- تکرار الگوی خواندن: تکرار مقدار در چند کلید شارد 'hot: k: 1.. N، هنگام خواندن تصادفی را انتخاب کنید.
- L1 محلی: روند اشتراک معلولیت را در ذهن داشته باشید.
- Redis خوشه - بومی (16384 اسلات هش).
- Memcached یک هش سازگار با مشتری است.
- Hash-tag در Redis «{...}» یک شکاف را برای مجموعه ای از کلیدها برطرف می کند: 'user: {42}: profile' و 'user: {42}: limits' در همان کارت خواهند بود.
7) سیاست ها و اندازه های پیشگیرانه
Redis 'maxmemory-policy': 'allkeys-lru', 'volatile-lru', 'allkeys-lfu', 'noeviction' и т. д. برای کش، معمولا «allkeys-lru »/« allkeys-lfu».
Memcached - LRU на مورد اسلب.
اندازه و مقدار کلید: برای حداکثر اندازه مورد (Memcached به طور پیش فرض 1 MB، تنظیم دال) تماشا کنید.
بیش از حد حافظه باید به طور قابل پیش بینی کاهش یابد: نه «توهم» در مسیر فعال.
maxmemory 32gb maxmemory-policy allkeys-lfu hz 50 tcp-keepalive 60
8) الگوهای حفاظت از طوفان - کد
8. 1 Redis لوا تک پرواز (شبه)
lua
-- KEYS[1] = data_key, KEYS[2] = lock_key
-- ARGV[1] = now_ms, ARGV[2] = soft_ttl_ms, ARGV[3] = hard_ttl_ms, ARGV[4] = lock_ttl_ms local payload = redis. call("GET", KEYS[1])
if payload then local meta = redis. call("HGETALL", KEYS[1].. ":meta")
local last = tonumber(meta[2] or "0")
if tonumber(ARGV[1]) - last < tonumber(ARGV[2]) then return { "HIT", payload }
end if redis. call ("SET," KEYS [2], "1," "NX," "PX," ARGV [4]) then return {"REFRESH," payload} - one worker updates, the rest give stale end return {"STALE," payload}
end if redis. call("SET", KEYS[2], "1", "NX", "PX", ARGV[4]) then return { "MISS", nil }
end return { "BUSY", nil }
8. 2 گره. js cache-aside (ساده شده)
js const v = await redis. get(key);
if (v) return decode(v);
const lock = await redis. setNX(key+":lock", "1", { PX: 1500 });
if (lock) {
const fresh = await loadFromDB(id);
await redis. set(key, encode(fresh), { EX: ttl, NX: false });
await redis. del(key+":lock");
return fresh;
} else {
await sleep(60); // short backoff const retry = await redis. get (key) ;//give someone's already filled return decode (retry);
}
9) ناتوانی و انسجام
توسط رویداد: هنگام تغییر در پایگاه داده، انتشار 'pub/sub' رویداد 'نامعتبر است: {ns}: {id} → مشترکین کلید را حذف کنید.
توسط تایمر: TTL کوتاه برای اغلب تغییر داده ها.
نسخهبندی: کلیدهای «ns:» را ببینید.
صندوق پستی: تضمین تحویل معلولیت (رویداد ورود/موضوع، retrai).
عملیات حافظه پنهان idempotency: استفاده از 'SETXX/SETNX'، نسخه ('etag') و زمینه های هش برای افزایش.
10) تکرار، خوشه، شکست خورده
10. 1 مجدد
Sentinel: Master-Replica اتوماتیک شکست خورده (stateFUL IP/name).
خوشه: شاردینگ + شکست خودکار ؛ مشتریان باید از تغییر مسیرهای «MOVE/ASK» پشتیبانی کنند.
AOF/RDB: برای حافظه پنهان معمولا «appendfsync everysec»، بدون پایداری (مانند حافظه پنهان خالص) امکان پذیر است.
10. 2 حافظه ذخیره شده
از جعبه خارج نشود. قابلیت اطمینان - از طریق چند سرور shard + تکرار 'n' (سمت مشتری).
هنگامی که گره ها سقوط می کنند، افزایش خطا و «آموزش مجدد» حافظه پنهان وجود دارد.
10. ۳ K8s و شبکه سازی
Redis/Memcached از ایجاد مجدد مکرر غلاف ها خوشش نمی آید. استفاده از antipodes StatefulSet + AZ، ثابت PVC/POD IP.
تنظیم PodDisruptionBudget و TopologySpreadConstraints.
11) معاملات، اسکریپت ها و اتمی (Redis)
INCR/DECR، HINCRBY - شمارنده، سهمیه، محدودیت نرخ (فقط در نظر بگیرید باقی بماند).
MULTI/EXEC - مجموعه ای از دستورات اتمی.
Lua (EVAL) - خواندن، اصلاح، نوشتن بدون مسابقه.
خط لوله - RTT را کاهش می دهد (به خصوص در هاپ شبکه).
lua
-- KEYS[1]=bucket, ARGV[1]=capacity, ARGV[2]=refill_rate_per_sec, ARGV[3]=now_ms
-- Returns 1 if the token is issued, otherwise 0
12) صف، میخانه/زیر و جریان (Redis)
میخانه/زیر: ناتوانی، سیگنال. بدون صرفه جویی، فقط شنوندگان آنلاین.
جریان: تایید صف رویداد (ACK), گروه مصرف کننده, Retrai - دستی برای نوشتن پشت/طرفداران outs.
لیست ها ('BRPOP'): صف های ساده.
از Redis به عنوان «اتوبوس تک همه چیز» بدون پشتیبان استفاده نکنید - این یک حافظه پنهان/سریع است، نه کافکا.
13) امنیت و دسترسی
جداسازی شبکه/VPC، mTLS در سطح ورودی، ACL/کلمه عبور («requirepass »/ACL در Redis 6 +).
غیرفعال کردن دستورات خطرناک در Redis («CONFIG»، «FLUSHALL»، «KEYS») از طریق ACL.
برای Memcached - به رابط های عمومی گوش ندهید، «-U 0» (بدون UDP)، فقط شبکه های خصوصی.
PII را ذخیره نکنید در صورت لزوم - کوتاه TTL + رمزگذاری در سطح برنامه.
14) قابلیت مشاهده و نگهداری
معیارهای کلیدی:- نسبت ضربه/نسبت خانم (توسط فضای نام/مسیر).
- Latency p95/p99 'GET/SET/MGET' دستورات، وقفه.
- فرار и اشتباهات OOM
- تکرار تاخیر (Redis)، وضعیت خوشه، مهاجرت/حوادث rehash.
- کلید های Top-N توسط ترافیک/بایت (نمونه برداری).
- سیاهههای مربوط: دستورات آهسته («slowlog»)، خطاهای شبکه.
- داشبورد: عمومی (CPU/RAM/اتصالات)، دستورات، اسلات خوشه، نگهبان، عبور از صادر کنندگان Prometheus.
15) پیکربندی و استقرار - نمونه
15. 1 Redis Sentinel (قطعه)
port 6379 protected-mode yes appendonly yes appendfsync everysec maxmemory-policy allkeys-lfu
هتل است. conf ':
sentinel monitor m1 10. 0. 0. 11 6379 2 sentinel auth-pass m1 sentinel down-after-milliseconds m1 5000 sentinel failover-timeout m1 60000
15. 2 Redis خوشه (ارزش هلیم، ساده شده)
yaml cluster:
enabled: true nodes: 6 # 3 masters + 3 replicas persistence:
size: 100Gi resources:
requests: { cpu: "500m", memory: "2Gi" }
15. 3 حافظه پنهان (استقرار)
yaml containers:
- image: memcached:1. 6 args: ["-m", "32768", "-I", "2m", "-v", "-t", "8", "-o", "modern"]
ports: [{ containerPort: 11211 }]
15. 4 NGINX به عنوان خوانده شده از طریق پروکسی (حلقه API)
nginx proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=api:100m max_size=10g inactive=10m;
map $request_uri $cache_key { default "api:$request_uri"; }
location /api/ {
proxy_cache api;
proxy_cache_valid 200 1m;
proxy_cache_use_stale updating error timeout http_500 http_502 http_503 http_504;
proxy_cache_lock on; # singleflight на уровне NGINX proxy_cache_key $cache_key;
proxy_pass http://backend;
}
16) تست و دروازه
سرد/گرم/گرم پروفایل بار کش.
تزریق از دست می رود (پاکسازی جمعی) - منشاء باید «آموزش مجدد» مقاومت در برابر.
هشدارها: کاهش شدید در نسبت ضربه، افزایش در تاخیر خانم، بهمن از اخراج، افزایش در وقفه.
17) ضد الگوهای
ذخیره «حقیقت» در Redis بدون AOF/RDB و بدون افزونگی.
TTL = 0 (دائمی) برای دادههای فرار → ناسازگاری دائمی.
دسته جمعی 'کلید' در انگیختن.
عدم وجود لرزش/نرم-TTL → قطع همزمان و طوفان.
یک نمونه برای تمام دستورات بدون shardings/replicas.
استفاده از Memcached برای وظایف نیاز به اتمی/اسکریپت.
18) چک لیست پیاده سازی (0-45 روز)
0-10 روز
یک الگو انتخاب کنید (cache-aside + L1/L2)، کلیدها، TTL، فضاهای نام را توصیف کنید.
فعال کردن لرزش/نرم-TTL، تک پرواز ؛ هشدار پایه/داشبورد.
برای Redis - پیکربندی ACL، حالت محافظت شده، slowlog، سیاست حداکثر.
11-25 روز
تغییر به sharding (خوشه Redis یا هش مشتری)، کپی.
معلولیت از طریق نسخه میخانه/زیر و یا neimspace ؛ صندوق خروجی در پایگاه داده.
آزمونهای بار «بازآموزی» نهانگاه ؛ محدود کردن منشأ
26-45 روز
Autopromo/canary TTL، گرم کردن قبل از انتشار.
جریان برای نوشتن پشت/مونتاژ پس زمینه.
گزارش های هفتگی در مورد نسبت ضربه، کلید های بالا، هزینه حافظه.
19) معیارهای بلوغ
نسبت ضربه L2 ≥ 80٪ (آمار مربوط به مسیرها/فضاهای نام).
P95 GET <2-3 ms (in-DC)، <SLO origin را از دست می دهد.
0 طوفان در ناتوانی جمعی (اثبات شده توسط آزمون).
ناتوانی خودکار و نسخه nymspace.
Sharding/replication 1 شکست گره را بدون تخریب قابل ملاحظه ای پوشش می دهد.
20) نتیجه گیری
معماری حافظه پنهان قوی نظم و انضباط از کلید و TTL، حفاظت از طوفان، سستی مناسب، و پیشگیری قابل پیش بینی است. Redis می دهد معانی غنی، پشتکار و اتمی ؛ Memcached - حداکثر سادگی و سرعت. قابلیت مشاهده، ناتوانی رویداد، L1 + L2 را اضافه کنید و حافظه پنهان به یک شتاب دهنده پلت فرم تبدیل می شود، نه منبع قطره های تصادفی و اشکالات «عرفانی».