GH GambleHub

메시지 순서 보증

1) "주문" 이란 무엇이며 왜 필요한가

메시지 순서는 한 엔티티 (주문, 사용자, 지갑) 또는 전체 스트림의 이벤트에 대한 "전에 처리해야 할 것" 관계입니다. 불변자에게는 중요합니다: "B 이전 상태", "상각 전 균형", "n + 1 이전 버전".
분산 시스템에서 전 세계 총 주문은 비싸고 거의 필요하지 않습니다. 로컬 키당 주문으로 충분합니다.


2) 질서 보장 유형

1. 파티션 당 (로그 섹션의 로컬 순서) -Kafka: 당사자 내 순서는 당사자 간에 유지됩니다.
2. 키 당 (키/메시지 그룹 주문) -하나의 키가있는 모든 메시지는 하나의 "스레드" 처리 (Kafka key, SQS FIFO MessageGroupID, Pub/Sub 주문 키) 로 라우팅됩니다.
3. 전 세계 총 순서-전체 시스템에는 단일 순서 (분산 저널/시퀀서) 가 표시됩니다. 비용이 많이 들고 가용성과 처리량이 저하됩니다.
4. 인과 순서- "B가 효과를 관찰하면 A 이후의 이벤트 B" 글로벌 시퀀서없이 메타 데이터 (버전, Lamport 시간/벡터 시계) 를 통해 회복 할 수 있습니다.
5. 최선의 노력 주문-중개인은 주문을 유지하려고 시도하지만 실패시 순열이 가능합니다 (종종 NATS Core, RabbitMQ에서 여러 소비자가 있음).


3) 주문이 무너지는 곳

동일한 큐의 병렬 소비자 (RabbitMQ: 큐당 여러 소비자 → 인터리빙).
배달/재 배달 (적어도 한 번), 'ack' 타임 아웃, 다시 큐잉.
재 균형/페일 오버 (Kafka: 파티/리더 이동).
DLQ/재 처리-" 유독 한 "메시지는 DLQ로갑니다. 다음 메시지는 추가 → 논리적 중단입니다.
다중 영역 및 복제-다른 지연 → 오정렬.


4) 주요 주문 설계

핵심은 "주문 단위" 를 형성합니다. "권장 사항:
  • 자연 키 사용: 'order _ id', 'wallet _ id', 'colligate _ id'.
  • "핫 키" 를보십시오. 하나의 키는 흐름을 "차단" 할 수 있습니다 (헤드 오브 라인 차단). 필요한 경우 키를 나눕니다. 'order _ id # shard (0.. k-1) '은 싱크대에서 순서를 결정 론적으로 재구성합니다.
  • Kafka-하나의 키 → 하나의 부분에서 순서는 키 내에 보존됩니다.
예 (Kafka, Java):
java producer.send(new ProducerRecord<>("orders", orderId, eventBytes));

(Key = 'orderID' 는 로컬 주문을 보장합니다.)


5) "주문 대 대역폭"

강력한 보증은 종종 처리량 및 가용성과 충돌합니다

대기열 당 한 명의 소비자가 주문을 유지하지만 동시성을 줄입니

적어도 한 번 + 동시성은 성능을 향상 시키지만 demempotency 및/또는 재정렬이 필요합니다.
글로벌 주문은 시퀀서에 홉 → latentnost 및 실패 위험에 홉을 추가합니다.

타협: 키 당 순서, 병렬 처리 = 당사자/그룹 수, + dempotent 타박상.


6) 특정 중개인의 주문 통제

카프카

파티 내에서 주문.
관찰 '최대. 에서. 비행. 요청. per. 연결을 사용할 수 있습니다. 생산자의 배상금이 순서를 변경하지 않도록 demempotence = 참 '.
소비자 그룹: 한 당사자 → 한 번에 한 명의 근로자. 반복 배송이 가능합니다 → 비즈니스 계층에서 시퀀스/버전을 유지하십시오.
읽기 프로세스 쓰기 트랜잭션은 읽기/쓰기/부스러기 오프셋 일관성을 유지하지만 글로벌 주문을 만들지는 않습니다.

생산 최소 (생산자. 속성):
properties enable.idempotence=true acks=all retries=2147483647 max.in.flight.requests.per.connection=5

RabbitMQ (AMQP)

