GH GambleHub

Mesajların qaydasına zəmanət

1) «sifariş» nədir və niyə lazımdır

Mesaj qaydası bir mahiyyət hadisələri (sifariş, istifadəçi, cüzdan) və ya bütün axın üçün «nə əvvəl işlənməlidir» münasibətidir. Bu invariantlar üçün vacibdir: «B-dən əvvəl A statusu», «silinmədən əvvəl balans», «n + 1-dən əvvəl n versiyası».
Paylanmış sistemlərdə qlobal ümumi yol qaydası və nadir hallarda lazımdır; adətən «açar» yerli sifariş kifayətdir.


2) Sifariş zəmanətlərinin növləri

1. Per-partition (log bölməsində yerli nizam) - Kafka: partiya daxilində nizam saxlanılır, partiyalar arasında - yoxdur.
2. Per-key (ordering key/message group) - bütün mesajlar bir «axın» emalına (Kafka key, SQS FIFO MessageGroupId, Pub/Sub ordering key) yönləndirilir.
3. Global total order - bütün sistem vahid sifariş (paylanmış jurnal/sekvenser) görür. Bahalı, mövcudluğu pisləşdirir və throughput.
4. Causal order (səbəb-nəticə) - «B A təsiri müşahidə əgər A sonra hadisə». Qlobal sekvenser olmadan meta-məlumatlarla (versiyalar, Lamport-time/vektor saatlar) əldə edilə bilər.
5. Best-effort order - broker nizam-intizamı qorumağa çalışır, lakin uğursuzluqlar ola bilər (çox vaxt NATS Core, RabbitMQ bir neçə konsumerdə).


3) Harada nizam pozulur

Paralel bir sıra konsumerlər (RabbitMQ: bir sıra → interleaving üçün bir neçə consumers).
Retray/təkrar çatdırılma (at-least-once), 'ack' taymautları, yenidən növbəyə qoyulması.
Rebalans/Feylover (Kafka: partiyanın/liderin hərəkəti).
DLQ/təkrar emal - «zəhərli» mesaj DLQ gedir, sonrakı → məntiqi boşluq.
Multi-region və replikasiya - müxtəlif gecikmələr → rassinxronizasiya.


4) Dizayn «açar sifariş»

Açar "nizamlama vahidi 'ni formalaşdırır. Tövsiyələr:
  • Təbii açarları istifadə edin: 'order _ id', 'wallet _ id', 'aggregate _ id'.
  • «Qaynar açarları» izləyin - bir açar axını «bloklaya» bilər (head-of-line blocking). Lazım gələrsə, açarı parçalayın: 'order _ id #shard (0.. k-1)' determinik yenidən qurulması ilə.
  • Kafka 'da - bir açar → bir hissə, sıra açar daxilində qalacaq.
Nümunə (Kafka, Java):
java producer.send(new ProducerRecord<>("orders", orderId, eventBytes));

(Açar = 'orderId' yerli qaydaya zəmanət verir.)


5) «Bant genişliyinə qarşı sifariş»

Güclü zəmanətlər tez-tez throughput və mövcudluğu ilə ziddiyyət təşkil edir:
  • Növbə üçün bir konsumer qaydanı saxlayır, lakin paralelliyi azaldır.
  • At-least-once + paralellik performansı artırır, lakin idempotentlik və/və ya nizam bərpa tələb edir.
  • Global order sekvenserə hop əlavə edir → ↑ gizlilik və imtina riski.

Kompromis: per-key sifariş, paralellik = partiyalar/qrupların sayı, + idempotent sink.


6) Xüsusi broker nizam nəzarət

Kafka

Partiya daxilində nizam.
'max. in. flight. requests. per. connection ≤ 5` с `enable. idempotence = true 'ki, prodüserin retrayları qaydanı dəyişməsin.
Konsumer qrupu: bir partiya → bir anda bir vorker. Yenidən çatdırılma mümkündür → sequence/version biznes təbəqəsində saxlayın.
Tranzaksiyalar (read-process-write) «oxu/qeyd/skommitil ofset» ardıcıllığını saxlayır, lakin qlobal sifariş yaratmır.

İstehsal minimumu (producer. properties):
properties enable.idempotence=true acks=all retries=2147483647 max.in.flight.requests.per.connection=5

RabbitMQ (AMQP)

Sifariş bir müştəri üçün bir növbədə təmin edilir. Bir neçə mesaj məsləhətçisi ilə «qarışıq» gələ bilər.
Sifariş üçün: bitdikdən sonra bir konsumer və ya prefetch = 1 + ack. Paralellik üçün - açar sıralarını bölün (sharding exchanges/consistent-hash exchange).

