<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Kafka on Thanh HV's Blog</title><link>https://thanhhv.github.io/tags/kafka/</link><description>Recent content in Kafka on Thanh HV's Blog</description><generator>Hugo -- 0.146.7</generator><language>en-us</language><lastBuildDate>Fri, 03 Jul 2026 12:00:00 +0700</lastBuildDate><atom:link href="https://thanhhv.github.io/tags/kafka/index.xml" rel="self" type="application/rss+xml"/><item><title>Bài 5 — Message Queue &amp; API</title><link>https://thanhhv.github.io/series/backend-interview/05-message-queue-api/</link><pubDate>Fri, 03 Jul 2026 12:00:00 +0700</pubDate><guid>https://thanhhv.github.io/series/backend-interview/05-message-queue-api/</guid><description>&lt;hr>
&lt;h1 id="phần-a--message-queue">PHẦN A — MESSAGE QUEUE&lt;/h1>
&lt;h2 id="câu-1--intermediate--senior-kafka-hoạt-động-thế-nào-tại-sao-nó-đạt-throughput-hàng-triệu-messagegiây">Câu 1 — [Intermediate → Senior] Kafka hoạt động thế nào? Tại sao nó đạt throughput hàng triệu message/giây?&lt;/h2>
&lt;h3 id="1-câu-hỏi">1. Câu hỏi&lt;/h3>
&lt;p>&amp;ldquo;Kiến trúc Kafka: topic, partition, consumer group, offset. Điều gì cho phép Kafka nhanh như vậy trên phần cứng thường?&amp;rdquo;&lt;/p>
&lt;h3 id="2-interviewer-muốn-kiểm-tra-điều-gì">2. Interviewer muốn kiểm tra điều gì?&lt;/h3>
&lt;ul>
&lt;li>Hiểu Kafka là &lt;strong>distributed log&lt;/strong>, không phải message queue truyền thống — khác biệt định hình mọi tính chất.&lt;/li>
&lt;li>Giải thích được nguồn hiệu năng bằng cơ chế cụ thể (sequential I/O, zero-copy, batching), không phải &amp;ldquo;Kafka nhanh vì được thiết kế tốt&amp;rdquo;.&lt;/li>
&lt;li>Nắm ordering, rebalance, lag — các khái niệm vận hành hằng ngày.&lt;/li>
&lt;/ul>
&lt;h3 id="3-câu-trả-lời-ngắn-gọn-30-giây">3. Câu trả lời ngắn gọn (30 giây)&lt;/h3>
&lt;p>&amp;ldquo;Kafka là log phân tán: topic chia thành partition, mỗi partition là file log append-only có thứ tự; message không bị xóa khi đọc mà giữ theo retention; consumer tự quản offset của mình. Consumer group chia partition cho các consumer — scale đọc bằng cách thêm consumer tới tối đa = số partition. Nhanh nhờ: ghi/đọc &lt;strong>tuần tự&lt;/strong> trên đĩa (nhanh gần bằng RAM, tận dụng page cache OS), &lt;strong>zero-copy&lt;/strong> (sendfile — dữ liệu từ page cache thẳng ra socket không qua user space), &lt;strong>batching + nén&lt;/strong> cả lô, và broker cực kỳ &amp;rsquo;ngu&amp;rsquo; — không track trạng thái từng message như RabbitMQ, chỉ là cái log có index.&amp;rdquo;&lt;/p></description></item><item><title>Bài 11 (Nâng cao) — Cơ chế lưu trữ: vì sao Kafka nhanh</title><link>https://thanhhv.github.io/series/kafka/11-storage-internals/</link><pubDate>Mon, 25 May 2026 08:00:00 +0700</pubDate><guid>https://thanhhv.github.io/series/kafka/11-storage-internals/</guid><description>&lt;p>Tốc độ Kafka đến từ &lt;strong>bốn quyết định thiết kế cộng hưởng&lt;/strong>, không phải một mẹo.&lt;/p>
&lt;h2 id="1-ghi-tuần-tự-sequential-write">1. Ghi tuần tự (sequential write)&lt;/h2>
&lt;p>Trực giác sai: &amp;ldquo;ghi đĩa chậm, phải dùng RAM&amp;rdquo;. Thực tế: &lt;strong>ghi đĩa &lt;em>tuần tự&lt;/em> nhanh hơn ghi RAM &lt;em>ngẫu nhiên&lt;/em>.&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>Random access (DB cập nhật chỗ này chỗ kia): tốn seek, chậm cả HDD lẫn SSD.&lt;/li>
&lt;li>Sequential write: chỉ ghi nối tiếp vào cuối file, không seek — HDD ~100s MB/s, SSD cao hơn.&lt;/li>
&lt;/ul>
&lt;p>Kafka chọn &lt;strong>log append-only&lt;/strong>: message mới luôn ghi vào &lt;em>cuối&lt;/em>, không sửa/chèn. Đây là lý do sâu xa Kafka không cho xóa/sửa message — ràng buộc có chủ đích để đổi lấy tốc độ.&lt;/p></description></item><item><title>Bài 10 — Kiến trúc thực chiến</title><link>https://thanhhv.github.io/series/kafka/10-kien-truc-thuc-chien/</link><pubDate>Sat, 23 May 2026 08:00:00 +0700</pubDate><guid>https://thanhhv.github.io/series/kafka/10-kien-truc-thuc-chien/</guid><description>&lt;h2 id="outbox-pattern--giải-bài-toán-dual-write">Outbox Pattern — giải bài toán &amp;ldquo;dual write&amp;rdquo;&lt;/h2>
&lt;p>Service order phải ghi vào &lt;strong>DB&lt;/strong> và bắn event lên &lt;strong>Kafka&lt;/strong>. Làm tuần tự thì luôn có khe hở:&lt;/p>
&lt;pre tabindex="0">&lt;code>ghi DB OK -&amp;gt; bắn Kafka FAIL =&amp;gt; DB có đơn, hệ thống khác không biết (lệch)
bắn Kafka OK -&amp;gt; ghi DB FAIL =&amp;gt; event bắn rồi nhưng đơn không tồn tại (ma)
&lt;/code>&lt;/pre>&lt;p>Hai hệ thống khác nhau không chia sẻ transaction → không thể &amp;ldquo;cùng thành công hoặc cùng thất bại&amp;rdquo; trực tiếp.&lt;/p></description></item><item><title>Bài 9 — Performance Tuning</title><link>https://thanhhv.github.io/series/kafka/09-performance-tuning/</link><pubDate>Wed, 20 May 2026 08:00:00 +0700</pubDate><guid>https://thanhhv.github.io/series/kafka/09-performance-tuning/</guid><description>&lt;blockquote>
&lt;p>Mọi tinh chỉnh là đánh đổi giữa &lt;strong>throughput&lt;/strong> (số lượng/giây), &lt;strong>latency&lt;/strong> (độ trễ mỗi message), và &lt;strong>durability&lt;/strong>. Không có nút &amp;ldquo;nhanh hơn&amp;rdquo; miễn phí.&lt;/p>&lt;/blockquote>
&lt;h2 id="phía-producer--gom-để-nhanh">Phía Producer — gom để nhanh&lt;/h2>
&lt;p>&lt;strong>&lt;code>linger.ms&lt;/code> + &lt;code>batch.size&lt;/code>&lt;/strong> (cặp quan trọng nhất). Mặc định &lt;code>linger.ms=0&lt;/code> = gửi ngay từng message → nhiều request nhỏ. Tăng &lt;code>linger.ms&lt;/code> (5–20ms) cho producer chờ gom batch rồi gửi một lần. &lt;code>batch.size&lt;/code> (mặc định 16KB) là trần mỗi batch.&lt;/p></description></item><item><title>Bài 8 — Schema Registry &amp; Schema Evolution</title><link>https://thanhhv.github.io/series/kafka/08-schema-registry-evolution/</link><pubDate>Sun, 17 May 2026 08:00:00 +0700</pubDate><guid>https://thanhhv.github.io/series/kafka/08-schema-registry-evolution/</guid><description>&lt;h2 id="vấn-đề">Vấn đề&lt;/h2>
&lt;p>Topic được nhiều team ghi/đọc. Một ngày team A đổi cấu trúc message (đổi tên field, đổi kiểu, bỏ field) → consumer của B, C, D &lt;strong>vỡ ngay&lt;/strong>, thường lúc 2h sáng. JSON tự do có 3 điểm yếu ở quy mô lớn: không có schema bắt buộc, tốn băng thông (lặp tên field), không kiểm soát thay đổi.&lt;/p>
&lt;h2 id="schema-registry-hoạt-động-thế-nào">Schema Registry hoạt động thế nào&lt;/h2>
&lt;p>Service riêng lưu và đánh version cho schema:&lt;/p></description></item><item><title>Bài 7 — Retry, Backoff &amp; Dead Letter Queue</title><link>https://thanhhv.github.io/series/kafka/07-retry-backoff-dlq/</link><pubDate>Thu, 14 May 2026 08:00:00 +0700</pubDate><guid>https://thanhhv.github.io/series/kafka/07-retry-backoff-dlq/</guid><description>&lt;blockquote>
&lt;p>Triết lý: &lt;strong>fail gracefully, đừng fail catastrophically.&lt;/strong> Một message hỏng là chuyện bình thường; mục tiêu là nó &lt;strong>không kéo cả partition/hệ thống sập&lt;/strong>.&lt;/p>&lt;/blockquote>
&lt;h2 id="hai-loại-lỗi--phân-biệt-được-mới-xử-lý-đúng">Hai loại lỗi — phân biệt được mới xử lý đúng&lt;/h2>
&lt;ul>
&lt;li>&lt;strong>Tạm thời (transient):&lt;/strong> DB timeout, API phụ thuộc down, mạng chập chờn. → &lt;strong>retry&lt;/strong> sẽ qua.&lt;/li>
&lt;li>&lt;strong>Vĩnh viễn (permanent / &amp;ldquo;poison&amp;rdquo;):&lt;/strong> sai format, thiếu field, vi phạm nghiệp vụ. → retry vô ích, đẩy đi chỗ khác.&lt;/li>
&lt;/ul>
&lt;p>Ánh xạ HTTP status hữu ích:&lt;/p></description></item><item><title>Bài 6 — Idempotent Producer &amp; Transactions (Exactly-Once)</title><link>https://thanhhv.github.io/series/kafka/06-transactions-exactly-once/</link><pubDate>Tue, 12 May 2026 08:00:00 +0700</pubDate><guid>https://thanhhv.github.io/series/kafka/06-transactions-exactly-once/</guid><description>&lt;h2 id="vấn-đề-1--duplicate-do-producer-retry">Vấn đề 1 — Duplicate do PRODUCER retry&lt;/h2>
&lt;p>Producer gửi message, broker &lt;strong>đã ghi thành công&lt;/strong> nhưng gói ACK &lt;strong>rớt trên đường về&lt;/strong>. Producer tưởng thất bại → retry → broker ghi &lt;strong>lần hai&lt;/strong>. Message nằm 2 lần trong log dù bạn làm đúng mọi thứ. (Khác với duplicate phía consumer ở Bài 4.)&lt;/p>
&lt;h3 id="giải-pháp--idempotent-producer">Giải pháp — Idempotent Producer&lt;/h3>
&lt;p>&lt;code>enable.idempotence=true&lt;/code>: broker cấp mỗi producer một &lt;strong>PID&lt;/strong> và mỗi message một &lt;strong>sequence number&lt;/strong> theo partition. Retry mang sequence đã thấy → broker &lt;strong>lặng lẽ bỏ qua&lt;/strong>. Thêm bảo đảm thứ tự không bị đảo khi retry.&lt;/p></description></item><item><title>Bài 5 — Replication, acks &amp; ISR</title><link>https://thanhhv.github.io/series/kafka/05-replication-acks-isr/</link><pubDate>Sun, 10 May 2026 08:00:00 +0700</pubDate><guid>https://thanhhv.github.io/series/kafka/05-replication-acks-isr/</guid><description>&lt;h2 id="replica-leader-follower">Replica, Leader, Follower&lt;/h2>
&lt;p>Mỗi partition có N bản sao (replication-factor):&lt;/p>
&lt;ul>
&lt;li>&lt;strong>1 leader&lt;/strong>: phục vụ mọi đọc/ghi của client.&lt;/li>
&lt;li>&lt;strong>N-1 follower&lt;/strong>: liên tục kéo dữ liệu từ leader để bắt kịp. Ẩn với client.&lt;/li>
&lt;/ul>
&lt;p>Client &lt;strong>chỉ làm việc với leader&lt;/strong>. Follower chỉ để chống mất dữ liệu khi broker chứa leader chết.&lt;/p>
&lt;h2 id="isr-in-sync-replicas">ISR (In-Sync Replicas)&lt;/h2>
&lt;p>Tập các replica &lt;strong>đang theo kịp&lt;/strong> leader (gồm cả leader). Follower tụt quá &lt;code>replica.lag.time.max.ms&lt;/code> (~30s) bị &lt;strong>đá khỏi ISR&lt;/strong>. Khi leader chết, Kafka chỉ bầu leader mới &lt;strong>từ trong ISR&lt;/strong> (vì chỉ chúng chắc chắn có đủ dữ liệu đã xác nhận).&lt;/p></description></item><item><title>Bài 4 — Offset &amp; Delivery Semantics</title><link>https://thanhhv.github.io/series/kafka/04-offset-delivery-semantics/</link><pubDate>Fri, 08 May 2026 08:00:00 +0700</pubDate><guid>https://thanhhv.github.io/series/kafka/04-offset-delivery-semantics/</guid><description>&lt;blockquote>
&lt;p>Bài quan trọng nhất về độ tin cậy. Hầu hết bug &amp;ldquo;mất message&amp;rdquo; / &amp;ldquo;xử lý trùng&amp;rdquo; ở production nằm ở đây.&lt;/p>&lt;/blockquote>
&lt;h2 id="offset-commit-là-gì">Offset commit là gì?&lt;/h2>
&lt;p>Consumer cần báo cho Kafka biết đã xử lý &lt;strong>đến đâu&lt;/strong>, để lần sau (hoặc consumer khác sau rebalance) đọc tiếp đúng chỗ. Việc đó gọi là &lt;strong>commit offset&lt;/strong>, lưu trong topic nội bộ &lt;code>__consumer_offsets&lt;/code>.&lt;/p>
&lt;p>Mấu chốt sinh ra mọi vấn đề: &lt;strong>xử lý message&lt;/strong> và &lt;strong>commit offset&lt;/strong> là hai hành động riêng biệt, giữa chúng consumer có thể crash. Thứ tự hai hành động này quyết định &amp;ldquo;delivery semantics&amp;rdquo;.&lt;/p></description></item><item><title>Bài 3 — Partitioning &amp; Đảm bảo thứ tự</title><link>https://thanhhv.github.io/series/kafka/03-partitioning-thu-tu/</link><pubDate>Wed, 06 May 2026 08:00:00 +0700</pubDate><guid>https://thanhhv.github.io/series/kafka/03-partitioning-thu-tu/</guid><description>&lt;h2 id="producer-chọn-partition-thế-nào">Producer chọn partition thế nào?&lt;/h2>
&lt;ul>
&lt;li>&lt;strong>Có key:&lt;/strong> &lt;code>partition = hash(key) % số_partition&lt;/code>. Cùng key + số partition không đổi → luôn cùng partition → giữ thứ tự.&lt;/li>
&lt;li>&lt;strong>Không key:&lt;/strong> rải đều (sticky/round-robin), tối ưu throughput nhưng &lt;strong>không đảm bảo thứ tự&lt;/strong>.&lt;/li>
&lt;/ul>
&lt;h2 id="ba-cạm-bẫy-quanh-partitioning">Ba cạm bẫy quanh partitioning&lt;/h2>
&lt;h3 id="bẫy-1--hàm-hash-khác-nhau-giữa-các-client">Bẫy 1 — Hàm hash khác nhau giữa các client&lt;/h3>
&lt;p>Client &lt;strong>Java&lt;/strong> dùng &lt;strong>murmur2&lt;/strong>; &lt;strong>librdkafka&lt;/strong> (confluent-kafka-go, Python, C…) mặc định dùng thuật toán khác (&lt;code>consistent_random&lt;/code>, nền CRC32). → &lt;strong>Cùng một key, producer Java và producer Go có thể đẩy vào hai partition khác nhau!&lt;/strong>&lt;/p></description></item><item><title>Bài 2 — Consumer Group &amp; Rebalance</title><link>https://thanhhv.github.io/series/kafka/02-consumer-group-rebalance/</link><pubDate>Sun, 03 May 2026 08:00:00 +0700</pubDate><guid>https://thanhhv.github.io/series/kafka/02-consumer-group-rebalance/</guid><description>&lt;h2 id="khái-niệm">Khái niệm&lt;/h2>
&lt;p>&lt;strong>Consumer group&lt;/strong> là tập các consumer cùng &lt;code>group.id&lt;/code>, hợp sức tiêu thụ một topic. Kafka tự chia partition cho các thành viên — gọi là &lt;strong>partition assignment&lt;/strong>.&lt;/p>
&lt;p>Quan hệ then chốt:&lt;/p>
&lt;pre tabindex="0">&lt;code>Trong 1 group: 1 partition -&amp;gt; tối đa 1 consumer (KHÔNG phải 1-n)
1 consumer -&amp;gt; có thể N partition
Trên nhiều group: 1 partition -&amp;gt; N consumer (mỗi group 1 đứa) (pub/sub)
&lt;/code>&lt;/pre>&lt;p>Hệ quả thực chiến: &lt;strong>số consumer hữu ích tối đa trong một group = số partition.&lt;/strong> Topic 3 partition, group 5 consumer → 3 đứa làm việc, 2 đứa ngồi không. &lt;strong>Partition là trần scale của consumer&lt;/strong> — muốn xử lý song song hơn phải tăng partition trước.&lt;/p></description></item><item><title>Bài 1 — Topic, Partition, Producer &amp; Consumer</title><link>https://thanhhv.github.io/series/kafka/01-topic-partition-producer-consumer/</link><pubDate>Fri, 01 May 2026 08:00:00 +0700</pubDate><guid>https://thanhhv.github.io/series/kafka/01-topic-partition-producer-consumer/</guid><description>&lt;h2 id="khái-niệm-nền-tảng">Khái niệm nền tảng&lt;/h2>
&lt;p>&lt;strong>Topic&lt;/strong> là một &amp;ldquo;kênh&amp;rdquo; logic chứa message, ví dụ &lt;code>orders&lt;/code> chứa các sự kiện đơn hàng.&lt;/p>
&lt;p>&lt;strong>Partition&lt;/strong> là điểm mấu chốt phân biệt Kafka với hàng đợi thường. Mỗi topic được chia thành nhiều partition. Mỗi partition là một &lt;strong>log ghi nối tiếp (append-only)&lt;/strong>: message có thứ tự tuyệt đối trong partition, và mỗi message mang một số thứ tự gọi là &lt;strong>offset&lt;/strong> (0, 1, 2, …).&lt;/p></description></item><item><title>Chương 13: Best Practices, Anti-patterns và Khi nào KHÔNG nên dùng CDC</title><link>https://thanhhv.github.io/series/cdc/13-best-practices-anti-patterns/</link><pubDate>Fri, 20 Feb 2026 20:00:00 +0700</pubDate><guid>https://thanhhv.github.io/series/cdc/13-best-practices-anti-patterns/</guid><description>&lt;p>Chương cuối này là phần &amp;ldquo;chưng cất&amp;rdquo; của toàn bộ tài liệu. Sau mười hai chương về cơ chế, pattern, sự cố và kiến trúc, câu hỏi còn lại rất thực dụng: &lt;strong>làm gì, tránh gì, và — quan trọng không kém — khi nào đừng làm cả&lt;/strong>. Tôi cố tình viết chương này theo kiểu có thể in ra dán cạnh bàn on-call: mỗi practice kèm &lt;em>lý do&lt;/em>, mỗi anti-pattern kèm &lt;em>hậu quả thật&lt;/em>, vì quy tắc không có lý do sẽ bị bỏ qua ngay lần deadline đầu tiên.&lt;/p></description></item><item><title>Chương 12: Kiến trúc CDC thực tế theo domain</title><link>https://thanhhv.github.io/series/cdc/12-kien-truc-thuc-te/</link><pubDate>Fri, 20 Feb 2026 19:00:00 +0700</pubDate><guid>https://thanhhv.github.io/series/cdc/12-kien-truc-thuc-te/</guid><description>&lt;p>Hai chương trước cho bạn pattern (chương 10) và bản đồ rủi ro (chương 11). Chương này ghép chúng lại thành &lt;strong>thiết kế hoàn chỉnh theo từng loại hệ thống&lt;/strong>. Cùng một công nghệ — Debezium, Kafka — nhưng bài toán e-commerce, FinTech hay SaaS multi-tenant dẫn đến những quyết định rất khác nhau, và điều làm nên một Solution Architect giỏi không phải là biết công cụ, mà là biết &lt;em>bối cảnh nào bẻ cong thiết kế theo hướng nào&lt;/em>.&lt;/p></description></item><item><title>Chương 11: Production Failure Cases</title><link>https://thanhhv.github.io/series/cdc/11-production-failure-cases/</link><pubDate>Fri, 20 Feb 2026 18:00:00 +0700</pubDate><guid>https://thanhhv.github.io/series/cdc/11-production-failure-cases/</guid><description>&lt;p>Đây là chương quan trọng nhất của toàn bộ tài liệu. Lý do rất đơn giản: &lt;strong>CDC không khó ở lúc setup — CDC khó ở tháng thứ ba vận hành.&lt;/strong> Demo Debezium chạy trong một buổi chiều; nhưng pipeline CDC production là một chuỗi hệ thống stateful nối tiếp nhau (database → connector → Kafka → consumer → sink), và mỗi mắt xích có những chế độ hỏng riêng, đôi khi âm thầm, đôi khi phá hủy cả database nguồn.&lt;/p></description></item><item><title>Chương 10: CDC trong bức tranh kiến trúc — Outbox, Event Sourcing, CQRS</title><link>https://thanhhv.github.io/series/cdc/10-cdc-va-kien-truc/</link><pubDate>Fri, 20 Feb 2026 17:00:00 +0700</pubDate><guid>https://thanhhv.github.io/series/cdc/10-cdc-va-kien-truc/</guid><description>&lt;p>Đến chương này, chúng ta đã hiểu CDC hoạt động thế nào ở tầng cơ chế: transaction log, replication slot, connector, offset. Câu hỏi tiếp theo — và là câu hỏi mà một Tech Lead hay Solution Architect thực sự phải trả lời — là: &lt;strong>CDC đứng ở đâu trong kiến trúc tổng thể?&lt;/strong> Nó thay thế cái gì, kết hợp với pattern nào, và quan trọng hơn: nó &lt;em>không phải&lt;/em> là cái gì.&lt;/p></description></item><item><title>Chương 9: Xây dựng Event Pipeline hoàn chỉnh — Kafka đến ClickHouse, Elasticsearch, Data Warehouse</title><link>https://thanhhv.github.io/series/cdc/09-event-pipeline/</link><pubDate>Fri, 20 Feb 2026 16:00:00 +0700</pubDate><guid>https://thanhhv.github.io/series/cdc/09-event-pipeline/</guid><description>&lt;p>Hai chương trước cho bạn nguồn (Debezium) và nền tảng (Kafka Connect). Chương này lắp mọi thứ thành pipeline hoàn chỉnh — và quan trọng hơn, chỉ ra các quyết định thiết kế &lt;strong>ở giữa&lt;/strong> hai đầu: topic và partition, schema contract, cách từng loại đích tiêu hóa change event, và latency/backpressure của toàn tuyến. Kinh nghiệm của tôi: pipeline CDC thất bại ở production hiếm khi vì Debezium hay Kafka lỗi — nó thất bại vì &lt;strong>các quyết định thiết kế trung gian bị bỏ qua&lt;/strong>: topic 200 partition cho bảng 50 nghìn row, JSON không schema, insert từng row vào ClickHouse. Cuối chương có đúng ví dụ đó, kèm bản chữa.&lt;/p></description></item><item><title>Chương 8: Kafka Connect — Nền tảng vận hành Connector</title><link>https://thanhhv.github.io/series/cdc/08-kafka-connect/</link><pubDate>Fri, 20 Feb 2026 15:00:00 +0700</pubDate><guid>https://thanhhv.github.io/series/cdc/08-kafka-connect/</guid><description>&lt;p>Chương 7 kết thúc với một nhận định: phần khó nhất của CDC không phải đọc log mà là quản lý trạng thái và fault tolerance — và Debezium đẩy toàn bộ phần đó cho Kafka Connect. Chương này mở hộp đen Kafka Connect từ góc nhìn người vận hành platform. Nếu Debezium là động cơ, Connect là khung gầm: khi pipeline CDC gặp sự cố lúc 3 giờ sáng, thứ bạn thao tác gần như luôn là Connect — REST API, task state, rebalance, internal topic — chứ không phải code Debezium.&lt;/p></description></item><item><title>Chương 7: Debezium Internal Architecture</title><link>https://thanhhv.github.io/series/cdc/07-debezium-internals/</link><pubDate>Fri, 20 Feb 2026 14:00:00 +0700</pubDate><guid>https://thanhhv.github.io/series/cdc/07-debezium-internals/</guid><description>&lt;p>Ở các chương trước, chúng ta đã phân tích cơ chế log-based CDC ở tầng database: WAL của PostgreSQL, binlog của MySQL, replication slot, logical decoding. Chương này đi vào bên trong Debezium — thành phần đứng giữa database và Kafka — để trả lời câu hỏi mà mọi kiến trúc sư phải trả lời được trước khi đưa Debezium vào production: &lt;strong>nó thực sự làm gì bên trong, trạng thái của nó nằm ở đâu, và điều gì xảy ra khi nó chết?&lt;/strong>&lt;/p></description></item><item><title>Chương 6: Cơ chế CDC — Snapshot, Offset, Ordering và Delivery Guarantee</title><link>https://thanhhv.github.io/series/cdc/06-co-che-cdc/</link><pubDate>Fri, 20 Feb 2026 13:00:00 +0700</pubDate><guid>https://thanhhv.github.io/series/cdc/06-co-che-cdc/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>Đối tượng&lt;/strong>: Senior Backend Engineer, Tech Lead, Solution Architect thiết kế pipeline CDC end-to-end.
&lt;strong>Mục tiêu chương&lt;/strong>: Hai chương trước đi sâu vào từng nguồn log. Chương này trả lời câu hỏi ở tầng trên: bất kể nguồn là WAL, binlog hay oplog, một CDC connector phải giải &lt;strong>năm bài toán bất biến&lt;/strong>: (1) dựng trạng thái ban đầu khi log không giữ toàn bộ lịch sử; (2) nhớ vị trí đọc để crash không chết pipeline; (3) đảm bảo gì về delivery; (4) đảm bảo gì về thứ tự; (5) sống sót qua schema change. Ai nắm năm bài toán này sẽ đánh giá được mọi công cụ CDC — Debezium hay bất cứ tên nào xuất hiện sau này — bằng cùng một checklist.&lt;/p></description></item><item><title>Chương 5: MySQL Binlog và MongoDB Oplog</title><link>https://thanhhv.github.io/series/cdc/05-mysql-mongodb-internals/</link><pubDate>Fri, 20 Feb 2026 12:00:00 +0700</pubDate><guid>https://thanhhv.github.io/series/cdc/05-mysql-mongodb-internals/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>Đối tượng&lt;/strong>: Senior Backend Engineer, Tech Lead, Solution Architect vận hành CDC trên MySQL và MongoDB.
&lt;strong>Mục tiêu chương&lt;/strong>: Chương 4 đã mổ xẻ WAL của PostgreSQL. Chương này áp cùng khung tư duy lên hai họ database còn lại chiếm phần lớn thị phần CDC: MySQL (binlog) và MongoDB (oplog). Điểm mấu chốt không phải là học ba bộ thuật ngữ — mà là nhận ra ba hệ đã chọn &lt;strong>ba mô hình retention và contract khác nhau&lt;/strong> cho cùng một bài toán, và mỗi lựa chọn sinh ra một failure mode đặc trưng mà bạn, người thiết kế platform, phải phòng thủ theo cách khác nhau.&lt;/p></description></item><item><title>Chương 4: PostgreSQL Internals — WAL và Logical Replication</title><link>https://thanhhv.github.io/series/cdc/04-postgresql-internals/</link><pubDate>Fri, 20 Feb 2026 11:00:00 +0700</pubDate><guid>https://thanhhv.github.io/series/cdc/04-postgresql-internals/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>Đối tượng&lt;/strong>: Senior Backend Engineer, Tech Lead, Solution Architect đang thiết kế hoặc vận hành pipeline CDC trên PostgreSQL.
&lt;strong>Mục tiêu chương&lt;/strong>: Sau chương này, bạn phải trả lời được ba câu hỏi mà mọi cuộc review kiến trúc CDC trên PostgreSQL đều xoay quanh: (1) WAL thực chất là gì và vì sao nó là &lt;em>nguồn sự thật duy nhất&lt;/em> mà CDC có thể tin; (2) replication slot hoạt động thế nào và vì sao nó là con dao hai lưỡi nổi tiếng nhất của CDC trên PostgreSQL; (3) REPLICA IDENTITY ảnh hưởng gì đến nội dung event và bạn phải trả giá gì cho từng lựa chọn.&lt;/p></description></item><item><title>Chương 3: Bản chất của Change Data Capture</title><link>https://thanhhv.github.io/series/cdc/03-ban-chat-cdc/</link><pubDate>Fri, 20 Feb 2026 10:00:00 +0700</pubDate><guid>https://thanhhv.github.io/series/cdc/03-ban-chat-cdc/</guid><description>&lt;h2 id="31-insight-nền-tảng-dữ-liệu-về-mọi-thay-đổi-đã-tồn-tại-sẵn">3.1. Insight nền tảng: dữ liệu về mọi thay đổi đã tồn tại sẵn&lt;/h2>
&lt;p>Hãy quay lại điểm mà Chương 2 dừng lại. Chúng ta cần một nguồn thông tin về thay đổi thỏa mãn ba điều kiện: &lt;strong>đầy đủ tuyệt đối&lt;/strong> (mọi thay đổi, từ mọi đường ghi, kể cả DELETE), &lt;strong>atomic với dữ liệu commit&lt;/strong> (không event ma, không mất event), và &lt;strong>không đặt thêm chi phí vào transaction path&lt;/strong>.&lt;/p></description></item><item><title>Chương 2: Các phương pháp đồng bộ truyền thống và hạn chế</title><link>https://thanhhv.github.io/series/cdc/02-cac-phuong-phap-dong-bo-truyen-thong/</link><pubDate>Fri, 20 Feb 2026 09:00:00 +0700</pubDate><guid>https://thanhhv.github.io/series/cdc/02-cac-phuong-phap-dong-bo-truyen-thong/</guid><description>&lt;p>Chương 1 đã xác lập bài toán: dữ liệu buộc phải phân mảnh theo workload, và cần một cơ chế đưa thay đổi từ source of truth đến các hệ thống downstream. Chương này đi qua các phương pháp mà ngành đã dùng suốt ba thập kỷ — theo đúng thứ tự tiến hóa của chúng. Đây không phải bài điểm danh lịch sử: mỗi phương pháp vẫn đang chạy trong production ở đâu đó ngay lúc này, và mỗi phương pháp đều dạy ta một bài học về &lt;strong>vì sao CDC log-based cuối cùng trở thành câu trả lời&lt;/strong>. Với mỗi phương pháp, ta phân tích theo cùng một template: cách hoạt động, ưu điểm, hạn chế kỹ thuật, một ví dụ production khi nó fail, và — quan trọng không kém — khi nào nó vẫn là lựa chọn đúng.&lt;/p></description></item><item><title>Chương 1: Bài toán đồng bộ dữ liệu</title><link>https://thanhhv.github.io/series/cdc/01-bai-toan-dong-bo-du-lieu/</link><pubDate>Fri, 20 Feb 2026 08:00:00 +0700</pubDate><guid>https://thanhhv.github.io/series/cdc/01-bai-toan-dong-bo-du-lieu/</guid><description>&lt;h2 id="11-bắt-đầu-từ-một-bài-toán-kinh-doanh-cụ-thể">1.1. Bắt đầu từ một bài toán kinh doanh cụ thể&lt;/h2>
&lt;p>Hãy hình dung một hệ thống e-commerce cỡ vừa: 5 triệu người dùng, 2 triệu SKU, khoảng 300.000 đơn hàng mỗi ngày. PostgreSQL là source of truth — nơi mọi transaction ghi đơn, trừ kho, cập nhật giá diễn ra. Hệ thống chạy tốt trong hai năm đầu. Rồi các yêu cầu sau lần lượt xuất hiện:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Search&lt;/strong>: người dùng cần tìm kiếm sản phẩm theo full-text, fuzzy matching, faceted filter theo thương hiệu, khoảng giá, đánh giá. Đội ngũ chọn Elasticsearch.&lt;/li>
&lt;li>&lt;strong>Analytics&lt;/strong>: đội business cần dashboard doanh thu theo giờ, phân tích cohort, funnel conversion trên hàng trăm triệu event. Đội data chọn ClickHouse.&lt;/li>
&lt;li>&lt;strong>Cache&lt;/strong>: trang chi tiết sản phẩm chịu 20.000 request/giây lúc flash sale, không thể đánh thẳng vào PostgreSQL. Đội backend đặt Redis phía trước.&lt;/li>
&lt;/ul>
&lt;p>Đến đây, cùng một thực thể &lt;code>product&lt;/code> tồn tại ở &lt;strong>bốn nơi&lt;/strong>: PostgreSQL (bản gốc), Elasticsearch (bản đánh index cho search), ClickHouse (bản denormalized cho analytics), Redis (bản serialized cho cache). Dữ liệu đã bị &lt;strong>phân mảnh&lt;/strong> (data fragmentation). Và câu hỏi trung tâm của toàn bộ tài liệu này xuất hiện:&lt;/p></description></item><item><title>Change Data Capture và Đồng bộ dữ liệu trong hệ thống Backend hiện đại</title><link>https://thanhhv.github.io/series/cdc/00-muc-luc/</link><pubDate>Fri, 20 Feb 2026 07:00:00 +0700</pubDate><guid>https://thanhhv.github.io/series/cdc/00-muc-luc/</guid><description>&lt;p>Bộ tài liệu chuyên sâu về Change Data Capture (CDC) — viết từ góc nhìn của người thiết kế Data Platform và Distributed Systems, không phải từ góc nhìn người dùng công cụ.&lt;/p>
&lt;p>&lt;strong>Đối tượng:&lt;/strong> Backend Engineer, Data Engineer, Senior Backend Engineer, Tech Lead, Solution Architect, Software Architect.&lt;/p>
&lt;p>&lt;strong>Triết lý trình bày:&lt;/strong> Business Problem → Vì sao cần đồng bộ dữ liệu → Hạn chế của Polling → Trigger / Dual Write / Event Publishing → CDC → Log-based CDC → Internal Architecture → Trade-off → Production → Khi nào không nên dùng CDC.&lt;/p></description></item></channel></rss>