کش چیست؟ معماری Cache از Browser تا Application

Cache پاسخ اشتباه را هم می‌تواند بسیار سریع تحویل دهد. اگر Key دو کاربر را یکی بداند، داده شخصی Share می‌شود؛ اگر Invalidation جا بماند، قیمت یا خبر قدیمی می‌ماند؛ و اگر همه Entryها هم‌زمان منقضی شوند، Origin زیر موج بازسازی می‌رود. بنابراین «کش چیست» فقط پرسش سرعت نیست؛ پرسش هویت پاسخ، تازگی، سازگاری، تاب‌آوری و شواهد صحت است.

در این راهنما Cache را از Browser و CDN تا API، Application و Redis به‌صورت یک سیستم تصمیم بررسی می‌کنیم. اگر هدف شما تنظیم WP Rocket، Object Cache، استثنای Checkout یا رفع نمایش نسخه قدیمی در WordPress است، راهنمای اجرایی کش وردپرس را بخوانید؛ این مقاله مرجع معماری عمومی وب است.

پاسخ کوتاه: کش چیست؟

Cache یک نسخه موقت و قابل‌بازسازی از Response یا نتیجه پردازش را در لایه‌ای نگه می‌دارد که استفاده از آن از تولید دوباره کم‌هزینه‌تر است. هنگام Request بعدی، سیستم با Cache key دنبال نسخه مناسب می‌گردد؛ اگر Entry قابل‌استفاده باشد HIT، اگر نباشد MISS، اگر از Freshness گذشته باشد Stale و اگر Rule عمداً Cache را کنار بزند BYPASS رخ می‌دهد.

اصلمعناپیامد طراحی
CopyCache نسخه اصلی نیستحذف آن نباید داده تجاری را نابود کند
Identityفقط Requestهای هم‌ارز Share می‌شوندCache key بخشی از مدل داده است
Bounded stalenessکهنگی باید حد داشته باشدTTL تنها کنترل نیست؛ Event هم لازم است
RegenerationMISS هزینه داردOrigin و Stampede باید طراحی شوند
EvidenceHIT به معنی صحت نیستHeader، Version و Source parity لازم‌اند

Cache با Storage، Session، Queue و Backup فرق دارد

جزءوظیفهاگر حذف شودنمونه
Cacheکاهش هزینه تکراربا هزینه بیشتر بازسازی شودHTML، Query result
Primary storageحقیقت پایداراز دست رفتن داده رخ می‌دهدOrder database
SessionState Journey/Identityکاربر Logout یا Journey خراب می‌شودCart session
Queueکارهای در انتظارJob گم یا تکرار می‌شودارسال ایمیل/پردازش
Backupبازیابی پس از خرابیRecovery ممکن نیستSnapshot دیتابیس

یک فناوری مانند Redis می‌تواند برای چند نقش استفاده شود، اما Persistence، Eviction، Isolation و Recovery آن نقش‌ها یکسان نیست. «پاک‌کردن Redis» بدون دانستن Scope ممکن است Cache، Session یا Queue برنامه دیگری را هم متاثر کند.

کش چه زمانی ارزش دارد؟

نامزد مناسب Cache معمولاً چهار ویژگی دارد: Read تکراری، هزینه تولید قابل‌توجه، خروجی نسبتاً پایدار و تحمل مشخص برای Staleness. Cache همیشه انتخاب درست نیست.

سیگنالCache محتمل استCache پرریسک/کم‌ارزش است
Reuseهمان نتیجه بارها خوانده می‌شودهر Request تقریباً یکتا است
Generation costDB/API/Render گران استساخت نتیجه از Lookup Cache ارزان‌تر است
Change rateتغییر قابل پیش‌بینی/رویداددار استداده لحظه‌ای و پرریسک است
Correctness impactکهنگی محدود قابل‌قبول استBalance/Payment/Permission باید جاری باشد
Working setبخش پرتکرار در Memory می‌گنجدCardinality بالا و Reuse پایین است
OperationsOwner/Monitor/Invalidation داریدهیچ‌کس Rule و Incident را مالک نیست

بهبود باید نسبت به TCO سنجیده شود: Latency و Origin load کمتر در برابر Memory، Complexity، Invalidation، Security review، Testing و Incident cost. برای اتصال Performance به Journey و Outcome، چارچوب سرعت سایت و اثر تجاری را ببینید.

معماری لایه‌ای Cache در وب

لایهچه چیزی Cache می‌شود؟نزدیک بهKey/PolicyFailure نمونه
Browser HTTP cacheResponse/AssetUserURL + HTTP semanticsAsset قدیمی
Service Worker/Cache APIResponse طبق کد ClientUser/Appمنطق برنامهOffline shell ناسازگار
CDN/EdgeAsset، HTML یا API عمومیUser regionEdge rule/HTTPPoP قدیمی یا Key اشتباه
Reverse proxyResponse ApplicationOriginVCL/Nginx/Host ruleCookie/Route bypass ناقص
Full-page/FragmentHTML یا بخش TemplateApplicationPage/Fragment identityPersonalization مشترک
API gatewayEndpoint responseService boundaryMethod/Path/Query/AuthScope/Permission غلط
Application/ObjectEntity/ComputationCodeEntity/version/tenantStale object
Database/resultPlan/Page/Query resultData sourceDB-specificQuery بد پنهان می‌شود
DNSName→recordResolverName/type/classCutover دیر همگرا

