امنیت، هویت، استقرار و تابآوری · فصل ۷ — Dependency، Contract، Event و Network Failure · 115
Duplicate/Late Events
failure را بعد از وقوع و بهصورت موردی تحلیل میکند و هنوز detection، containment و repair path از قبل طراحی نشده است. موضوع جاری: «Duplicate/Late Events». میتواند failure family «Duplicate/Late Events» را بازتولید/تشخیص دهد و detection، containment و recovery مناسب را تعیین کند.
خلاصهٔ درس
failure را بعد از وقوع و بهصورت موردی تحلیل میکند و هنوز detection، containment و repair path از قبل طراحی نشده است. موضوع جاری: «Duplicate/Late Events».
میتواند failure family «Duplicate/Late Events» را بازتولید/تشخیص دهد و detection، containment و recovery مناسب را تعیین کند.
خروجی این درس
میتواند failure family «Duplicate/Late Events» را بازتولید/تشخیص دهد و detection، containment و recovery مناسب را تعیین کند.
1. مسئله اصلی: delivery دوباره با اجرای دوبارهی کسبوکار یکی نیست
در سیستمهای event-driven ممکن است یک پیام دوباره تحویل شود، دیر برسد یا نسبت به رویدادهای دیگر جابهجا شود. خطای اصلی این است که arrival را معادل «یک بار و فقط یک بار اجرای business effect» بگیریم. در این درس transport delivery، ordering و side effect را جدا ثبت میکنیم تا هر کدام مستقل قابل آزمون باشد.
2. هشت ستون شواهد را جدا نگه دار
برای هر event حداقل delivery attempt، duplicate detection، late classification، ordering policy، idempotency identity، side-effect evidence، replay result و residual risk را ثبت کن. اگر این ابعاد در یک status فشرده شوند، معلوم نمیشود مشکل از redelivery بوده، event واقعاً stale بوده یا consumer همان business operation را دوباره اجرا کرده است.
3. At-least-once یعنی redelivery ممکن است
مستندات Kafka delivery semantics را به at-most-once، at-least-once و exactly-once تفکیک میکند و صریحاً publish و consume/output را دو مسئله جدا میداند. [KAFKA-DESIGN] بنابراین در یک مسیر at-least-once، مشاهدهی دوبارهی event میتواند رفتار مجاز transport باشد؛ consumer باید مشخص کند تکرار چه اثری روی state و side effect دارد.
4. Producer idempotence مرز خودش را دارد
در Kafka، enable.idempotence برای جلوگیری از ثبت نسخههای تکراری ناشی از producer retry تحت شرایط مستند طراحی شده است. [KAFKA-PRODUCER] این ادعا به log producer محدود است؛ از آن نمیتوان نتیجه گرفت یک consumer که به database، ایمیل، پرداخت یا سرویس دیگری مینویسد حتماً external side effect را exactly once اجرا میکند.
5. event_id و business operation identity را قاطی نکن
یک duplicate ساده میتواند همان event_id را دوباره بیاورد. اما failure سختتر وقتی است که event_id جدید است ولی همان business operation، مثلاً order-42:charge, دوباره درخواست شده است. dedupe صرفاً با event_id این حالت را نمیبیند. برای side effect باید identity متناسب با معنای کسبوکار تعریف شود.
6. Consumer idempotency باید اثر را محافظت کند
Processed-marker فقط وقتی مفید است که دقیقاً همان مرزی را پوشش دهد که میخواهی محافظت کنی. اگر marker قبل از effect نوشته شود ممکن است effect گم شود؛ اگر بعد از effect و در storage مستقل نوشته شود crash میتواند ambiguity بسازد. این درس marker را oracle مطلق نمیداند و side-effect evidence را جدا ثبت میکند.
7. Late با duplicate فرق دارد
رویدادی ممکن است برای اولین بار برسد اما sequence یا event-time آن از state اعمالشده عقبتر باشد؛ این event late/stale است ولی duplicate نیست. برعکس یک duplicate میتواند از نظر sequence هم late باشد. record باید هر دو محور را مستقل علامت بزند تا policy مناسب انتخاب شود.
8. Ordering همیشه global نیست
Ordering معمولاً به key، partition یا scope مشخص وابسته است. اگر sequence 7 قبل از 6 برسد، لزوماً نباید آن را stale دور بیندازی؛ ممکن است policy صحیح buffer، gap detection یا reconciliation باشد. «out of order» و «late stale update» یک تصمیم واحد نیستند.
9. برای stale update policy صریح داشته باش
وقتی event قدیمیتر از آخرین state معتبر است، consumer باید تصمیم آشکار داشته باشد: reject، merge، compensate یا reconcile. اعمال کور رویداد قدیمی میتواند state جدید را عقب برگرداند. در fixture این درس، stale update تا زمانی که policy اجازه ندهد side effect جدید تولید نمیکند.
10. Dedupe window و retention بخشی از correctness است
اگر dedupe record زودتر از retry window حذف شود، همان event بعداً دوباره «جدید» دیده میشود. در مقابل نگهداری بینهایت هم هزینه و lifecycle دارد. record باید scope و residual risk را بیان کند؛ این درس یک retention عددی جهانی تجویز نمیکند.
11. Replay باید همان invariantها را حفظ کند
replay برای recovery مفید است، اما اگر از مسیر متفاوتی عبور کند یا dedupe/order policy را دور بزند میتواند دوباره side effect بسازد. proof معتبر این است که replay همان duplicate gate و ordering policy را طی کند و evidence نشان دهد اثر ناخواستهی جدید ایجاد نشده است.
12. Counterexample: event ID جدید، business key تکراری
در یکی از fixtureها دو event ID متفاوت به یک business operation اشاره میکنند. اگر learner فقط event ID را چک کند، transport duplicate نمیبیند و side effect را دوباره اجرا میکند. راه درست، تشخیص این است که transport uniqueness و business idempotency دو قرارداد متفاوتاند.
13. Transfer: دو consumer و ordering key جدید
در transfer، ordering key تغییر میکند و دو consumer همزمان فعالاند. state محلی یک consumer دیگر برای dedupe کافی نیست. باید مشخص شود کدام shared identity/state مرز concurrency را پوشش میدهد و late/order decision چگونه بدون ادعای global exactly-once بازسازی میشود.
14. Lab: هشت fixture و ۶۴ assertion
Lab کاملاً local، deterministic و synthetic است. هشت case شامل baseline سالم، duplicate همان event ID، late stale event، business duplicate با event ID جدید، gap/out-of-order، producer retry که در log dedupe شده، evidence ناقص و transfer دو-consumer است. evaluator پنهان هشت خروجی برای هر case را میسنجد؛ در مجموع ۶۴ assertion.
15. Exit checklist و مرز ادعا
برای خروج باید بتوانی duplicate و late را مستقل تشخیص دهی؛ event identity را از business idempotency جدا کنی؛ producer idempotence را به scope واقعیاش محدود کنی؛ ordering policy را explicit کنی؛ side-effect evidence و replay را بررسی کنی؛ در نبود evidence حالت OPEN را حفظ کنی؛ و transfer را با context جدید از صفر حل کنی. fixture مصنوعی این درس هیچ تضمین global exactly-once برای سیستم واقعی اثبات نمیکند.
ارزیابی
پاسخنامهی این درس در بستهی آموزش وجود ندارد؛ خودت جواب بده و صادقانه علامت بزن. «نیاز به مرور» درس را به صف تکرار میفرستد.
FLR-005-AF1 formative
FLR-005-AF2 formative
FLR-005-AF3 formative
FLR-005-AS1 summative
FLR-005-AS2 transfer
ملاکهای ارزیابی (rubric)
| Dimension | Sufficient evidence | Blocking failure |
|---|---|---|
| Duplicate vs late | Both dimensions are classified independently from direct evidence | Treats every late event as duplicate or vice versa |
| Identity boundary | Event identity and business-operation identity are explicitly separated | Event-ID-only dedupe accepted as universal protection |
| Ordering judgment | Ordering scope/policy is explicit; gap is not silently labeled stale | Global-order assumption without evidence |
| Side-effect protection | Side-effect evidence and idempotency gate are audited independently of broker claim | Producer idempotence treated as external exactly-once proof |
| Replay and transfer | Replay preserves invariants and transfer is rebuilt for two-consumer context | Green replay or copied first-fixture answer treated as proof |
منابع و تازگی
مطالعهٔ موارد (case studies)
تصاویر درس
فایلهای آزمایشگاه
Use only the supplied deterministic synthetic fixtures. For each case, build Event Delivery Anomaly Record v1 from observable evidence.
Keep duplicate detection and late classification separate. Distinguish event identity from business-operation identity. Producer idempotence is bounded to its documented producer/log scope and is not proof of exactly-once external side effects. Preserve UNKNOWN when evidence is incomplete.
The transfer fixture changes the ordering key and enables two consumers; do not assume one consumer's local dedupe/order state spans that concurrency boundary.
رسانه و اسلایدهای درس
فایلهای آموزشی (دانلود)