GH GambleHub

모델 및 프로젝션 읽기

읽기 모델은 특정 제품 시나리오에 대한 빠른 읽기를 위해 특별히 설계된 테이블/색인/뷰입니다. 프로젝션은 소스 이벤트/변경 사항을 읽기 모델 업데이트 (일반적으로 dempotent upsert) 로 변환하는 프로세스입니다. CQRS와 함께 OLTP 코어를 내리고 p95/p99 판독을 안정화하여 "신선도" 를 제어 할 수 있습니다.

주요 아이디어:
  • "범용 제도" 가 아니라 요청에 따라 거부.
  • 점진적으로 그리고 엄청나게 업데이트하십시오
  • 정체성과 질서를 명시 적으로 관리합니다.

1) 읽기 모델 사용시기 (및 그렇지 않은 경우)

적합:
  • 허용 가능한 업데이트 대기 시간이있는 빈번한 무거운 읽기 (가입/집계/정렬).
  • 대시 보드, 카탈로그, 방문 페이지, "top-N", 개인 피드, 검색 목록.
  • 로드 공유: 쓰기 코어-엄격하고 읽기 평면-빠르고 확장 가능합니다.
적합하지 않음:
  • 엄격한 불변량이 필요한 작업 "입력 당" (돈, 독창성). 강한 길이 있습니다.

2) 건축 개요 (언어 체계)

1. 변경 사항: OLTP의 도메인 이벤트 (이벤트 소싱) 또는 CDC 이벤트.
2. 투영 파이프 라인: parser → 집계/비정규화 → demempotent upsert.
3. 읽기 저장소: 쿼리에 최적화 된 데이터베이스/색인 (RDBMS, 열, 검색).
4. API/클라이언트: "as _ of/freshness" 속성을 가진 빠른 SELECT/GET.

3) 모델 디자인 읽기

쿼리로 시작하십시오: 어떤 필드, 필터, 정렬, 페이지 매김, 상단 N?
Denormalize: 이미 병합 된 데이터 (이름, 금액, 상태) 를 저장합니다.

키:
  • 파티션: '테넌트 _ id', 날짜, 지역별.
  • 기본 키: 비즈니스 키 + 타임 버킷 (예: '(테넌트 _ id, 엔티티 _ id)' 또는 '(테넌트 _ id, 버킷 _ 분)').
  • 색인: 빈번한 위치/주문.
  • TTL/보존: 임시 디스플레이 사례 (예: 90 일).

4) 흐름 및 demmpotency 업데이트

Idempotent upsert는 투영 안정성의 기초입니다.

의사:
sql
-- Projection table
CREATE TABLE read_orders (
tenant_id  TEXT,
order_id  UUID,
status   TEXT,
total    NUMERIC(12,2),
customer  JSONB,
updated_at TIMESTAMP,
PRIMARY KEY (tenant_id, order_id)
);

-- Idempotent update by event
INSERT INTO read_orders(tenant_id, order_id, status, total, customer, updated_at)
VALUES (:tenant,:id,:status,:total,:customer,:ts)
ON CONFLICT (tenant_id, order_id) DO UPDATE
SET status = EXCLUDED. status,
total = EXCLUDED. total,
customer = COALESCE(EXCLUDED. customer, read_orders. customer),
updated_at = GREATEST(EXCLUDED. updated_at, read_orders. updated_at);
규칙:
  • 각 메시지에는 버전/시간이 있습니다. "신선하거나 동등한" (demempotency) 만 허용합니다.
  • 집계 (카운터, 합계) 의 경우-상태를 저장하고 정류 업데이트 (또는 CRDT 접근 방식) 를 사용하십시오.

5) 변화의 출처: 이벤트 vs CDC

이벤트 (이벤트 소싱): 풍부한 의미론, 다른 프로젝션을 쉽게 구축 할 수 있습니다. 회로의 진화가 중요합니다.
CDC (논리 복제): 간단히 기존 데이터베이스에 연결하십시오. DML → sobyty 매핑 및 노이즈 업데이트 필터링이 필요합니다.