주문은 하나의 여름 동안 하나의 대기열로 보장됩니다. 메시지의 여러 소비자와 함께 "혼합" 될 수 있습니다.
순서대로: 완료되면 하나의 consummer 또는 prefetch = 1 + ack. 동시성의 경우 키별로 분리 된 대기열 (샤딩 교환/일관된 해시 교환).

NATS/제트 스트림

NATS Core-최선의 노력, 낮은 대기 시간, 주문이 방해 될 수 있습니다.
JetStream: 스트림/시퀀스 내에서 주문; 재배송 중에 콘솔의 재 배열이 가능합니다. → 시퀀스 및 복구 버퍼를 사용할 수 있습니다.

SQS FIFO

정확히 한 번 처리 (효과적으로 중복으로 인해) 및 MessageGroupID 내의 순서. 동시성-헤드 라인 그룹 내 그룹 수.

구글 펍/서브

주문 키는 키 내에서 주문을 제공합니다. 오류가 발생하면 복원 될 때까지 게시가 차단됩니다. 역압을 조심하십시오.


7) 순서 보존 및 복원 패턴

7. 1 시퀀스/버전 지정

각 이벤트에는 'seq '/' 버전' 이 있습니다. 회중:
  • 'seq = last _ seq + 1' 인 경우에만 이벤트를 수행합니다.
  • 그렇지 않으면 누락 된 버퍼가 도착하기 전에 대기 버퍼를 넣으십시오 ('last _ seq + 1').
의사 코드:
pseudo if seq == last+1: apply(); last++
else if seq > last+1: buffer[seq] = ev else: skip // дубль/повтор

7. 버퍼 및 창 2 개 (스트림 처리)

시간 창 + 워터 마크: 워터 마크에 따라 창을 "닫고" 정렬합니다.
지연 시간 허용: 늦게 도착할 수있는 채널 (재 컴파일/무시).

7. 키별로 3 끈적 끈적한 라우팅

해시 (키)% 파편 해시 라우팅은 모든 주요 이벤트를 단일 작업자에게 보냅니다.
Kubernetes에서-L4 HTBalancer가 아닌 대기열/sherds 레벨에서 세션 (고정) 을 유지합니다.

7. 4 배우 모델/" 키당 하나의 스트림 "

중요한 집계 (지갑) 의 경우: 배우가 순차적으로 처리하고 나머지 병렬 처리-배우의 수.

7. 5 Idempotence + 재정렬

질서가 회복되더라도 반복이 가능합니다. 키 + 버전과받은 편지함으로 UPSERT를 결합하십시오 (정확히 한 번 vs 최소 한 번 참조).


8) "독" 메시지로 작업 (독 약)

"하나의 메시지가 처리되지 않으면 어떻게 살아야합니까?"

엄격한 순서: 키 흐름 차단 (SQS FIFO: 전체 그룹). 솔루션은 키별로 DLQ입니다. 문제 키/그룹 만 별도의 큐/수동 구문 분석으로 전송합니다.
유연한 주문: 건너 뛰기/보상이 가능합니다. 우리는 로그인하고 계속합니다 (금융/임계 집계가 아님).
재 트레이 정책: 제한된 'max-advery' + backoff + avidempotent 효과.


9) 다중 지역 및 글로벌 시스템

클러스터 연결/복제 (Kafka) 는 지역 간 글로벌 주문을 보장하지 않습니다. 로컬 키당 주문 및 demmpotent 타박상을 우선시하십시오.
진정한 글로벌 순서의 경우 시퀀서 (중앙 로그) 를 사용하지만 이는 가용성 (CAP: 네트워크 중단의 경우 A 빼기) 에 영향을줍니다.
대안: 일부 도메인 (카운터, 세트) 에 대한 인과 순서 + CRDT-엄격한 순서가 필요하지 않습니다.


10) 순서의 관찰 가능성

(PHP 3 = 3.0.6, PHP 4)

확인: 'key', 'seq', 'respended _ seq', 'action = 적용버퍼건너 뛰기dlq '.
추적: 스팬 'order _ key', 'partition', 'offset', 'seq' 의 속성은 배상에 대한 참조입니다.

11) 반 패턴

키를 깎지 않고 한 대기열 + 많은 소비자-주문이 즉시 분류됩니다.
dempotency없이 동일한 대기열에서 다시 공개하여 두 배로 증가합니다.
전 세계 "경우에 따라" 순서는 실질적인 이점이없는 대기 시간과 가치의 폭발입니다.
SQS FIFO는 모든 그룹을위한 하나의 그룹입니다. 키 당 MessageGroupId를 사용하십시오.
"핫 키" 를 무시하십시오-하나의 "지갑" 은 모든 것을 느리게합니다. 가능한 경우 키를 하위 키로 나눕니다.
동일한 대기열/그룹에서 중요 및 벌크 스트림을 혼합-상호 영향 및 순서 상실.