هر Layer مستقل Freshness و Purge دارد. کاهش TTL مرورگر Edge را پاک نمی‌کند؛ Purge CDN Object cache برنامه را تازه نمی‌کند؛ و پاک‌سازی Plugin DNS resolver را تغییر نمی‌دهد.

چرخه تصمیم: Request تا Response

  1. Eligibility: Method، Status، Authentication و Rule اجازه Storage می‌دهند؟
  2. Selection: Cache key و Vary کدام Response ذخیره‌شده را انتخاب می‌کنند؟
  3. Freshness: Age هنوز در Freshness lifetime است؟
  4. Reuse: Request directive و Policy اجازه استفاده مستقیم می‌دهند؟
  5. Validation: Entry stale با Origin و Validator تازه می‌شود؟
  6. Forward/Generate: MISS/BYPASS به Layer بعد یا Origin می‌رود؟
  7. Store: Response جدید با Metadata و TTL ذخیره می‌شود؟
  8. Invalidate/Evict: Event، Expiry یا فشار Memory Entry را کنار می‌زند؟

RFC ۹۱۱۱ درباره HTTP Caching مرجع هنجاری رفتار Cacheهای HTTP است. Cache برنامه یا Redis الزاماً همان Semantics را ندارد؛ قرارداد آن باید جدا تعریف شود.

قرارداد Cache: تصمیم را قابل‌اجرا کنید

فیلدپرسششاهد
ArtifactResponse، Fragment، Entity یا Query چیست؟Content/data model
Source of truthنسخه معتبر کجاست؟DB/API owner
Eligibilityچه Method/Status/Persona قابل Cache است؟Route policy
Identityچه اجزایی Key را می‌سازند؟Key schema
Freshness budgetحداکثر کهنگی مجاز چیست؟Risk/SLO
Invalidationچه Eventی چه Dependencyهایی را پاک می‌کند؟Event/graph
Failure modeStale، Fail-open یا Fail-closed؟Runbook/test
ObservabilityHIT/MISS/Age/Version چگونه دیده می‌شود؟Header/log/metric
Ownerچه کسی Rule، Change و Incident را پاسخ می‌دهد؟RACI/on-call

Cache key هویت پاسخ است

Key بیش‌ازحد کلی Under-partition می‌کند: Requestهای متفاوت یک Response می‌گیرند. Key بیش‌ازحد جزئی Over-partition می‌کند: Entryهای فراوان با Reuse کم ساخته می‌شوند. هر دو خطا هزینه دارند، اما اولی می‌تواند Correctness یا Privacy را نقض کند.

جزء Requestچه زمانی در Key؟خطر حذفخطر افزودن
Scheme/HostOrigin/Response متفاوتHost contaminationFragmentation
Pathتقریباً همیشهResource اشتباهAliasهای بی‌دلیل
QueryParameter محتواییSearch/Variant اشتباهUTM/Noise و Cardinality
Accept-EncodingRepresentation متفاوتEncoding ناسازگارVariation بی‌قاعده
LanguageServer-side locale متفاوتزبان/RTL اشتباهHeader variation زیاد
DeviceMarkup سرور واقعاً متفاوتنسخه ناسازگارHit کمتر
Tenant/Permissionاگر Cache مجاز و Scope جداستCross-tenant leakPer-user cache کم‌ارزش

مستند Cache keys در Cloudflare نمونه‌ای از تأثیر Query، Header، Cookie، Host و ویژگی User بر Key است. قابلیت و Plan هر CDN فرق دارد؛ طراحی مفهومی را با Rule اجراشده همان Provider تطبیق دهید.

Parameter registry بسازید

ParameterPurposeOutput را عوض می‌کند؟Key policyOwner
utm_sourceAttributionمعمولاً خیرNormalize/Exclude پس از تستMarketing
langLocaleبلهInclude یا Path مستقلProduct
variantSKU selectionممکن استطبق Response contractCommerce
previewDraft accessبله/حساسShared bypassCMS

Cookie را کورکورانه وارد Vary نکنید

Cookie می‌تواند ترکیب بسیار پرCardinality بسازد. برای محتوای شخصی، Bypass Shared cache یا Key محدود و صریح اغلب امن‌تر از Variation روی کل Cookie header است. Presence کوکی به‌تنهایی Response را Private نمی‌کند.

Private cache و Shared cache

راهنمای HTTP caching در MDN Private cache مانند Browser یک کاربر را از Shared cache مانند Proxy/CDN جدا می‌کند. Response شخصی اگر در Shared cache ذخیره شود ممکن است به User دیگر برسد. private استفاده Shared را منع می‌کند، اما رفتار Managed CDN و Ruleهای Override نیز باید بررسی شوند.

ResponsePrivate cacheShared cacheکنترل اصلی
Asset عمومیمناسبمناسبVersion + max-age
HTML عمومیمشروطمشروطs-maxage/Purge/Validator
Profile/Accountطبق حساسیتنامناسبprivate/no-store + Rule
Payment resultاغلب نامناسبنامناسبno-store/Bypass + Backend truth
Public APIطبق Contractطبق ContractAuth/Query/Vary/TTL

Cache-Control را دقیق بخوانید