NATS / JetStream

NATS Core - ən yaxşı effort, aşağı gecikmə, sifariş pozula bilər.
JetStream: axın/ardıcıllıq daxilində nizam; Nadir hallarda konsumerdə yerdəyişmələr mümkündür → sequence və bərpa buferi istifadə edin.

SQS FIFO

Exactly-once processing (səmərəli, babasının hesabına) və MessageGroupId daxilində nizam. Paralellik - qrupların sayı, qrup daxilində head-of-line.

Google Pub/Sub

Ordering key açar daxilində sifariş verir; səhv olduqda, nəşr bərpa əvvəl bloklanır - backpressure izləyin.


7) Qaydanın qorunması və bərpası nümunələri

7. 1 Sequence/versiyası

Hər bir hadisə 'seq '/' version' daşıyır. Konsumer:
  • hadisəni yalnız 'seq = last_seq + 1' olduqda qəbul edir;
  • əks halda - itkin gələnə qədər gözləmə tamponuna qoyur ('last _ seq + 1').
Psevdokod:
pseudo if seq == last+1: apply(); last++
else if seq > last+1: buffer[seq] = ev else: skip // дубль/повтор

7. 2 Buferlər və pəncərələr (stream processing)

Time-window + watermark: pəncərə daxilində out-of-order qəbul, watermark vasitəsilə pəncərəni «bağlayın» və nizamlayın.
Allowed lateness: gecikənlər üçün kanal (recompute/ignore).

7. 3 Sticky-routing açar

'hash (key)% shards' hash marşrutu bütün açar hadisələrini bir worker-ə göndərir.
Kubernetes-də - sessiyanı (sticky) L4 balanslayıcısında deyil, növbə/şerda səviyyəsində saxlayın.

7. 4 Actor modeli/« açar başına bir axın »

Kritik aqreqatlar üçün (pul kisəsi): aktyor ardıcıl olaraq emal edir, qalan paralellik - aktorların sayı ilə.

7. 5 İdempotentlik + reordering

Düzənin bərpası ilə belə təkrarlamalar mümkündür. UPSERT + versiyasını Inbox ilə birləşdirin (bax: «Exactly-once vs At-least-once»).


8) «zəhərli» mesajlarla işləmək (poison pills)

Sifarişin qorunması vəzifəsi ilə üzləşir: «Bir mesaj emal edilmədikdə necə yaşamaq olar?»

Ciddi sifariş: açar axını bloklanması (SQS FIFO: bütün qrup). Həll yolu - by-key DLQ: yalnız problem açarını/qrupunu ayrıca növbəyə/əl analizinə köçürürük.
Çevik sifariş: keçid/kompensasiya icazə; loging və davam (maliyyə/kritik aqreqatlar üçün deyil).
Retraj siyasəti: məhdud 'max-deliver' + backoff + avidempotent effektləri.


9) Multi-region və qlobal sistemlər

Cluster-linking/replikasiya (Kafka) regionlararası qlobal nizama zəmanət vermir. Yerli per-key sifarişinə və idempotent sinklərinə üstünlük verin.
truly-global order üçün sekvenser (mərkəzi log) istifadə edin, lakin bu əlçatanlığa təsir edir (CAP: şəbəkə boşluqlarında mənfi A).
Alternativ: bəzi domenlər (sayğaclar, çoxluqlar) üçün causal order + CRDT - ciddi sifariş tələb etmir.


10) Sıra müşahidə

Метрики: `out_of_order_total`, `reordered_in_window_total`, `late_events_total`, `buffer_size_current`, `blocked_keys_total`, `fifo_group_backlog`.

Логи: `key`, `seq`, `expected_seq`, `action=applybufferskipdlq`.
Trace: 'order _ key', 'partition', 'offset', 'seq' span atributları, retraya bağlantılar.

11) Anti-nümunələr

Bir sıra + açar olmadan bir çox konsumer - sifariş dərhal pozulur.
idempotency olmadan eyni sırada pere-publich vasitəsilə retrai - dubli + out-of-order.
Qlobal sifariş «hər ehtimala qarşı» - real faydası olmadan gizli və dəyərli partlayış.
SQS FIFO bütün bir qrup - tam baş-of-line. MessageGroupId per açarını istifadə edin.
"Qaynar açarlar 'a məhəl qoymamaq - bir" cüzdan "hər şeyi yavaşlatır; açarı mümkün olan yerdə alt açarlara bölün.
Kritik və bulk axınlarının bir sıra/qrupda qarışdırılması qarşılıqlı təsir və nizam itkisidir.


