[ ♥REC. ] ·Đề xuất kỹ thuật — Bản nội bộ (VN)
🇻🇳 Tiếng Việt 🇯🇵 JP: team-proposal-jp.html
📋 Đề xuất kỹ thuật LRCC-2386 2026-05-19 | Amela 開発チーム

Hiện đại hoá tốc độ CMS
song song giữ độ mới dữ liệu

Tiếp nối báo cáo phân tích nguyên nhân chậm (LRCC-2386), đây là đề xuất giải pháp dài hạn để CMS xử lý được khối lượng dữ liệu đã tăng lên đáng kể, mà vẫn đáp ứng yêu cầu thực tế của quý khách về độ tươi dữ liệu.

TÓM TẮT ĐỀ XUẤT
  • Quyết định ban đầu (realtime, query trực tiếp) hoàn toàn đúng với bối cảnh lúc đó
  • Dữ liệu nay đã tăng quy mô đáng kể → cần evolve architecture
  • Đề xuất kiến trúc 2 lớp — chuẩn industry (GA, Stripe, Mixpanel áp dụng)
  • Tốc độ: 60 giây → <1 giây, độ tươi vẫn ~5 phút
01 | Bối cảnh

Quyết định ban đầu — và hiện trạng

Hiểu đúng bối cảnh trước khi đề xuất thay đổi.

QUYẾT ĐỊNH BAN ĐẦU ~ ngày đầu dự án

Realtime + query trực tiếp DB

Lúc khởi tạo CMS, quý khách yêu cầu dashboard phải hiển thị dữ liệu mới nhất theo thời gian thực. Để đáp ứng yêu cầu này một cách trung thực nhất, team chọn query trực tiếp từ database mỗi khi admin mở trang.

Quyết định này là chuẩn xác: dataset lúc đó còn nhỏ, query nặng vẫn chạy trong 1–2 giây, và việc đảm bảo độ chính xác tuyệt đối là ưu tiên hàng đầu.

HIỆN TRẠNG 2026-05 data đã tăng ~50–100×

Cùng cách làm — nhưng dữ liệu đã lớn

Sau 1–2 năm vận hành, các bảng giao dịch đã tăng quy mô: video_view ~5M dòng, transaction ~3M dòng.

Cùng câu query đó hiện cần quét ~150 triệu dòng mỗi lần admin mở trang → 60 giây+ tải (chi tiết trong báo cáo LRCC-2386).

Xem chi tiết: customer-report.html

Nói cách khác: cách làm cũ không sai — chỉ là không scale được khi dữ liệu lớn lên. Đây là một bước phát triển bình thường trong vòng đời mọi sản phẩm dữ liệu.
— Amela 開発チーム
02 | Đề xuất kiến trúc

Kiến trúc 2 lớp — Industry standard

Thay vì query trực tiếp mỗi request, chia làm 2 lớp đệm — đây là pattern mặc định của mọi dashboard analytics lớn.

HIỆN TẠI
CMS Admin Page
Backend API
Query trực tiếp DB
~150M dòng / request
60 giây
ĐỀ XUẤT
CMS Admin Page
Backend API
Layer 1 | Redis Cache
TTL 5–10 phút · <100ms
↓ (cache miss)
Layer 2 | Aggregate Tables
Refresh mỗi 15 phút · <1 giây
↓ (fallback)
Database gốc
chỉ chạm khi cần dữ liệu rất mới
< 1 giây
LAYER 1

Redis Cache

Lưu tạm kết quả query trong bộ nhớ tốc độ cao. Mỗi request kiểm tra cache trước, chỉ chạm database nếu cache miss hoặc hết hạn (TTL 5–10 phút).

  • +Lần đầu mở trang vẫn như cũ (cache miss)
  • +Mọi lần sau trong 10 phút: <100ms
  • +Hạ tầng Redis hiện đã có sẵn trong stack — không phát sinh chi phí
LAYER 2

Pre-aggregate Tables

Tạo bảng tổng hợp theo ngày (vd: partnership_revenue_daily), cron job nền refresh mỗi 15–30 phút. Query phức tạp được rút gọn thành SUM trên bảng nhỏ.

  • +Query 6-tháng-data → chỉ scan ~180 dòng thay vì 150 triệu
  • +Response <1 giây cho mọi filter dài hạn
  • +Áp dụng được cho các trang aggregate khác (Sales, Member statistics)
03 | Industry Standard

Đây là cách xử lý chuẩn ngành

Mọi dashboard analytics quy mô lớn đều dùng kiến trúc này. Không phải workaround — đây là pattern được tài liệu hoá trong sách giáo khoa kiến trúc hệ thống.