Directiveمعنامرزبندی
max-ageFreshness lifetime برای Cache هدفاز زمان تولید Response محاسبه می‌شود، نه صرفاً دریافت
s-maxageFreshness ویژه Shared cacheبر max-age/Expires در Shared cache تقدم دارد
publicذخیره Shared را حتی در بعضی حالت‌ها مجاز می‌کندبه معنی «همه Data امن است» نیست
privateShared cache نباید ذخیره کندPrivate cache ممکن است
no-cacheپیش از Reuse باید Validate شودذخیره را منع نمی‌کند
no-storeCache نباید Response را ذخیره کندHistory/Implementation nuance را هم تست کنید
must-revalidateپس از Stale بدون Validation reuse نشودFailure mode را سخت‌تر می‌کند
immutableدر Freshness نیاز به Revalidate نیستبرای URL Versioned مناسب است

مرجع Cache-Control در MDN Directiveها و تفاوت Request/Response را توضیح می‌دهد. ترکیب Copy-paste شده برای همه Routeها نسازید؛ Header باید خروجی Cache contract باشد.

Asset fingerprinting، TTL بلند را کم‌ریسک می‌کند

وقتی نام فایل از Content hash می‌آید، تغییر محتوا URL جدید می‌سازد. نسخه قبلی می‌تواند با immutable و عمر بلند بماند و HTML جدید به Asset جدید اشاره کند. ترتیب Deploy باید مانع HTML جدید + Asset غایب یا HTML قدیمی + Asset حذف‌شده شود. Minify/Bundle/Delay JS موضوع جداست و در راهنمای بهینه‌سازی CSS و JavaScript بررسی شده است.

Freshness، Age و Expiration یکی نیستند

TTL در زبان عملی معمولاً «عمر» است، اما در HTTP Freshness از زمان تولید، Headerها و Age محاسبه می‌شود. Response پس از پایان Freshness فوراً حذف نمی‌شود؛ Stale می‌شود و شاید Validate، Reuse محدود یا Evict شود.

مفهومپرسشخطای رایج
Freshness lifetimeتا چه زمانی بدون تماس با Origin قابل استفاده است؟برابر دانستن با وجود فیزیکی Entry
Current ageResponse عملاً چند ثانیه سن دارد؟نادیده گرفتن زمان Cacheهای قبلی
Staleاز Freshness گذشته؟فرض اینکه حتماً حذف شده
ExpirationPolicy برنامه چه زمانی Entry را منقضی می‌کند؟قول ماندگاری تا آن زمان
EvictionMemory policy Entry را زودتر حذف کرده؟تفسیر هر MISS به TTL

Validation: تازه‌سازی بدون دریافت دوباره Body

Validatorهایی مانند ETag و Last-Modified به Cache اجازه می‌دهند با Request شرطی بپرسد Representation تغییر کرده است یا نه. اگر تغییر نکرده باشد، Origin می‌تواند 304 Not Modified بدون Body کامل برگرداند. Validator جای Invalidation نیست؛ فقط Revalidation را کارآمد می‌کند.

ValidatorRequest شرطیStrength/Useریسک
ETagIf-None-Matchشناسه Representationتولید ناسازگار میان Nodeها
Last-ModifiedIf-Modified-Sinceزمان تغییرResolution/Clock/تغییر سریع
Version keyApplication lookupنسخه Entity/Buildفراموشی bump وابستگی

Vary بخشی از Selection است

Vary: Accept-Language می‌گوید انتخاب Response ذخیره‌شده به Header زبان Request وابسته است. Vary: * Reuse را عملاً محدود می‌کند. Vary: User-Agent می‌تواند Variantهای بسیار زیاد بسازد؛ اگر Feature detection یا Responsive CSS کافی است، Variation دستگاه را نسازید.

Method و Status را در Cacheability لحاظ کنید

GET/HEAD معمولاً محور Cache HTTP هستند، اما Method تنها شرط نیست. Authorization، Directive، Status، Rule محلی و Semantics Response هم دخیل‌اند. عملیات State-changing را با Cache پاسخ خواندنی اشتباه نگیرید.

حالتخطرPolicy لازم
Authenticated GETداده شخصی در Shared cacheصریح و پیش‌فرض محافظه‌کارانه
301/308Redirect قدیمی طولانی می‌ماندMigration و TTL آگاهانه
404پس از ایجاد Resource، Not-found قدیمیNegative-cache budget/Purge
429Throttle یک User به دیگران تعمیم می‌یابدIdentity/Retry contract
5xxخطا به‌جای Recovery Cache می‌شودعدم ذخیره یا TTL بسیار کنترل‌شده
Range/206Partial response ناقص reuse می‌شودپشتیبانی استاندارد لایه

Negative caching برای جلوگیری از فشار Resourceهای ناموجود مفید است، اما TTL بلند روی ۴۰۴ یا Failure می‌تواند Recovery را پنهان کند. Status policy را مثل Content policy مستند کنید.

Cache-Status: HIT/MISS را استانداردتر گزارش کنید

Providerها Headerهایی مانند X-Cache یا CF-Cache-Status دارند، اما معنی و Syntax آن‌ها یکسان نیست. RFC 9211 هدر استاندارد Cache-Status را برای توضیح رفتار Cache تعریف می‌کند: hit، علت Forward، TTL باقیمانده، Stored بودن، Request collapse و حتی نمایش اختیاری Key.

سیگنالچه می‌گوید؟چه نمی‌گوید؟
hitRequest از همان Cache پاسخ گرفتهResponse درست یا تازه تجاری است
fwd=uri-missURI قابل استفاده در Cache نبودچرا Layerهای دیگر MISS بودند
fwd=staleEntry بود اما برای Reuse کافی نبودعلت Root تغییر/TTL
ttlFreshness باقیمانده طبق همان CacheFreshness همه Layerها
collapsedRequestها هنگام Forward همگرا شدندظرفیت Origin در Burstهای دیگر