12) Giriş çek siyahısı

  • Zəmanət səviyyəsi müəyyən edilmişdir: per-key/per-partition/causal/global?
  • Sifariş açarı və "isti açarlar 'a qarşı strategiya hazırlanmışdır.
  • Router konfiqurasiya :/MessageGroupId/ordering key.
  • Konsumerlər açarlar (sticky-routing, shard-workers) ilə təcrid olunur.
  • Sinklərdə idempotentlik və/və ya Inbox/UPSERT daxildir.
  • sequence/version və bufer reordering həyata keçirilmişdir (lazım olduqda).
  • DLQ siyasəti by key və backoff ilə retrai.
  • Sıra metrikası və risklər: out-of-order, blocked_keys, late_events.
  • Game day: rebalance, düyün itkisi, «zəhərli» mesaj, şəbəkə gecikmələri.
  • Sənədləşmə: invariant sifariş, pəncərə sərhədləri, SLA təsir.

13) Konfiqurasiya nümunələri

13. 1 Kafka Consumer (qaydanın pozulmasını minimuma endirmək)

properties max.poll.records=500 enable.auto.commit=false  # коммит после успешной обработки батча isolation.level=read_committed
💡 Bir işçinin bütün partiyaları emal etməsinə və əməliyyatlarınızın idempotent olmasına əmin olun.

13. 2 RabbitMQ (paralellik bahasına sifariş)

Növbə üçün bir konsumer + 'basic. qos(prefetch=1)`

Paralellik üçün - bir neçə növbə və hash-exchange:
bash rabbitmq-plugins enable rabbitmq_consistent_hash_exchange публикуем с хедером/ключом для консистентного хеша

13. 3 SQS FIFO

MessageGroupId = key. Paralellik = qrupların sayı.
MessageDeduplicationId (provayder pəncərəsində).

13. 4 NATS JetStream (ordered consumer, eskiz)

bash nats consumer add ORDERS ORD-KEY-42 --filter "orders.42.>" --deliver pull \
--ack explicit --max-deliver 6
💡 Proqramda 'sequence' və tamponuna nəzarət edin.

14) FAQ

Q: Mən qlobal sifariş lazımdır?
A: Demək olar ki, heç vaxt. Demək olar ki, həmişə per-key kifayətdir. Qlobal nizam bahadır və əlçatanlığa zərbə vurur.

Q: ciddi qaydada «zəhərli» mesaj haqqında necə?
A: Yalnız onun açarını/qrupunu DLQ-yə köçürmək, qalanını davam etdirmək.

S: Sifariş və miqyas eyni vaxtda əldə edilə bilərmi?
A: Bəli, açar qaydası + bir çox açar/partiyalar + idempotent əməliyyatlar və lazımi yerlərdə tamponlar.

Q: Hansı daha vacibdir: sifariş və ya exactly-once?
A: Əksər domenlər üçün - açar qaydası + effektiv exactly-once effektləri (idempotentlik/UPSERT). Nəqliyyat at-least-once ola bilər.


15) Nəticələr

Sifariş biznes açarı ətrafında yerli zəmanətdir, bahalı qlobal intizam deyil. Açarları və hissələri layihələndirin, «qaynar» açarları məhdudlaşdırın, idempotluq və lazım olduqda sequence + bufer reordering istifadə edin. «Out-of-order» və «blocked keys» metriklərini izləyin, uğursuzluqları sınayın - və performans və əlçatanlıqda qurbanlar olmadan proqnozlaşdırıla bilən emal alacaqsınız.

Contact

Bizimlə əlaqə

Hər hansı sualınız və ya dəstək ehtiyacınız varsa — bizimlə əlaqə saxlayın.Həmişə köməyə hazırıq!

İnteqrasiyaya başla

Email — məcburidir. Telegram və ya WhatsApp — istəyə bağlıdır.

Adınız istəyə bağlı
Email istəyə bağlı
Mövzu istəyə bağlı
Mesaj istəyə bağlı
Telegram istəyə bağlı
@
Əgər Telegram daxil etsəniz — Email ilə yanaşı orada da cavab verəcəyik.
WhatsApp istəyə bağlı
Format: ölkə kodu + nömrə (məsələn, +994XXXXXXXXX).

Düyməyə basmaqla məlumatların işlənməsinə razılıq vermiş olursunuz.