12) 구현 점검표

  • 키/파티션 당/인과/글로벌?
  • 시퀀싱 키 및 핫 키 전략이 설계되었습니다.
  • 라우터 구성: 파티셔닝/MessageGroupID/주문 키.
  • 콘솔은 열쇠 (끈적 끈적한 라우팅, 파편 작업자) 에 의해 분리됩니다.
  • 타박상에 대한 이데올로기 및/또는받은 편지함/UPSERT가 포함되어 있습니다.
  • 시퀀스/버전 구현 및 버퍼 재정렬 (필요한 경우).
  • 주요 정책 및 백오프 배상에 의하여 DLQ.
  • 주문 외, 차단 된 _ keys, 늦은 _ 이벤트 순서 및 경고 메트릭스.
  • 게임 데이: 재조정, 노드 손실, 유독 한 메시지, 네트워크 지연.
  • 문서: 순서 불변, 창 경계, SLA에 미치는 영향.

13) 설정 예

13. 1 카프카 소비자 (주문 위반 최소화)

properties max.poll.records=500 enable.auto.commit=false  # коммит после успешной обработки батча isolation.level=read_committed
💡 한 명의 작업자가 전체 당사자를 처리하고 귀하의 운영이 유쾌한 지 확인하십시오.

13. 2 RabbitMQ (동시성 가격 별 주문)

대기열 당 하나의 소비자 + '기본. qos (프리 페치 = 1) '

동시성-여러 대기열 및 해시 교환:
bash rabbitmq-plugins enable rabbitmq_consistent_hash_exchange публикуем с хедером/ключом для консистентного хеша

13. 3 SQS FIFO

메사지그룹 = 키를 설정합니다. 동시성 = 그룹 수.
복제물로부터 보호하기위한 MessageDeduplicationID (공급자 창에서).

13. 4 NATS JetStream (주문 소비자, 스케치)

bash nats consumer add ORDERS ORD-KEY-42 --filter "orders.42.>" --deliver pull \
--ack explicit --max-deliver 6

키> 응용 프로그램에서 '시퀀스' 를 모니터링하고 버퍼를 재정렬합니다.


14) FAQ

Q: 글로벌 주문이 필요합니까?
A: 거의 없습니다. 거의 항상 키로 충분합니다. 전 세계 질서는 비싸고 경제성이 뛰어납니다.

Q: 엄격한 순서로 "유독 한" 메시지는 어떻습니까?
A: 키/그룹 만 DLQ로 이전하면 나머지는 계속됩니다.

Q: 동시에 주문과 규모를 확장 할 수 있습니까?
A: 예, 키 주문 + 많은 키/부품 + dempotent 작업 및 필요한 경우 버퍼 재정렬.

Q: 더 중요한 것은: 주문 또는 정확히 한 번입니까?
A: 대부분의 도메인-키 오더 + 효과적으로 정확히 한 번의 효과 (dedempotency/UPSERT). 운송은 적어도 한 번은 가능합니다.


15) 총계

주문은 비싼 글로벌 규율이 아니라 비즈니스 키에 대한 지역 보증입니다. 키 및 파티를 설계하고 핫 키를 제한하며 demempotence를 사용하고 필요한 경우 시퀀스 + 재정렬 버퍼를 사용하십시오. 순서가 맞지 않고 차단 된 키 메트릭, 테스트 충돌을 조심하면 성능이나 가용성을 희생하지 않고 예측 가능한 처리를받을 수 있습니다.

Contact

문의하기

질문이나 지원이 필요하시면 언제든지 연락하십시오.우리는 항상 도울 준비가 되어 있습니다!

통합 시작

Email — 필수. Telegram 또는 WhatsApp — 선택 사항.

이름 선택 사항
Email 선택 사항
제목 선택 사항
메시지 선택 사항
Telegram 선택 사항
@
Telegram을 입력하시면 Email과 함께 Telegram에서도 답변드립니다.
WhatsApp 선택 사항
형식: +국가 코드 + 번호 (예: +82XXXXXXXXX).

버튼을 클릭하면 데이터 처리에 동의하는 것으로 간주됩니다.