#experience
Let's talk about distributed systems.
Siz distributed system backend qismini qurayabsiz. Client serverga request (so'rov) yuboradi - API, message queue yoki event bus orqali. Ammo bir muammo bor, qanday qilib request'ni serveringiz aniq bir marta process qilishini ta'minlaysiz?
Eng qiziq muammolar bu yerda faqat u emas balkim:
- Network paketlarni drop qilishi mumkin (tashlavoradi)
- Client retry qilishi (qayta so'rov yuborishi) mumkin
- Server process qilish jarayonida crash bo'lishi (buzilishi) mumkin
- Message ketma-ketligi buzilishi, kech kelishi, yoki 2 marta kelishi mumkin
Agar yuqoridagi muammolarni oldini olmasangiz:
- Client'dan 2 marta to'lov yechishingiz mumkin
- Duplikat ma'lumot yaratib qo'yishingiz mumkin
- Mahsulotni 2 marta yuborishingiz mumkin
- 50 marta notification yuborishingiz mumkin (Twitter bir yili shunday qilgandi, foydalanuvchilar retry sababli chatiga bir xil xabarlar bilan to'ldirilgandi)
Distributed tizimlarda "At-most-once", "At-least-once" va "Exactly-once" degan tushunchalar mavjud. "At-most-once" holatida xabarlar/so'rovlar 0 yoki 1 marta yetkaziladi. Duplikatlarsiz, ammo siz uni yo'qotishingiz (drop) mumkin. "At-least-once" holatida xabarlar 1+ marta yetkaziladi. Yo'qotish yo'q, lekin takrorlanish mumkin. "Exactly-once" holatida xabar bir marta yuboriladi (bu ko'rsatkichga erishish qiyin).
Exactly-once holati deyarli mavjud emas. Siz user'ni idempotent qilib fake qilib turasiz. Ya'ni HTTP headerga doim idempotency token qo'shasiz. Process qilingan ID'lar tarixini saqlab borasiz. Outbox patter ya'ni event (xodisa)lar ma'lumotlar omborida saqlaysiz va ularni o'sha yerdan olib process qilasiz.
Misol uchun, S3, Google drive, Dropbox kabi tizimlarga ko'pchilik fayllarni yuklashadi. API'lari doim ham barqaror ishlamaydi. Xuddi o'sha PUT yoki POST request bir necha marta yuborilishi mumkin. Har bir obyekt uchun maxsus key va ETag (content caching) bilan yuborishadi. Bu esa content-based idempotency deyiladi. Yanada chqur kirsak, kontentlarni bitta qilib yubormaydi, TCP ni chegarasi (65KB) tufayli kontentlar bir nechta iteratsiya qilib yuboriladi va buni MTU deyishadi. Endi tasavvur qiling, brinchi yuklashda 20% yuklandi va crash bo'ldi, 2chisida esa 40% bo'lib crash bo'lsa nima qilasiz. Bu holatlarda ham content-based idempotency key ishlatish ko'p muammoni yechadi. Keyingi marta qayta urinishda siz kelgan joyidan davom eta olasiz degani.
System Design intervyularda ko'p yordam bergan shu mavzular menga. Sizga ham foydali bo'lishi mumkin. Bugunchalik kallangizni achitish uchun shu yetadi : )
Post #521
5.1K