RFC همچنین هشدار می‌دهد که افشای جزئیات Key/Status می‌تواند به تحلیل رفتار Cache یا حمله کمک کند. Header Debug حساس را فقط برای Client مجاز یا بدون Detail خطرناک ارائه دهید.

CDN و Edge Cache: نزدیکی کافی نیست

CDN زمانی ارزش دارد که Route/Asset واقعاً Cacheable، PoP برای Audience مفید و Origin/Purge درست متصل باشند. انتخاب Provider، پوشش شبکه ایران، امنیت Origin، WAF، Contract و Exit در راهنمای انتخاب CDN برای سایت ایرانی جدا بررسی شده است.

تصمیم Edgeپرسششاهد
Eligibilityکدام Content type/Status/Route ذخیره می‌شود؟Cache rule trace
KeyQuery/Cookie/Host/Language چگونه‌اند؟Key inspection/variant test
Origin controlHeader Origin اجرا یا Override می‌شود؟Rule precedence
PurgeURL/Prefix/Tag و Propagation SLA چیست؟API response + probe
ResilienceOrigin down چه نسخه‌ای سرو می‌شود؟Failure exercise
PrivacyAuthenticated/personal route Bypass است؟Cross-session test

مستند Cache response در Cloudflare نمونه‌ای از Statusهای HIT/MISS/BYPASS/EXPIRED/STALE/REVALIDATED و شرایط محصول است. از معنای یک Provider برای دیگری استفاده نکنید.

Browser TTL و Edge TTL را جدا طراحی کنید

ممکن است بخواهید HTML در Browser زود Validate شود اما Edge مدت بیشتری نگه دارد و با Purge کنترل شود. s-maxage یا Header/Rule مخصوص CDN می‌تواند این تفکیک را بسازد. نتیجه را روی Chain واقعی تست کنید؛ Layer میانی ممکن است Directive را Override کند.

Purge propagation بخشی از SLO است

پاسخ ۲۰۰ API پاک‌سازی لزوماً به معنی تازه‌شدن همه PoPها در همان لحظه نیست. زمان Event→Provider accepted→PoP visible را با Version marker و Region probes اندازه بگیرید. برای خبر اصلاحی، قیمت یا Incident این فاصله Outcome مهم است.

Service Worker Cache با HTTP Cache یکی نیست

Cache API در MDN Storage برنامه‌پذیر برای Request/Response pairs است و از HTTP cache-control headers به‌صورت خودکار برای Expiration پیروی نمی‌کند؛ برنامه باید Version، Update و Delete را مدیریت کند. بنابراین Hard refresh یا Purge CDN ممکن است نسخه Service Worker را عوض نکند.

StrategyرفتارFitریسک
Cache firstCache سپس NetworkAsset Versioned/OfflineUpdate دیر
Network firstNetwork سپس Fallback CacheHTML/Data تازهLatency/Offline timeout
Stale-while-revalidateCache فوری + Update پس‌زمینهکهنگی کوتاه قابل‌قبولنمایش نسخه قدیمی
Network onlyبدون Cache APITransaction/sensitiveعدم Offline

نام Strategy شبیه Directive HTTP است اما Implementation و پشتیبانی یکی نیست. Client cache را در Inventory مستقل ثبت کنید.

الگوهای Cache در Application

PatternReadWriteمزیتریسک
Cache-asideCache→MISS→Primary→StorePrimary سپس Invalidate/Updateفقط Working setCold miss/Stale race
Read-throughCache خودش Primary را می‌خواندطبق ProviderCode ساده‌ترCoupling/Provider fit
Write-throughCache آماده‌ترPrimary و Cache همگامRead hit بیشترDual-write failure/Cache pollution
Write-aroundMISS پس از Write محتملمستقیم Primaryداده کم‌خوانده Cache را پر نمی‌کندRead-after-write کند
Write-behindاز CacheCache سپس Async PrimaryWrite throughputDurability/ordering/data loss

راهنمای الگوهای Cache در AWS Cache-aside و Write-through را مقایسه می‌کند. Write-behind را فقط چون سریع‌تر است انتخاب نکنید؛ اگر Cache پیش از Durable write از دست برود، داده ممکن است گم شود. برای Order/Payment معمولاً Source of truth پایدار و Idempotency مقدم‌اند.

Cache-aside ساده است، Race ساده نیست

جریان معمول: Read Cache؛ در MISS از Primary بخوان؛ Store با TTL. هنگام Update معمولاً ابتدا Primary را تغییر و سپس Key را Invalid می‌کنیم. اگر Delete قبل از Commit یا هم‌زمان با Reader انجام شود، Reader ممکن است مقدار قدیمی را دوباره Store کند. Transaction boundary، Versioned key، event ordering و Retry لازم‌اند.

مستند Cache-aside در Redis TTL-bounded staleness، Invalidate-on-write و خطر Stampede روی Key محبوب را توضیح می‌دهد. عددهای Performance آن محصول/سناریو را Benchmark عمومی سایت خود ندانید.

Invalidation: تغییر Source باید به Dependency برسد

TTL فقط سقف زمانی است؛ اگر داده پیش از آن تغییر کند، Event باید Entryهای وابسته را تازه کند. Dependency همیشه یک‌به‌یک نیست.