Google Analytics
Phục vụ hàng triệu site/ngày
"Standard reports are processed and updated approximately every 24–48 hours. Real-time reports are shown in a separate panel with last 30 minutes only."
Stripe Dashboard
Trang quản trị thanh toán toàn cầu
"Dashboard metrics may reflect data with a slight delay (up to a few minutes). For real-time data, use Stripe Sigma queries or the events API."
Mixpanel
Product analytics platform
"Charts and funnels use hourly aggregated cubes. Live View shows events from the last 100 records only."
Amazon QuickSight
AWS BI service
"SPICE in-memory cache refreshes on schedule (hourly to daily). Direct query mode available but recommended only for sub-million-row tables."
Snowflake / BigQuery
Data warehouse hàng đầu
"Materialized views automatically pre-aggregate query results. Standard pattern for dashboards over large fact tables."
Shopify Admin
Trang quản trị thương mại điện tử
"Analytics data has a delay of approximately 30 minutes to ensure performance and consistency across merchants."
Pattern này có tên kỹ thuật chính thức: OLAP query optimization — tách biệt query giao dịch (OLTP: cần real-time, ít hàng) khỏi query thống kê (OLAP: tổng hợp, cache). Mọi sản phẩm analytics doanh nghiệp đều áp dụng. Việc LoveRec evolve theo hướng này là một bước phát triển tự nhiên, không phải khắc phục lỗi.
04 | Đảm bảo độ tươi dữ liệu

Giảm thiểu lo ngại về "realtime"

Hiểu rằng yêu cầu ban đầu của quý khách về dữ liệu real-time là chính đáng. Đề xuất này có sẵn cơ chế đảm bảo độ tươi vẫn ở mức gần như real-time.

QUAN NGẠI
"Cache thì dữ liệu có bị stale không?"
Trả lời: TTL cache đặt 5–10 phút — gần như real-time với context CMS admin. Admin Nhật mở dashboard thường để xem trend, không phải để quyết định trong vòng 30 giây. Lag 5 phút trên 1 trang aggregate không khác biệt cảm nhận với "tức thì".
QUAN NGẠI
"Nếu admin cần xem ngay lập tức số mới nhất thì sao?"
Trả lời: Thêm nút 「🔄 最新を取得 / Refresh now」 trên trang — admin click thì bypass cache và query trực tiếp 1 lần. Tốc độ vẫn lâu (vì là query gốc), nhưng tự admin chủ động chấp nhận thời gian chờ. Trải nghiệm tương tự nút "Refresh" của Stripe Dashboard.
QUAN NGẠI
"Admin có biết dữ liệu là phiên bản nào không?"
Trả lời: Hiển thị nhãn 「3 phút trước に更新」 ở góc trang — minh bạch về độ tươi. Admin luôn biết dữ liệu được tổng hợp lúc nào.
QUAN NGẠI
"Có chức năng nào VẪN cần real-time tuyệt đối không?"
Trả lời: Đề xuất chỉ áp dụng cho các trang aggregate / thống kê (doanh thu tổng, số members theo plan, v.v…). Các tính năng cần real-time tuyệt đối (thông báo, chat, danh sách user đang online) vẫn giữ nguyên query trực tiếp.
05 | Lộ trình triển khai

Đề xuất 2 phase

Có thể chia thành 2 release, mỗi phase đều cho thấy hiệu quả rõ rệt.

1

Phase 1 — Redis cache layer

Effort: 1–2 ngày ROI cao nhất

Thêm cache layer cho 5 endpoint nặng nhất trong CMS (revenue, statistics, member list). Lần đầu admin mở vẫn 60 giây (cache miss); từ lần thứ 2 trong 10 phút → <100ms.

Risk: rất thấp (rollback chỉ là disable cache)
Visible to KH: Tốc độ load nhanh hơn nhiều
Test plan: A/B trong 1 tuần
2

Phase 2 — Pre-aggregate tables

Effort: 3–5 ngày Giải pháp gốc

Tạo các bảng *_daily, cron job refresh mỗi 15 phút (sử dụng cron-job-service đã có sẵn). Query nặng → <1 giây ngay cả lần đầu.

Risk: thấp (bảng cũ giữ nguyên, chỉ thêm bảng aggregate)
Visible to KH: Tốc độ ổn định <1 giây mọi lúc
Áp dụng được cho 80% trang dashboard khác
3

Phase 3 — Refresh button + freshness label (UI)

Effort: 1 ngày Tuỳ chọn

Thêm nút "Refresh now" + nhãn "Updated X minutes ago" trên các trang aggregate. Cho admin quyền chủ động lấy bản mới nhất khi cần. Đáp ứng nốt yêu cầu real-time cho 1% case đặc biệt.

Đề xuất quyết định

Trước khi gửi bản này cho quý khách, mong BA + PM team duyệt:

  1. 1
    Có nên gửi bản này cho KH không — hay chỉ áp dụng Phase 1 (cache) im lặng? Khuyến nghị: gửi, vì sự minh bạch xây dựng tin cậy + Phase 2 cần buy-in từ KH (có visible delay).
  2. 2
    Có nên đi cả 3 phase hay tách thành 2 đề xuất riêng (Phase 1 trước, Phase 2/3 sau khi KH thấy kết quả Phase 1)? Khuyến nghị: đi cả 3 — communication 1 lần.
  3. 3
    Effort tổng 5–8 ngày dev — có fit vào sprint kế tiếp không? Có thể phải tradeoff với feature khác — cần PM align.
FILE LIÊN QUAN
  • 📋 Backlog: LRCC-2386
  • 📄 Báo cáo nguyên nhân: customer-report.html
  • 📄 Phân tích kỹ thuật chi tiết: perf-root-cause.md
  • 🇯🇵 Bản gửi KH (JP): team-proposal-jp.html
Amela Dev Team | Bản nội bộ — chưa gửi KH
2026-05-19