두 옵션 모두 다음이 필요합니

"유독 한" 메시지에 대한 배송 보장 (적어도 한 번) 및 DLQ.
키별로 주문 (파티션 키 = 'tenant _ id: 엔티티 _ id').

6) 질서, 인과 관계 및 "신선도"

키별로: 한 객체의 이벤트는 순차적으로 와야합니다. 파티셔닝 및 버전을 사용하십시오

세션/인과: 저자가 변경 사항 (RYW) 을 보려면 워터 마크 버전을 쿼리로 전달하십시오.
경계 정체: 'of _ of '/' X-Data-Freshness' 로 반환하고 SLO 보유 (예: p95 소 60c).

7) 증분 집계 및 상위 N

미세한 판매 버킷의 예:
sql
CREATE TABLE read_sales_minute (
tenant_id TEXT,
bucket  TIMESTAMP, -- toStartOfMinute revenue  NUMERIC(14,2),
orders  INT,
PRIMARY KEY (tenant_id, bucket)
);

-- Update by Event
INSERT INTO read_sales_minute(tenant_id, bucket, revenue, orders)
VALUES (:tenant,:bucket,:amount, 1)
ON CONFLICT (tenant_id, bucket) DO UPDATE
SET revenue = read_sales_minute. revenue + EXCLUDED. revenue,
orders = read_sales_minute. orders + 1;
Top N의 경우:
  • 순위 쇼케이스 (예: '수익 DESC') 를 유지하고 변경된 위치 (힙/건너 뛰기/제한 테이블) 만 업데이트하십시오.
  • 상단의 "창" 을 저장하십시오 (예: 세그먼트 당 100-1000 줄).

8) 검색 및 지리 투영

검색 (ES/OpenSearch): 비정규화 된 문서, 파이프 라인 변환, 문서 버전 = 소스 버전.
지오: 'POINT/LAT, LON', 사전 집계 타일/쿼드를 저장하십시오.

9) 멀티 테넌트 및 지역

프로젝션 키 및 이벤트에는 '테넌트 _ id' 가 필요합니다.
공정성: "잡음" 이 나머지 속도를 늦추지 않도록 테넌트 당 투영 처리량 (WFQ/DRR) 을 제한하십시오.
거주지: 투영은 쓰기 코어와 같은 지역에 있습니다. 지역 간 쇼케이스-집계/요약.

10) 관찰 및 SLO

메트릭:
  • 'project _ lag _ ms' (istochnik → vitrina), 'freshness _ age _ ms' (마지막 델타 이후).
  • 업데이트 처리, 오류율, DLQ 속도, 재 구동 성공.
  • 창 크기, p95/p99 판독 대기 시간.
추적/통나무:
  • 지정 번호: '테넌트 _ id', '엔티티 _ id', '이벤트 _ id', '버전', '투영 _ 네임', '시도'.
  • 주석: 솔루션 병합, 오래된 버전의 생략.

11) 플레이 북 (런북)

1. 성장 지연: 커넥터/브로커 확인, 당사자 증가, 주요 쇼케이스 우선 순위 지정 등이 있습니다.
2. 많은 스키마 오류: 리드라이브 동결, 스키마 마이그레이션 (백필), 새 버전의 매퍼로 다시 시작하십시오.
3. 반복 된 DLQ: 배치를 줄이고 "그림자" 핸들러를 활성화하며 demempotency를 증가시킵니다.
4. 창 불일치: 창 당 로그/소스에서 창을 다시 만듭니다 (테넌트/파티션 선택).
5. 핫 키: 키별로 경쟁을 제한하고 로컬 대기열을 추가하고 별도의 쇼케이스에 장치를 배치하십시오.

12) 전체 재 계산 (재건) 및 백필