Change eventDependencyهاInvalidationAcceptance
ویرایش مقالهArticle، Home، Category، RelatedURL/Tag purgeVersion در همه Surfaceها
تغییر SKUPDP، Listing، Search، APIEntity event fan-outPage/API/Cart parity
تغییر PermissionPolicy/Profile cacheUser/role version bumpAccess فوری درست
Deploy Templateهمه Responseهای TemplateSurrogate tag/GenerationBuild ID همگرا
Delete ResourceEntity، Lists، Negative cacheTombstone + dependent purgeنه Ghost، نه resurrect

Generation key از Delete انبوه ارزان‌تر است

به‌جای پیدا کردن همه Keyهای قدیمی، Namespace نسخه‌ای مانند catalog:v42:... می‌تواند با تغییر Generation، Readهای جدید را به مجموعه تازه ببرد. اما Entryهای قدیمی تا Eviction Memory می‌گیرند و Bump اشتباه Full cold start می‌سازد.

Tag purge برای Graph مناسب‌تر از URL تنهاست

اگر Responseهای Product و Listing Tag مشترک SKU داشته باشند، Event تغییر SKU می‌تواند همه را هدف بگیرد. Support و Limit Provider، Cardinality Tag، Propagation و Failure باید سنجیده شوند.

Expiry، Eviction و Invalidation سه رویداد متفاوت‌اند

رویدادعلتقابل پیش‌بینی؟کنترل
Expiryزمان سیاست تمام شدهتقریباًTTL/Jitter/Refresh
InvalidationSource/Dependency تغییر کردهEvent-drivenPurge/Version/Update
EvictionMemory/Policy/Pressureنه برای هر KeySizing/Policy/Working set
Manual purgeOperator/IncidentبلهScope/Approval/Log

مستند Eviction در Redis Policyهای LRU/LFU/TTL/random/noeviction و شاخص‌های Memory/Hit/Miss/Evicted را توضیح می‌دهد. MISS ناگهانی را فقط به TTL نسبت ندهید؛ Eviction یا Namespace churn ممکن است علت باشد.

Stale پاسخ بد نیست؛ پاسخ بدون بودجه بد است

در بعضی Routeها نسخه چندثانیه‌ای قدیمی بهتر از Error یا Latency زیاد است؛ در Balance، Permission یا Payment چنین نیست. RFC 5861 دو کنترل را تعریف می‌کند:

  • stale-while-revalidate: در بازه محدود نسخه Stale سرو و Revalidation پس‌زمینه انجام شود؛
  • stale-if-error: در خطای Origin، نسخه Stale تا بازه تعیین‌شده استفاده شود.
ArtifactSWR fitSIE fitGuardrail
مقاله عمومیاغلب قابل‌بررسیممکن استاصلاح حساس سریع Purge شود
Catalog عمومیمشروطمشروطPrice/Stock parity
Service status pageبا احتیاطممکن است گمراه کندIncident truth
Account/PermissionنامناسبنامناسبCurrent authorization
Payment/BalanceنامناسبنامناسبDurable truth

پشتیبانی واقعی Browser/CDN/Proxy را آزمون کنید؛ وجود Header مساوی اجرا در هر Layer نیست.

Cache stampede: محبوب‌ترین Key می‌تواند Origin را بشکند

اگر Entry داغ منقضی شود و همه Requestها MISS شوند، هرکدام به Primary می‌رود. کنترل‌ها:

کنترلاثرریسک/شرط
Request collapse/singleflightیک Regeneration، چند WaiterTimeout/leader failure
Lock با Tokenمالک مشخص بازسازیLock expiry و safe release
TTL jitterانقضاها پخش می‌شوندFreshness سخت
Probabilistic early refreshKey داغ زودتر تازه می‌شودپیچیدگی/Extra load
SWRWaiter نسخه Stale می‌گیردبودجه Staleness
PrewarmEntryهای حیاتی آماده‌اندCache pollution/Origin load

Full purge در ترافیک بالا Stampede را از یک Key به کل Working set گسترش می‌دهد. سناریوی Cache cold، شکست Layer و Recovery را همراه طرح Uptime و مانیتورینگ تمرین کنید.

API caching: Contract هر Endpoint جداست

API عمومی Read-heavy می‌تواند Cache شود، اما Auth scope، Query normalization، Pagination، Error، Rate limit، Version و Invalidation باید مشخص باشند. REST بودن به‌تنهایی Cacheability را تضمین نمی‌کند.

EndpointKeyFreshnessریسک
Public catalogVersion/Query/Page/Localeکوتاه + EventPrice/stock stale
Search suggestionNormalized query/localeمتوسطCardinality/abuse
User profileترجیحاً Shared bypassجاریCross-user leak
Permission checkSubject/resource/policy versionبسیار محدودAccess stale
Webhook/callbackCache نشودعملیات IdempotentReplay/state loss

Validation، Idempotency، Retry و Reliability Endpointها در راهنمای طراحی و امنیت API عمیق‌تر آمده است.

Cache security: سرعت روی مرز اعتماد

Web Cache Deception

Attacker مسیری می‌سازد که برای Origin Dynamic/شخصی است اما برای Cache شبیه Asset است. اگر Origin روی Path اضافه همان HTML شخصی را ۲۰۰ بدهد و CDN از پسوند تصمیم بگیرد، Response ممکن است Shared شود. مستند Cloudflare درباره Cache Deception تطابق Extension و Content-Type را یکی از کنترل‌ها می‌داند؛ Route correctness و no-store/private همچنان لازم‌اند.

