Mục lục
- Mục Tiêu Bài Học
- Bài Toán Analytics Realtime
- Yêu Cầu Typical Của Hệ Thống Analytics
- Tại Sao SQL OLTP Không Đủ
- Tại Sao Data Warehouse Không Đủ Realtime
- OLAP Engine (ClickHouse, Druid): Tốt Nhưng Không Phải Lúc Nào Cũng Cần
- Redis Fit Ở Đâu
- Bảng So Sánh Tools
- Architecture Pattern: Lambda & Kappa
- Tám Use Case Trong Module 8
- Accuracy vs Memory: Exact hay Probabilistic
- Persistence & Pipeline
- Decision Framework
- Tổng Kết & Quiz
Mục Tiêu Bài Học
- Xác định được các use case analytics thực tế mà Redis xử lý tốt: counter realtime, leaderboard, DAU/MAU, distinct count, trending, time series.
- Hiểu tại sao SQL OLTP, data warehouse và OLAP engine mỗi loại đều có giới hạn với một tập bài toán cụ thể.
- Nắm được Redis fit vào đâu trong kiến trúc analytics nhờ in-memory atomic ops, Sorted Set, Bitmap, HyperLogLog, và probabilistic structures.
- Phân biệt khi nào dùng exact structures (Set, Sorted Set) và khi nào probabilistic (HyperLogLog, Bloom, Count-Min) là đủ.
- Biết hai pattern kiến trúc phổ biến: Lambda (speed layer + batch layer) và Kappa (stream-only).
- Có framework quyết định để chọn đúng công cụ cho từng bài toán analytics.
Bài Toán Analytics Realtime
Analytics realtime bao gồm nhiều loại bài toán khác nhau, nhưng tất cả đều có điểm chung: dữ liệu phải được cập nhật và truy vấn trong khoảng thời gian rất ngắn — thường dưới 1 giây lag từ lúc event xảy ra đến lúc hiện ra trên dashboard.
Các bài toán phổ biến trong production:
- Dashboard operational: Hiển thị số user đang online, page view trong 5 phút qua, số đơn hàng mỗi phút. Dashboard này mở 24/7 và phải phản hồi dưới 100ms.
- Leaderboard: Top user theo điểm, top sản phẩm theo doanh thu, top nhân viên theo KPI. Cần cập nhật ngay khi điểm thay đổi và trả về top-N hiệu quả.
- Trending: Hashtag trending realtime, category đang được xem nhiều trong 1 giờ qua. Yêu cầu sliding window và ranking liên tục.
- Counting unique (DAU/MAU): Có bao nhiêu user duy nhất đã active hôm nay, tuần này, tháng này — không đếm trùng.
- Rate metrics: Click/s, error/s, request/s — để alert và scaling decision.
- Cohort retention: Trong số user đăng ký ngày 2026-05-01, bao nhiêu % còn active sau 7 ngày, 30 ngày.
Điểm chung của tất cả những bài toán này: write rất nhiều (mỗi event đều cần ghi), read với aggregate nhẹ (top-N, count, sum), và latency yêu cầu thấp. Đây không phải là bài toán mà SQL OLTP, data warehouse hay OLAP engine đều giải tốt.
Yêu Cầu Typical Của Hệ Thống Analytics
Khi thiết kế hệ thống analytics cho một ứng dụng trung bình đến lớn, các con số cần nắm:
- Latency read: Dashboard cần phản hồi dưới 100ms. Leaderboard realtime dưới 50ms.
- Throughput write: Ứng dụng 1M DAU với 50 event/user/ngày ≈ 580 event/s trung bình, nhưng peak có thể 10-20x, tức 5k–10k event/s. Ứng dụng lớn hơn (social, e-commerce, gaming) dễ đạt 100k–1M event/s.
- Update frequency: Lag từ event đến dashboard dưới 1 giây cho realtime; chấp nhận đến 5 giây cho near-realtime.
- Query patterns: Phần lớn là aggregate đơn giản — count, sum, top-N, distinct count trong một time range.
- Concurrent readers: Dashboard thường có hàng trăm đến hàng nghìn tab/user mở đồng thời, thăm dò theo poll hoặc WebSocket.
Với profile này, bộ đôi write-heavy + read-aggregate-light cùng latency thấp là điều kiện để Redis phát huy lợi thế.
Tại Sao SQL OLTP Không Đủ
SQL OLTP (PostgreSQL, MySQL) được thiết kế cho transactional workload: ghi nhất quán với ACID, đọc theo primary key, join phức tạp. Khi dùng cho analytics realtime, gặp ba vấn đề:
1. Mỗi INCR là một UPDATE + WAL
Mỗi lần tăng một counter trong SQL là một UPDATE counter SET value = value + 1 WHERE id = X. Database phải: lấy lock row, đọc giá trị cũ, tính giá trị mới, ghi vào buffer, ghi WAL (Write-Ahead Log). Ở 10k increment/s, điều này tạo ra I/O và lock pressure rất lớn.
2. Aggregate trên dataset lớn chậm
-- Đếm page view ngày hôm nay: quét 1B+ row
SELECT COUNT(*) FROM page_views
WHERE created_at >= '2026-06-01'
AND created_at < '2026-06-02';
-- Kết quả: 5-60 giây tuỳ index, partition, data size
Ngay cả với index đúng và partition theo ngày, COUNT(*) trên hàng trăm triệu row mất vài giây đến vài chục giây. Dashboard không thể đợi vậy.
3. Concurrent UPDATE → lock contention
Khi 1000 request đồng thời cùng UPDATE một row counter, chúng xếp hàng chờ lock. Throughput thực tế của một row bị update concurrent trong PostgreSQL thường dưới 5k–10k/s và latency tăng theo queue.
4. DAU là expensive query
-- DAU ngày hôm nay: dedup user_id trên 100M event
SELECT COUNT(DISTINCT user_id) FROM events
WHERE date = '2026-06-01';
-- Full scan hoặc sort + dedup = expensive
SQL không có cấu trúc dữ liệu tích hợp cho distinct count hiệu quả. Mỗi lần query là O(N log N) sort hoặc hash table trên toàn bộ dataset của ngày đó.
Tại Sao Data Warehouse Không Đủ Realtime
Data warehouse (BigQuery, Redshift, Snowflake) giỏi phân tích historical trên hàng tỷ row, nhưng có những đặc điểm khiến chúng không phù hợp cho dashboard realtime:
Batch ingestion lag
Data warehouse nhận dữ liệu qua batch hoặc micro-batch: từ 5 phút (Firehose → Redshift) đến 60 phút (Airflow daily job). Lag này là cấu trúc — không thể giảm xuống dưới vài phút mà không thay đổi kiến trúc ingestion hoàn toàn.
Query latency 1–30 giây
Ngay cả query đơn giản trên BigQuery với clustering/partitioning đúng vẫn mất 1–5 giây. Query phức tạp với JOIN hoặc window function trên dataset lớn mất 10–30 giây. Không thể dùng trực tiếp cho dashboard reload mỗi 1–5 giây.
Chi phí per-query
BigQuery tính tiền theo bytes scanned: $5/TB. Dashboard refresh mỗi 5 giây × 500 tab mở × 1TB scan/query = $1.25M/giờ — rõ ràng không khả thi. Ngay cả với materialized view và caching layer của BigQuery, mỗi lần cache miss vẫn scan full.
Data warehouse giỏi cho: báo cáo end-of-day, phân tích cohort sau nhiều tuần, ad-hoc exploration của data scientist. Không phải cho dashboard operational cần cập nhật mỗi giây.
OLAP Engine (ClickHouse, Druid): Tốt Nhưng Không Phải Lúc Nào Cũng Cần
ClickHouse và Apache Druid là OLAP columnar store được thiết kế cho analytics throughput cao. Chúng tốt hơn nhiều so với SQL OLTP và data warehouse cho bài toán analytics, nhưng có những trade-off:
- Infrastructure: ClickHouse cluster cần ít nhất 3 shard × 2 replica, mỗi node 32GB+ RAM và SSD nhanh. Druid phức tạp hơn với Historical, Broker, Coordinator node riêng. Không phải every team có bandwidth vận hành.
- Ingestion lag: ClickHouse với Kafka connector: 2–5 giây lag. Druid streaming ingestion: 2–5 giây. Gần realtime nhưng không phải sub-second.
- Query latency: Aggregate đơn giản (COUNT, SUM) trên 1B row: 100ms–2s với ClickHouse. Đủ tốt cho nhiều use case nhưng không đủ cho counter cần < 10ms.
- Overkill cho counter đơn giản: Nếu chỉ cần "đơn hàng hôm nay" hoặc "user online", dựng ClickHouse cluster là over-engineering. Redis với một
INCRgiải quyết trong 1 dòng code.
ClickHouse thích hợp khi cần phân tích sâu (GROUP BY nhiều chiều, window function, cohort phức tạp) trên dataset tỷ row. Không phải thay thế cho Redis ở bài toán counter/leaderboard đơn giản.
Redis Fit Ở Đâu
Redis có một số đặc điểm cấu trúc khiến nó phù hợp tự nhiên với analytics realtime:
In-memory: < 1ms mọi ops
Mọi thao tác Redis đều trên RAM. Latency P99 thường dưới 1ms ở local network, 1–3ms ở cloud region. Không có I/O disk trong hot path.
Atomic INCR / HINCRBY
INCR là atomic — không cần lock, không cần transaction. Một Redis instance xử lý được 100k–1M INCR/s. Nhiều worker đồng thời cùng INCR một key sẽ không race condition.
# Tăng counter trang / ngày — atomic, không lock
INCR page:view:/products/123:2026-06-01
# Tăng nhiều field trong hash — 1 round-trip
HINCRBY stats:2026-06-01 views 1
HINCRBY stats:2026-06-01 clicks 1
Sorted Set: leaderboard O(log N)
Sorted Set lưu member kèm score, tự sắp xếp. ZADD insert/update O(log N). ZREVRANGE ... WITHSCORES lấy top-N O(log N + N). Không cần sort lại khi đọc.
ZADD leaderboard:game:weekly 4200 user:7381
ZREVRANGE leaderboard:game:weekly 0 9 WITHSCORES
# → top 10 user với điểm, O(log N + 10)
Bitmap: DAU compact với 1 bit/user
100 triệu user = 100 triệu bit = 12.5 MB per ngày. SETBIT dau:2026-06-01 user_id 1 là O(1). BITCOUNT đếm toàn bộ ngày: O(N/8) — rất nhanh nhờ CPU popcount instruction.
HyperLogLog: distinct count 12KB cố định
HyperLogLog (HLL) là probabilistic data structure ước lượng cardinality với sai số ~0.81%, bộ nhớ cố định 12KB bất kể set có 1M hay 1B phần tử. Phù hợp khi "khoảng 2.3 triệu unique visitor" là đủ chính xác.
Probabilistic structures (RedisBloom module)
RedisBloom thêm vào Redis các cấu trúc: Bloom Filter (membership check), Count-Min Sketch (frequency estimation), Top-K (top-N element), T-Digest (percentile estimation). Module này chạy natively trong Redis process, không overhead network.
RedisTimeSeries
Module native cho time series: ingest high-rate, automatic downsampling (aggregation rule), retention policy, range query. Tích hợp với Grafana qua Prometheus adapter.
Bảng So Sánh Tools
| Tool | Latency (read) | Write throughput | Ingestion lag | Phù hợp nhất |
|---|---|---|---|---|
| SQL OLTP (PostgreSQL) | 5–50ms | ~10k op/s (row lock) | Realtime | Transactional, JOIN phức tạp |
| Data Warehouse (BigQuery, Redshift) | 1–30s | Batch | 5–60 phút | Historical, ad-hoc analytics |
| ClickHouse | 100ms–2s | ~100k row/s | 2–5 giây | Deep analytics, GROUP BY nhiều chiều |
| Redis | <1ms | 100k–1M op/s | <1ms | Realtime counter, leaderboard, DAU, top-N |
| Redis + Data Warehouse | <1ms (recent) / 1–30s (history) | Redis limit | Hybrid | Realtime view + historical drill-down |
Nhận xét từ bảng: không có tool nào tốt ở mọi chiều. Redis có latency và throughput tốt nhất nhưng không làm được deep analytics phức tạp và không giữ historical data rẻ. Đây là lý do nhiều hệ thống production dùng hybrid.
Architecture Pattern: Lambda & Kappa
Khi cần cả realtime lẫn historical, có hai pattern kiến trúc phổ biến:
Lambda Architecture
Tách hệ thống thành hai layer xử lý song song:
- Speed layer (Redis): Nhận event stream trực tiếp, tính toán incremental view cho 24–48h gần nhất. Dashboard đọc từ đây cho "hôm nay" và "hôm qua".
- Batch layer (Data Warehouse): Nhận toàn bộ event, chạy job định kỳ (hàng giờ hoặc hàng ngày), tính toán historical view chuẩn xác. Dashboard đọc từ đây cho tuần, tháng, năm.
# Speed layer (Redis): dashboard đọc 24h gần nhất
GET counter:orders:2026-06-01 # orders hôm nay
ZREVRANGE leaderboard:today 0 9 # top 10 hôm nay
# Batch layer query (data warehouse): historical
# SELECT date, SUM(orders) FROM fact_orders
# WHERE date BETWEEN '2026-05-01' AND '2026-06-01'
# GROUP BY date
Lambda có độ phức tạp cao: cần maintain hai code path (realtime và batch), đôi khi kết quả không khớp 100% do cách aggregate khác nhau. Nhưng nó là pattern production-proven cho hệ thống lớn.
Kappa Architecture
Đơn giản hơn Lambda: chỉ có một stream processing pipeline (Kafka + Flink/Spark Streaming). Redis đóng vai trò materialized view — kết quả aggregate được ghi vào Redis sau mỗi window, consumer đọc từ Redis. Không có batch layer riêng. Historical được tính bằng cách replay stream từ đầu khi cần.
Kappa phù hợp khi team có infrastructure stream processing tốt và không cần complex historical backfill thường xuyên.
Tám Use Case Trong Module 8
Module 8 đi qua tám nhóm bài toán, mỗi bài sẽ có deep dive riêng. Đây là preview để hiểu toàn cảnh:
Realtime counter (Bài 90–91)
Bài toán đơn giản nhất: tăng counter mỗi khi có event. INCR counter:page:/home:2026-06-01. Bài 90 cover các pattern: simple counter, sharded counter (khi cần > 1M/s trên một key), throttled counter (giới hạn rate write để giảm overhead). Bài 91 áp dụng cho page view tracking production.
Leaderboard (Bài 92)
Sorted Set là cấu trúc tự nhiên cho leaderboard. ZADD update score, ZREVRANK lấy rank của một user, ZREVRANGE lấy top-N. Bài 92 cover: leaderboard toàn thời gian, leaderboard theo window (weekly/monthly bằng TTL), concurrent update, sharding khi leaderboard > 10M member.
Bloom filter (Bài 93)
Bloom filter trả lời câu hỏi membership: "Email này đã đăng ký chưa?" với false positive rate thấp (< 1%) và memory tiết kiệm. BF.ADD, BF.EXISTS từ module RedisBloom. Dùng để guard trước database: chỉ query DB khi BF nói "có thể có", skip khi BF nói "chắc chắn không có".
HyperLogLog distinct count (Bài 94)
PFADD visitors:today user_id, PFCOUNT visitors:today → distinct count với 12KB bộ nhớ cố định, sai số ~0.81%. So sánh trực tiếp: lưu 100M unique user_id trong Set cần ~8GB, HLL chỉ cần 12KB. Bài 94 phân tích khi nào sai số 0.81% là chấp nhận được.
Count-Min Sketch & RedisTimeSeries (Bài 95)
Count-Min Sketch ước lượng frequency của item trong stream (log analysis, term counting) với sublinear memory. RedisTimeSeries cho metrics infrastructure: ingest latency/throughput time series, query range, downsampling tự động.
Top-K (Bài 96)
Xác định top-K element từ high-cardinality stream mà không cần lưu toàn bộ. TOPK.ADD từ RedisBloom cập nhật probabilistic top-K. Kết hợp với Sorted Set + sliding window window cho trending hashtag realtime.
Cohort analysis (Bài 97)
Bitmap kết hợp với date-based key để tính retention: user active ngày D và ngày D+7 → BITOP AND. Cohort retention matrix có thể tính từ Redis với memory O(users/8) per day.
Bitmap DAU/MAU/WAU (Bài 98)
Deep dive Bitmap analytics: SETBIT dau:2026-06-01 user_id 1, BITCOUNT cho DAU. BITOP OR nhiều ngày cho WAU/MAU. 100M user × 30 ngày = 360MB total — compact hơn nhiều so với lưu user_id list.
Cuối module là Bài 99: anti-patterns và incident stories từ các hệ thống analytics dùng Redis sai cách.
Accuracy vs Memory: Exact hay Probabilistic
Một trong những quyết định quan trọng nhất trong analytics Redis là: exact hay probabilistic?
| Structure | Accuracy | Memory (100M items) | Use case |
|---|---|---|---|
| Set | Exact | ~8 GB | Distinct count, nhỏ (< 10M) |
| Sorted Set | Exact | ~4–8 GB | Leaderboard, rank chính xác |
| Bitmap | Exact | 12.5 MB (user_id dense) | DAU/MAU (integer user_id) |
| HyperLogLog | ±0.81% | 12 KB (cố định) | Distinct count lớn, chấp nhận xấp xỉ |
| Bloom Filter | No false negative, FP rate < 1% | ~120 MB (1% FP rate) | Membership check |
| Count-Min Sketch | Overestimate, tunable error | KB–MB | Frequency estimation stream |
Nguyên tắc chọn: nếu SLA chỉ yêu cầu "khoảng X người" hoặc "top hashtag gần đúng", probabilistic structure tiết kiệm bộ nhớ 100–1000x. Nếu dùng cho billing, audit, hoặc kết quả hiển thị cho từng user cụ thể (rank chính xác của tôi), cần exact structure.
Persistence & Pipeline
Persistence cho analytics counter
Mất một vài giây counter do Redis restart thường chấp nhận được cho dashboard analytics (RDB snapshot mỗi 5–15 phút là đủ). Nhưng nếu counter dùng cho billing (số transaction tính tiền) hoặc audit log, cần AOF với appendfsync everysec hoặc always. Trade-off rõ ràng: AOF everysec giảm throughput ~30% so với không có persistence.
# RDB: snapshot mỗi 60s nếu ít nhất 1000 key thay đổi
save 60 1000
# AOF: safe cho billing counter, overhead ~30%
appendonly yes
appendfsync everysec
Pipeline để tăng throughput
Khi ingest 100k event/s, nếu mỗi event là 1 round-trip Redis, network latency trở thành bottleneck ngay cả khi Redis đủ nhanh. Pipeline batch nhiều command trong 1 round-trip:
import redis
r = redis.Redis()
# Không pipeline: 100 round-trip
for event in events[:100]:
r.incr(f"counter:{event.page}:{event.date}")
# Với pipeline: 1 round-trip cho 100 INCR
pipe = r.pipeline(transaction=False)
for event in events[:100]:
pipe.incr(f"counter:{event.page}:{event.date}")
pipe.execute()
# Throughput tăng 10–50x tuỳ network latency
Lưu ý: transaction=False không wrap trong MULTI/EXEC — phù hợp cho analytics counter vì không cần atomicity toàn batch, chỉ cần atomicity từng INCR riêng lẻ.
Decision Framework
Khi đứng trước một bài toán analytics, dùng flow sau để chọn công cụ:
Cần kết quả < 1s lag?
Không → Data Warehouse (BigQuery, Redshift)
Có → tiếp tục
Cần historical > 7 ngày kết hợp?
Có → Hybrid: Redis (realtime) + Data Warehouse (historical)
Không → Redis đủ
Loại query:
Counter đơn giản (increment/read)?
→ INCR / HINCRBY
Leaderboard / top-N với rank?
→ Sorted Set
Membership check (đã có chưa)?
→ Bloom Filter (RedisBloom)
Distinct count, chấp nhận ~1% error?
→ HyperLogLog
Distinct count, cần exact, dataset nhỏ (< 10M)?
→ Set
DAU/MAU với integer user_id?
→ Bitmap
Top-K trên high-cardinality stream?
→ Sorted Set + sliding window, hoặc TOPK (RedisBloom)
Time series (latency/throughput metrics)?
→ RedisTimeSeries
Frequency estimation trên log stream?
→ Count-Min Sketch (RedisBloom)
Deep GROUP BY nhiều chiều?
→ ClickHouse / Druid (Redis không phù hợp)
Framework này không absolute — nhiều bài toán thực tế kết hợp nhiều cấu trúc. Ví dụ: leaderboard gaming dùng Sorted Set cho rank + HLL cho unique player count + Bitmap cho DAU.
Tổng Kết & Quiz
Module 8 tập trung vào nhóm bài toán analytics và counting — nơi Redis có lợi thế rõ ràng so với các hệ thống khác nhờ in-memory operations, atomic INCR, và các data structure chuyên biệt. Các điểm cốt lõi:
- SQL OLTP chậm cho analytics vì mỗi counter update là một row lock + WAL; aggregate trên 1B row mất giây đến phút.
- Data warehouse có ingestion lag 5–60 phút và query latency 1–30s — phù hợp historical, không phù hợp dashboard realtime.
- OLAP engine (ClickHouse) tốt cho deep analytics nhưng over-engineering cho counter đơn giản và vẫn có 2–5s ingestion lag.
- Redis phù hợp nhờ: < 1ms latency, 1M+ op/s atomic INCR, Sorted Set O(log N) cho leaderboard, Bitmap 12.5MB cho 100M user DAU, HyperLogLog 12KB cho distinct count xấp xỉ.
- Chọn exact (Set, Sorted Set, Bitmap) khi cần chính xác tuyệt đối; chọn probabilistic (HLL, Bloom, Count-Min) khi chấp nhận sai số nhỏ để tiết kiệm memory 100–1000x.
- Hệ thống production thường dùng hybrid Lambda: Redis cho 24–48h gần nhất, data warehouse cho historical.
Quiz
- Tại sao
SELECT COUNT(DISTINCT user_id) FROM events WHERE date = todaychậm hơnBITCOUNT dau:todaynhiều bậc, ngay cả khi PostgreSQL có index trênuser_id? - Một team đang tính DAU bằng Redis Set:
SADD dau:today user_id. Sau 3 tháng, mỗi Set chứa 20M user_id (UUID string). Tính bộ nhớ xấp xỉ và đề xuất thay thế phù hợp hơn với lý do. - Dashboard cần hiển thị "đơn hàng hôm nay" (realtime, cập nhật mỗi 5s) và "đơn hàng 12 tháng qua theo ngày" (historical). Đề xuất kiến trúc và giải thích tại sao không dùng chỉ Redis hoặc chỉ data warehouse.
- Khi nào nên dùng
transaction=Falsevới Redis pipeline thay vìtransaction=True(MULTI/EXEC)? Cho ví dụ cụ thể với analytics counter. - Bloom filter "không có false negative" nghĩa là gì? Nếu
BF.EXISTS email:registered [email protected]trả về 0, điều gì chắc chắn? Nếu trả về 1, điều gì chắc chắn?
Đáp án gợi ý
- PostgreSQL cần scan hoặc sort toàn bộ user_id của ngày đó để dedup — O(N log N).
BITCOUNTdùng CPU POPCNT instruction trên mảng bit compact trong RAM — O(N/8) và N/8 rất nhỏ. Ngoài ra không có disk I/O và không có query planning overhead. - UUID string 36 ký tự × 20M = ~720MB per Set, cộng Redis overhead per member (~50 bytes) ≈ 1.7GB per ngày, 90 ngày = ~150GB. Thay bằng: (a) Bitmap nếu user_id là integer dense: 20M bit = 2.5MB per ngày; (b) HyperLogLog nếu chỉ cần count xấp xỉ: 12KB per ngày.
- Kiến trúc Lambda: Redis lưu counter từng ngày với TTL 48h → dashboard đọc "hôm nay". Data warehouse (BigQuery/Redshift) nhận event qua Kinesis Firehose, job hourly tổng hợp → dashboard đọc historical. Dùng chỉ Redis: không kinh tế lưu 12 tháng counter chi tiết, và thiếu khả năng GROUP BY phức tạp. Dùng chỉ data warehouse: lag 5–60 phút cho "hôm nay" là không chấp nhận được.
transaction=Falsekhi các command độc lập nhau và không cần atomicity toàn batch. Ví dụ: increment 100 counter page view khác nhau — OK nếu một vài cái fail (retry từng cái). Dùngtransaction=Truekhi cần all-or-nothing: ví dụ transfer điểm từ A sang B (DECRBY A + INCRBY B phải cùng succeed hoặc cùng fail).- Bloom filter "no false negative": nếu
BF.EXISTStrả về 0 → item chắc chắn KHÔNG có trong set (100% chắc chắn). Nếu trả về 1 → item có thể có hoặc là false positive (không 100% chắc chắn — cần verify DB nếu cần exact answer). Nói ngắn: kết quả "không" là đáng tin; kết quả "có" cần xác nhận thêm tuỳ SLA.
Bài tiếp theo
Bài 90 đi vào chi tiết đầu tiên của module: Realtime Counter Patterns — INCR đơn giản, sharded counter khi cần throughput > 1M/s trên một key, throttled counter giảm write overhead, và các pattern production-proven khác.