접근 방식:
  • 소비 중지 (또는 새로운 버전의 쇼케이스로 전환).
  • 배치/날짜/테넌트별로 재구성하십시오.
  • 2 단계 스위치 사용: 먼저 '읽기 _ _ v2' 를 채운 다음 읽기 라우팅을 원자 적으로 전환하십시오.

13) 회로의 진화 (버전)

'스키마 _ 버전' 이벤트/문서.

프로젝션은 여러 버전을 읽고 즉시 마이그레이션 할 수 있습니다

주요 변경 사항-새로운 v2 쇼케이스 및 카나리아 트래픽.

14) 보안 및 액세스

소스에서 상속 RLS/ACL; 쇼케이스를 원래 데이터보다 더 넓게 액세스하지 마십시오.
UX/분석에 필요하지 않은 프로젝션의 마스크 PII.
재구성/재 계산/수동 편집 감사.

15) 설정 템플릿

yaml projections:
read_orders:
source: kafka. orders. events partition_key: "{tenant_id}:{order_id}"
idempotency: version_ts upsert:
table: read_orders conflict_keys: [tenant_id, order_id]
freshness_slo_ms: 60000 dlq:
topic: orders. events. dlq redrive:
batch: 500 rate_limit_per_sec: 50 read_sales_minute:
source: cdc. orders partition_key: "{tenant_id}:{bucket_minute}"
aggregate: increment retention_days: 90 limits:
per_tenant_parallelism: 4 per_key_serial: true observability:
metrics: [projection_lag_ms, dlq_rate, redrive_success, read_p95_ms]

16) 전형적인 오류

"모든 사례에 대한 하나의 쇼케이스" → 무거운 업데이트 및 나쁜 p99.
dempotency → 부족은 집계로 복제/점프합니다.
쇼케이스 및 OLTP → 불일치에 직접 이중 쓰기.
신선도의 가시성이 제로이므로 제품과 기대치가 상충됩니다.
답변에서 2 상 스위치없이 → "홀" 을 다시 구축하십시오.
분할/인덱스 → 비용 및 대기 시간 성장이 없습니다.

17) 빠른 레시피

카탈로그/검색: 문서 쇼케이스 + 증분 확대, 지연 5-15 초, 필터 색인.

대시 보드: 분/시간 탱크, 'SUM/COUNT' 장치, p95 신선도

개인 테이프: 저자를위한 사용자 + 인과/RYW에 의한 투영, 캐시로 대체.
Global SaaS: 지역 쇼케이스, 지역 간 집계; 임차인 당 공정성.

18) 사전 판매 점검표

  • 쇼케이스는 특정 요청을 위해 설계되었습니다. 지수와 당사자가 있습니다.
  • 선택된 변경 출처 (이벤트/CDC); 배송 보증 및 주요 주문.
  • 버전/시간에 대한 이념적 확신; "오래된" 이벤트에 대한 보호.
  • 신선도 SLO가 정의되고 응답됩니다 ('_ of/freshness').
  • DLQ 및 보안 릴리스 구성; 재건/백필에 대한 플레이 북.
  • 세입자 당 키 당 연속 및 공정성.
  • 래그/오류/대기 시간 지표, p95/p99 경고 및 DLQ 성장.
  • 서킷 버전 지정 및 마이그레이션 전략 (v2 + 스위치).
  • 액세스/PII 정책은 상속 및 검증됩니다.

결론

읽기 모델 및 프로젝션은 읽기의 엔지니어링 액셀러레이터입니다. "신선도" 및 스트리밍 인프라에 대해 적은 가격을 지불하여 예측 가능한 밀리 초를 얻고 녹음의 핵심을 오프로드합니다. 디자인 상점은 귀하의 요청에 맞게 업데이트를 업데이트하고 지연을 측정하며 신선도를 명확하게 약속합니다. API는로드, 데이터 및 지리가 증가하더라도 빠르게 유지됩니다.

Contact

문의하기

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

통합 시작

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

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

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