Cache poisoning

Input کنترل‌شده مهاجم—Host، Header، Query یا Path normalization—ممکن است Response آلوده‌ای بسازد که زیر Key عمومی ذخیره شود. Canonicalization یکسان در CDN/Proxy/App، Allowlist Host، حذف Headerهای Unkeyed اثرگذار، تست Variant و محدود کردن Debug detail لازم‌اند.

Cross-tenant و Cross-user leakage

دو Tenant یا User را با Markerهای متفاوت هم‌زمان تست کنید. اگر پاسخ شخصی جابه‌جا شد، فوراً Bypass/Purge، Evidence و Scope را حفظ و Incident را فعال کنید؛ این فقط Bug Performance نیست. پاسخ اعتماد و Remedy را با سیستم اعتماد و رسیدگی به رخداد مشتری هماهنگ کنید.

چندلایه بودن، Debug را سخت می‌کند

Browser ممکن است HIT دهد درحالی‌که CDN MISS است؛ CDN می‌تواند HIT باشد و Object cache هم HIT قدیمی خودش را داشته باشد. برای هر Layer شناسه و Marker مستقل لازم است.

EvidenceLayerمحدودیت
DevTools memory/disk cacheBrowserهمه Clientها را نمایندگی نمی‌کند
Service Worker log/versionClient appHTTP cache جداست
Age/Cache-Status/vendor headerEdge/Proxyمعنای Provider-specific
Build/Content versionBody/Applicationباید غیرشخصی باشد
Key/TTL/Hit metricObject storeSampling/Cardinality
Trace/Query logOrigin/PrimaryPrivacy/Cost

اندازه‌گیری Cache: Hit ratio کافی نیست

Metricتعریفتقسیم لازمتصمیم
Request hit ratioHIT / LookupLayer، Route، PersonaKey/TTL/Eligibility
Byte hit ratioByteهای Cache / کل ByteAsset type/RegionBandwidth/CDN
Origin offloadRequest/Compute حذف‌شده از OriginEndpoint/Cold/WarmCapacity/TCO
Latencyp50/p75/p95/p99HIT/MISS/BYPASS/PoPUser/SLO
Freshness lagEvent→نسخه تازه قابل مشاهدهSurface/RegionInvalidation/Purge
CorrectnessParity/Leakage/Stale incidentEntity/PersonaGuardrail/Incident
Store healthMemory/Eviction/Latency/ErrorInstance/NamespaceSizing/Policy

Hit ratio را با Denominator روشن گزارش کنید: آیا BYPASS داخل Lookup است؟ درخواست Revalidated HIT یا MISS شمرده شده؟ Layerها یک تعریف دارند؟ Data contract و Reconciliation این ابهام را حل می‌کند؛ اصول آن در معماری تحلیل داده و GA4/Warehouse قابل تعمیم است.

Hit بالا می‌تواند بد باشد

اگر Error، ۴۰۴ طولانی، Permission قدیمی یا Response شخصی Cache شود، Hit بالا فقط دامنه خطا را بیشتر می‌کند. Correctness، Freshness و Business guardrail مقدم‌اند.

Hit پایین همیشه بد نیست

Checkout و Account باید BYPASS باشند. Long-tail URLها ممکن است Reuse کافی نداشته باشند. به‌جای هدف کلی ۹۰٪، Target را برای هر Artifact class و Cost/Benefit آن تعریف کنید.

آیا Cache مستقیماً رتبه SEO را بالا می‌برد؟

Cache تضمین رتبه یا Conversion نیست. می‌تواند Origin latency و پایداری را بهتر و تحویل Asset را کارآمد کند؛ اما محتوای ضعیف، JavaScript سنگین، Layout shift، Server error یا UX بد را خودکار حل نمی‌کند. از سوی دیگر، Cache قدیمی می‌تواند Title، Canonical، Robots، Structured data یا Content قبلی را به Crawler بدهد. پس Release SEO نیز به Purge و بررسی HTML عمومی نیاز دارد.

عیب‌یابی Cache با فرضیه، نه Clear همه‌چیز

۱. Artifact و Expected version را ثبت کنید

URL نهایی، زمان تغییر، Expected/Actual، Persona، Region و Artifact را بنویسید: HTML، Asset، API، Entity یا DNS. یک Marker مانند Build ID یا Content version از «برای من تازه است» دقیق‌تر است.

۲. Redirect و Variant را مشخص کنید

Scheme، Host، Slash، Query، Language، Encoding، Device و Auth را ثبت کنید. ممکن است URL قدیمی Purge شده اما Destination، Variant زبان یا PoP دیگری قدیمی باشد.

۳. Header و Body را با Request واقعی بگیرید

curl -sS -D headers-1.txt -o body-1.html 'https://example.com/final-url/'
curl -sS -D headers-2.txt -o body-2.html 'https://example.com/final-url/'

HEAD ممکن است مسیر متفاوتی از GET داشته باشد. Headerهای Cache-Control/Age/Vary/ETag/Cache-Status و Provider را کنار Hash/Marker Body بخوانید. Request Debug را روی داده حساس یا بدون مجوز اجرا نکنید.

۴. Layer را با آزمون ردکننده محدود کنید

نشانهفرضیهآزمون ردکننده
فقط یک Browser قدیمیHTTP cache/SWProfile/Device دیگر
یک Region قدیمیCDN PoPProbe چند Region/Origin
HTML تازه، Data قدیمیAPI/Object cachePrimary/API direct evidence
Guest قدیمی، Login تازهShared page cacheAuthorized bypass/Origin
Purge بی‌اثرLayer دیگر/Key دیگرCache chain و exact key
Purge→5xxCold capacity/StampedeWarm vs Cold load

۵. کوچک‌ترین Scope اثبات‌شده را تغییر دهید

یک URL، Tag، Entity key یا Version را هدف بگیرید. Full purge، Flush سراسری یا Restart فقط با Scope معتبر، Window، Monitoring و Rollback انجام شود.

۶. Root cause را پس از Recovery ببندید

Purge موفق نشان می‌دهد یک نسخه Cached دخیل بوده؛ مشخص نمی‌کند Event چرا نرسید، Dependency چرا جا ماند یا Key چرا متفاوت بود. Timeline، Rule diff، Purge log و Regression test را ثبت کنید.

ماتریس تست Cache

محورحالت‌هاAssertion
IdentityGuest A/B، User A/B، AdminResponse شخصی جابه‌جا نمی‌شود
StateCold، MISS، HIT، Stale، پس از PurgeHeader/Body مطابق Contract
QueryCanonical، UTM، Search، VariantNormalization و Key صحیح
Locale/Devicefa/en، RTL/LTR، Mobile/DesktopVariant درست و محدود
Status۲۰۰، ۳۰۱، ۴۰۴، ۴۲۹، ۵۰۰TTL/Store policy درست
ChangeEntity، List، Template، Permissionهمه Dependencyها تازه
FailureOrigin/Cache/Network downStale/Fail mode درست
ConcurrencyHot key expiry/Purge burstStampede کنترل شده

تست Layer-local و End-to-end هر دو لازم‌اند

Unit test Key builder و Invalidation handler خطای Code را می‌گیرد؛ Integration test Cache store و Event را؛ End-to-end مسیر Browser→Edge→Origin را. هیچ‌کدام جای دیگری را نمی‌گیرد.

سه مثال برای مخاطب ایرانی

رسانه با خبر و اصلاح فوری

Assetهای Versioned عمر بلند دارند؛ HTML خبر Edge-cache کوتاه و Event purge دارد. اصلاح حقوقی/حساس Priority purge و Probe چند Region می‌گیرد. Home/Category وابسته نیز با Tag خبر پاک می‌شوند. Stale-if-error برای مقاله عادی شاید مجاز باشد، اما برای Correction حساس بودجه محدودتری دارد.

فروشگاه با قیمت و موجودی

Catalog/PDP عمومی Cacheable مشروط‌اند؛ تغییر SKU به Listing/Search/API fan-out می‌شود. Cart، Account، Checkout و Callback Shared bypass هستند. Price/Stock در Cart دوباره از Source معتبر کنترل می‌شود. Cache cold پیش از کمپین با نرخ کنترل‌شده سنجیده می‌شود.

SaaS با Landing عمومی و Dashboard شخصی

Landing و Docs در Browser/CDN Cache می‌شوند؛ Dashboard و Permission response پیش‌فرض Shared bypass هستند. Reference data عمومی ممکن است Cache-aside با Version tenant-independent داشته باشد، اما Feature entitlement به Policy version و User/Tenant scope حساس است.

چه چیزهایی را بهتر است Cache نکنیم؟

  • Secret، Token، Password reset و Response دارای اطلاعات حساس؛
  • Payment، Balance، Permission و تصمیم امنیتی بدون طراحی تخصصی؛
  • Responseهای Per-user با Reuse ناچیز در Shared layer؛
  • Queryهای ارزان که Cache lookup/serialization از آن‌ها گران‌تر است؛
  • داده‌ای که Invalidation یا Freshness آن قابل تعریف نیست؛
  • Entry با Cardinality کنترل‌نشده و ورودی مهاجم؛
  • Result غلط برای پنهان‌کردن Query/Architecture مسئله‌دار.

Rollout سیاست Cache

  1. یک Artifact class پرتکرار و کم‌ریسک انتخاب کنید.
  2. Baseline Cost/Latency/Correctness و Freshness budget را ثبت کنید.
  3. Key schema، Eligibility، TTL، Event و Failure mode را بنویسید.
  4. Unit/Integration/Cross-session/Status tests را بسازید.
  5. Canary را روی Scope کوچک فعال کنید.
  6. HIT/MISS/Eviction/Purge lag/Origin/Guardrail را ببینید.
  7. Cache cold و Layer failure را Controlled آزمایش کنید.
  8. پس از Acceptance، Coverage را تدریجی گسترش دهید.
  9. Rollback Rule و همگرایی Cache قبلی را تمرین کنید.

اشتباه‌های رایج طراحی Cache

اشتباهپیامداصلاح
TTL واحد برای همهکهنگی یا MISS بی‌دلیلFreshness budget هر Artifact
URL-only key برای پاسخ شخصیLeakageBypass/Scope صریح
همه Queryها در KeyCardinality/Hit پایینParameter registry
Ignore همه QueryهاSearch/Variant غلطContent-effect analysis
Full purge عادیCold stormDependency/tag/version
فقط TTL، بدون Eventتاخیر FreshnessInvalidate-on-change
Cache جای PrimaryData lossDurable source
Hit ratio هدف نهاییخطای سریع‌ترCorrectness/Outcome guardrail
فرض یک LayerDebug/Purge ناقصCache inventory/chain
Header Debug عمومی و پرجزئیاتاطلاعات برای حملهحداقل/Authorized diagnostics

برنامه ۳۰/۶۰/۹۰ روزه معماری Cache

روز ۱ تا ۳۰: Inventory و مرز اعتماد

  • نقشه Browser/SW/CDN/Proxy/API/App/DB/DNS و Owner؛
  • طبقه‌بندی Public/Personal/Sensitive/Transactional؛
  • Baseline Warm/Cold، Origin، Freshness و Incident؛
  • تأیید Bypass پاسخ‌های حساس با دو Identity؛
  • ثبت Parameter و Status policy.

روز ۳۱ تا ۶۰: قرارداد و کنترل تغییر

  • Cache contract برای Artifact classهای اولویت‌دار؛
  • Key schema/version، TTL و Dependency graph؛
  • Event-driven invalidation و Purge log/Retry؛
  • Versioned asset و Cache-Status/Marker کنترل‌شده؛
  • Automated correctness/freshness tests.

روز ۶۱ تا ۹۰: تاب‌آوری و اقتصاد

  • Stampede control، SWR/SIE فقط در Route مناسب؛
  • Memory/Eviction/Working-set tuning؛
  • Failure و Cache-cold exercise؛
  • SLO تازگی/Purge/Recovery و Business guardrail؛
  • حذف Entryها و Layerهای کم‌ارزش بر اساس TCO.

چک‌لیست کیفیت سیاست Cache

  • Cache کپی قابل‌بازسازی است و Source of truth مشخص دارد.
  • Benefit/TCO و Artifact class قبل از پیاده‌سازی تعریف شده‌اند.
  • تمام Layerها، Rule، Purge path، Evidence و Owner ثبت‌اند.
  • Eligibility شامل Method، Status، Auth و Data class است.
  • Key schema و Cardinality budget داریم.
  • Query/Cookie/Language/Device فقط با اثر واقعی وارد Key می‌شوند.
  • Private و Shared cache صریحاً جدا شده‌اند.
  • Cache-Control و Vary با Contract سازگارند.
  • Freshness/Age/Stale/Eviction درست تفکیک شده‌اند.
  • Validator و Asset fingerprinting در محل مناسب‌اند.
  • TTL محافظ و Event invalidation هر دو وجود دارند.
  • Dependency graph و Targeted purge داریم.
  • Purge Idempotent، Observable و Retryable است.
  • Stale policy برای Route حساس Fail-closed است.
  • Stampede و Full-cold recovery تست شده‌اند.
  • Cache-Status/Provider headers بدون افشای خطرناک‌اند.
  • Cross-user/tenant، Poisoning و Deception تست شده‌اند.
  • Warm/Cold/Region/Status/Failure matrix اجرا می‌شود.
  • Correctness/Freshness/Outcome بر Hit ratio مقدم‌اند.
  • Rollout، Rollback و Incident owner مشخص‌اند.

پرسش‌های متداول درباره Cache

کش چیست و دقیقاً چه چیزی را سریع می‌کند؟

Cache نسخه قابل‌بازسازی Response یا نتیجه پردازش را نگه می‌دارد تا Request هم‌ارز کار کمتری انجام دهد. بسته به Layer می‌تواند انتقال شبکه، Render، API call یا Query را حذف کند. اگر Reuse یا هزینه تولید کم باشد، سودی ندارد.

TTL مناسب Cache چند ثانیه است؟

عدد جهانی وجود ندارد. TTL باید از نرخ تغییر، پیامد Staleness، هزینه Regeneration، Event invalidation و Failure mode بیاید. Asset Versioned می‌تواند بسیار بلند و Permission/Payment باید جاری یا بدون Shared cache باشد.

تفاوت no-cache و no-store چیست؟

no-cache Storage را منع نمی‌کند؛ Reuse را به Validation موفق وابسته می‌کند. no-store ذخیره Response را منع می‌کند. private نیز Shared cache را منع می‌کند، اما Private cache ممکن است ذخیره کند.

چرا با وجود Cache، Hit ratio پایین است؟

Cardinality Query/Cookie/Device، TTL کوتاه، Eviction، Working set بزرگ، Routeهای BYPASS، چند Host یا Key normalization متفاوت ممکن است علت باشد. ابتدا Miss reason را به تفکیک Layer/Route بخوانید؛ افزایش Memory تنها یکی از فرضیه‌هاست.

چرا پاک‌سازی کامل Cache خطرناک است؟

Full purge تمام Working set را Cold می‌کند. Requestهای بعدی هم‌زمان به Origin/Primary می‌روند و می‌توانند Stampede بسازند. Targeted purge، Generation/Tag، Priority warmup، Rate control و Capacity monitoring کم‌ریسک‌ترند.

جمع‌بندی: Cache یک قرارداد صحت است

پرسش خوب «کش را روشن کنیم؟» نیست؛ این است: کدام Artifact برای کدام Identity، با چه Key، تا چه Freshness، زیر کدام Event و Failure mode، در کدام Layer و با چه شاهدی قابل Reuse است؟

با یک Artifact عمومی و پرتکرار شروع کنید. Contract، Key و Guardrail را بنویسید؛ Warm/Cold و دو Identity را تست کنید؛ Dependency invalidation و Recovery را اجرا؛ و فقط وقتی Correctness و Outcome پایدارند Coverage را افزایش دهید. Cache باید دوباره‌کاری را حذف کند، نه شفافیت و اعتماد را.

منابع رسمی و مرجع

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *