Chương 34. Analytics và dữ liệu hành vi
Ở các chương trước, ta đã nói về dữ liệu dùng để vận hành hệ thống:
- Database.
- Cache.
- Search.
- File storage.
Chương này nói về một loại dữ liệu khác:
Dữ liệu phân tích.
Hay nói gần gũi hơn:
Dữ liệu để hiểu chuyện gì đang xảy ra.
Ví dụ:
- User vào trang nào nhiều nhất?
- Học sinh bỏ dở bài ở bước nào?
- Tính năng nào ít được dùng?
- Một bài học mất trung bình bao lâu để hoàn thành?
- Bao nhiêu người bấm "nộp bài" nhưng không hoàn tất?
- AI Judge mất bao lâu từ lúc nhận bài đến lúc trả kết quả?
- Chi phí gọi AI theo từng lớp/course là bao nhiêu?
- Tỉ lệ bài chấm lỗi là bao nhiêu?
Đây không phải dữ liệu để xử lý một request ngay lập tức.
Đây là dữ liệu để:
- Làm dashboard.
- Phân tích sản phẩm.
- Theo dõi hành vi.
- Tối ưu vận hành.
- Tính chi phí.
- Tìm vấn đề trong funnel.
- Ra quyết định sau khi nhìn số liệu.
Thông điệp chính của chương:
> Dữ liệu vận hành giúp hệ thống chạy đúng. Dữ liệu analytics giúp ta hiểu hệ thống đang được dùng như thế nào. Đừng nhét mọi event hành vi vào database chính nếu traffic bắt đầu lớn.
---
34.1. Ví dụ dễ hiểu: cửa hàng và sổ bán hàng
Một cửa hàng có hai loại ghi chép.
Loại 1: sổ bán hàng chính thức.
Đơn hàng số 123.
Khách A.
Đã thanh toán.
Tổng tiền 250.000.
Sổ này phải đúng.
Nếu sai, tiền bạc và giao hàng sẽ rối.
Loại 2: ghi chú quan sát hành vi.
10 người đi ngang qua kệ bánh dâu.
6 người cầm lên xem.
3 người bỏ vào giỏ.
2 người mua.
Ghi chú này rất hữu ích để hiểu khách.
Nhưng nếu thiếu một dòng, cửa hàng vẫn giao hàng được.
Nếu ghi chú trễ 5 phút, đơn hàng vẫn không sai.
Trong phần mềm cũng vậy.
Database vận hành giống sổ bán hàng chính thức.
Analytics giống ghi chú hành vi.
Hai thứ đều quan trọng, nhưng mức độ "phải đúng ngay" khác nhau.
---
34.2. Dữ liệu vận hành là gì?
Dữ liệu vận hành là dữ liệu hệ thống dùng để chạy nghiệp vụ.
Ví dụ trong AI Judge:
User
Course
Assignment
Submission
GradingJob
GradingResult
Payment
Permission
Dữ liệu này trả lời câu hỏi:
Hệ thống cần làm gì ngay bây giờ?
Ví dụ:
- User này có được nộp bài không?
- Assignment còn mở không?
- Submission đã được chấm chưa?
- Điểm chính thức là bao nhiêu?
- Teacher có quyền xem lớp này không?
- Job này đang pending hay completed?
Dữ liệu vận hành cần:
- Đúng.
- Nhất quán.
- Có transaction.
- Có constraint.
- Có quyền truy cập rõ.
- Có backup tốt.
- Có thể query cho nghiệp vụ.
Đây là nơi relational database rất mạnh.
---
34.3. Dữ liệu phân tích là gì?
Dữ liệu phân tích là dữ liệu dùng để nhìn lại và hiểu hành vi.
Ví dụ:
UserViewedAssignment
UserClickedSubmit
SubmissionUploadStarted
SubmissionUploadCompleted
GradingStarted
GradingCompleted
FeedbackViewed
PaymentButtonClicked
SearchPerformed
Dữ liệu này trả lời câu hỏi:
Chuyện gì đã xảy ra theo thời gian?
Ví dụ:
- Bao nhiêu học sinh mở assignment nhưng không nộp?
- Bao nhiêu người upload lỗi?
- Thời gian chấm trung bình là bao nhiêu?
- Search keyword nào phổ biến?
- Teacher có dùng tính năng rubric không?
- Lớp nào tốn nhiều chi phí AI nhất?
- User rời khỏi flow ở bước nào?
Analytics không phải để thay thế dữ liệu nghiệp vụ.
Nó là lớp quan sát.
---
34.4. Một ví dụ rất cụ thể
Học sinh bấm nộp bài.
Dữ liệu vận hành cần ghi:
Submission created.
File attached.
GradingJob pending.
Nếu ghi thiếu những thứ này, hệ thống hỏng.
Dữ liệu analytics có thể ghi:
submit_button_clicked
submission_upload_started
submission_upload_completed
grading_result_viewed
Nếu một event analytics bị mất, dashboard có thể lệch một chút.
Nhưng bài nộp vẫn phải tồn tại.
Điểm vẫn phải đúng.
Đây là khác biệt sống còn:
> Operational data là dữ liệu hệ thống cần để hành động. Analytics data là dữ liệu con người cần để hiểu và cải thiện.
---
34.5. Vì sao không nên nhét mọi event vào database chính?
Lúc đầu, làm đơn giản là hợp lý.
Ví dụ:
INSERT INTO events (...)
vào PostgreSQL chính.
Nếu traffic nhỏ, không sao.
Nhưng analytics event có một đặc điểm:
Rất nhiều.
Một page view cũng là event.
Một click cũng là event.
Một lần search cũng là event.
Một lần mở feedback cũng là event.
Một user trong 10 phút có thể tạo hàng chục event.
Nếu có 10.000 user hoạt động, số event tăng rất nhanh.
Database chính có thể bị kéo vào việc ghi những thứ không trực tiếp cần cho nghiệp vụ.
Hậu quả:
- Bảng event phình nhanh.
- Index nặng.
- Backup chậm.
- Query nghiệp vụ bị ảnh hưởng.
- Replication nặng.
- Chi phí tăng.
- Migration khó.
- Vacuum/maintenance mệt hơn nếu dùng PostgreSQL.
Nói ngắn:
> Đừng để dữ liệu "để phân tích sau" làm nghẽn dữ liệu "để hệ thống chạy đúng ngay".
---
34.6. Nhưng có phải lúc nào cũng cần pipeline riêng không?
Không.
Đây là điểm thực dụng.
Nếu sản phẩm còn nhỏ, có thể bắt đầu bằng cách đơn giản.
Ví dụ:
events table trong database chính.
Hoặc:
Gửi event sang một dịch vụ analytics có sẵn.
Không cần dựng Kafka, warehouse, data lake từ ngày đầu.
Điều cần là biết giới hạn.
Bắt đầu đơn giản khi:
- Traffic thấp.
- Event ít.
- Dashboard chưa quan trọng.
- Team nhỏ.
- Chưa có nhu cầu phân tích sâu.
- Dữ liệu có thể xoá/gom theo thời gian.
Tách pipeline khi:
- Event quá nhiều.
- Query analytics làm chậm database chính.
- Cần dashboard phức tạp.
- Cần join nhiều nguồn dữ liệu.
- Cần lưu lịch sử dài.
- Cần phân tích theo batch.
- Cần data team hoặc BI tool.
- Cần replay/backfill.
Senior không phải là người dùng công nghệ to nhất.
Senior là người biết khi nào cái đơn giản bắt đầu không còn đủ.
---
34.7. Event analytics là gì?
Event analytics là một bản ghi nói rằng:
Ai đó đã làm gì đó, vào lúc nào đó, trong ngữ cảnh nào đó.
Ví dụ:
{
"event_name": "submission_uploaded",
"user_id": "user_9",
"assignment_id": "assignment_12",
"course_id": "course_3",
"file_size_mb": 8.1,
"created_at": "2026-05-12T10:15:00Z"
}
Một event tốt thường có:
- Tên event.
- Thời gian.
- Actor: ai làm.
- Object: làm với cái gì.
- Context: ở đâu, thiết bị nào, course nào.
- Properties: số liệu phụ.
Tên event nên rõ:
submission_upload_started
submission_upload_completed
grading_completed
feedback_viewed
search_performed
Không nên quá mơ hồ:
click
action
event
thing_happened
Vì vài tháng sau nhìn lại sẽ không hiểu.
---
34.8. Event analytics khác domain event không?
Có liên quan, nhưng không giống hoàn toàn.
Domain event là sự kiện nghiệp vụ quan trọng.
Ví dụ:
SubmissionCreated
GradingCompleted
PaymentSucceeded
Nó có thể được service khác dùng để làm việc thật:
Gửi email.
Cập nhật trạng thái.
Tạo invoice.
Tính quota.
Analytics event dùng để quan sát hành vi.
Ví dụ:
submit_button_clicked
assignment_page_viewed
feedback_panel_expanded
search_performed
Một số event có thể vừa là domain event vừa được dùng cho analytics.
Ví dụ:
GradingCompleted
Vừa quan trọng cho nghiệp vụ, vừa hữu ích cho báo cáo.
Nhưng không nên trộn hết vào một mớ.
Tư duy:
Domain event:
hệ thống cần biết để phản ứng nghiệp vụ.
Analytics event:
con người cần biết để phân tích hành vi.
---
34.9. Page view, click, business event
Analytics event có nhiều cấp độ.
Page view:
assignment_page_viewed
pricing_page_viewed
feedback_page_viewed
Click:
submit_button_clicked
retry_button_clicked
download_report_clicked
Business event:
submission_created
grading_completed
payment_succeeded
course_completed
Page view/click thường nhiều và nhiễu hơn.
Business event ít hơn nhưng quan trọng hơn.
Nếu mới làm analytics, nên ưu tiên business event trước.
Vì nó trả lời câu hỏi rõ hơn:
Người dùng có hoàn thành việc quan trọng không?
Sau đó mới thêm các event nhỏ để phân tích funnel.
---
34.10. Funnel là gì?
Funnel là chuỗi bước user đi qua để hoàn thành một việc.
Ví dụ AI Judge:
1. Mở assignment.
2. Bấm upload.
3. Upload thành công.
4. Bấm nộp.
5. Nhận kết quả chấm.
6. Mở feedback.
Nếu 1.000 học sinh mở assignment:
900 bấm upload
850 upload thành công
830 bấm nộp
820 nhận kết quả
500 mở feedback
Ta học được:
Nhiều người nhận kết quả nhưng không mở feedback.
Có thể feedback khó thấy.
Hoặc user chỉ quan tâm điểm.
Hoặc thời gian chấm quá lâu khiến họ rời đi.
Analytics giúp ta hỏi đúng câu hỏi.
Không có analytics, ta chỉ đoán.
---
34.11. Metrics khác event thế nào?
Event là chuyện xảy ra.
Ví dụ:
grading_completed
Metric là con số đo được.
Ví dụ:
grading_duration_seconds = 87
grading_success_count = 1
grading_error_count = 0
queue_wait_seconds = 12
Event thường dùng để phân tích hành vi/sản phẩm.
Metric thường dùng để monitoring/vận hành.
Nhưng chúng có thể liên quan.
Ví dụ event grading_completed có property:
duration_seconds = 87
model = gemini-...
cost_usd = 0.02
Từ đó analytics có thể tính:
- Thời gian chấm trung bình.
- Chi phí trung bình mỗi bài.
- Tỉ lệ lỗi theo model.
- Lớp nào tạo nhiều workload.
---
34.12. Log khác analytics thế nào?
Log là nhật ký kỹ thuật để debug.
Ví dụ:
Worker received job job_123.
Gemini API returned timeout.
Retry attempt 2.
Analytics là dữ liệu có cấu trúc để phân tích hành vi hoặc kinh doanh.
Ví dụ:
grading_failed
reason=timeout
model=gemini
assignment_id=12
Log thường đọc khi có sự cố.
Analytics thường tổng hợp thành dashboard/báo cáo.
Đừng chỉ có log rồi nghĩ là đã có analytics.
Log nhiều nhưng khó trả lời:
Trong 30 ngày qua, lớp nào có chi phí AI cao nhất?
Analytics event được thiết kế để trả lời những câu hỏi kiểu đó.
---
34.13. Kiến trúc analytics đơn giản nhất
Bản đơn giản:
App -> Database events table -> Dashboard query
Ví dụ:
events
------
id
event_name
user_id
properties_json
created_at
Ưu điểm:
- Dễ làm.
- Dễ debug.
- Không cần nhiều hạ tầng.
- Phù hợp giai đoạn đầu.
Nhược điểm:
- Dữ liệu tăng nhanh.
- Query dashboard có thể nặng.
- JSON khó kiểm soát schema.
- Database chính bị kéo thêm tải.
Nếu dùng cách này, nên:
- Giới hạn event cần ghi.
- Có retention.
- Index tối thiểu.
- Không query dashboard nặng trực tiếp trên DB production.
- Cân nhắc read replica nếu cần.
- Dọn dữ liệu cũ.
Đơn giản không sai.
Nhưng phải biết nó sẽ đau ở đâu.
---
34.14. Kiến trúc phổ biến hơn: event collector
Khi event nhiều hơn, ta có thể tách một service nhận event.
Luồng:
Frontend/Backend
-> Analytics Collector
-> Queue/Stream
-> Storage/Warehouse
Collector làm nhiệm vụ:
- Nhận event.
- Validate schema cơ bản.
- Gắn metadata.
- Rate limit.
- Đẩy vào queue/stream.
- Không làm chậm request chính.
Ví dụ:
Browser gửi assignment_page_viewed.
Collector nhận.
Collector ghi vào queue.
Worker/pipeline đưa vào warehouse.
Ưu điểm:
- Tách tải khỏi app chính.
- Có thể scale riêng.
- Có thể xử lý event bất đồng bộ.
- Có thể gom nhiều nguồn event.
Nhược điểm:
- Thêm service.
- Thêm pipeline.
- Thêm monitoring.
- Thêm vấn đề mất/trễ event.
Không nên dựng collector riêng nếu chưa cần.
Nhưng khi event lớn, nó là một bước tự nhiên.
---
34.15. Queue hay stream cho analytics?
Với analytics đơn giản, queue có thể đủ.
Ví dụ:
App -> Queue -> Analytics worker -> Warehouse
Queue hợp khi:
- Event không quá lớn.
- Consumer xử lý từng job.
- Cần retry.
- Pipeline đơn giản.
Stream như Kafka/Pulsar/Kinesis/Pub/Sub hợp khi:
- Event rất nhiều.
- Nhiều consumer cùng đọc.
- Cần replay.
- Cần lưu lịch sử event trong một thời gian.
- Cần xử lý gần real-time.
Đừng dùng Kafka chỉ vì analytics nghe to.
Hãy hỏi:
Có bao nhiêu event mỗi giây?
Có cần replay không?
Có bao nhiêu consumer?
Có cần real-time không?
Team có vận hành nổi không?
Nếu chưa trả lời được, bắt đầu đơn giản hơn.
---
34.16. Batch analytics là gì?
Batch analytics là xử lý dữ liệu theo lô.
Ví dụ:
Mỗi giờ tổng hợp.
Mỗi ngày tính báo cáo.
Mỗi đêm chạy job thống kê.
Luồng:
Event được lưu lại
-> đến giờ job chạy
-> đọc dữ liệu
-> tính số liệu
-> ghi vào bảng dashboard/report
Batch hợp khi:
- Không cần real-time.
- Báo cáo theo ngày/tuần/tháng.
- Dữ liệu lớn nhưng có thể xử lý chậm.
- Muốn giảm độ phức tạp.
Ví dụ AI Judge:
Mỗi đêm tính:
số bài nộp mỗi lớp
thời gian chấm trung bình
chi phí AI mỗi assignment
tỉ lệ lỗi theo model
Kết quả sáng hôm sau có là đủ.
Không cần realtime.
---
34.17. Streaming analytics là gì?
Streaming analytics là xử lý event gần như ngay khi chúng đến.
Ví dụ:
Event xảy ra
-> vài giây sau dashboard cập nhật
Streaming hợp khi:
- Cần cảnh báo nhanh.
- Cần dashboard realtime.
- Cần phát hiện bất thường sớm.
- Event volume lớn.
- Nhiều consumer cần đọc cùng luồng event.
Ví dụ:
AI Judge đang có 5.000 bài nộp trong 10 phút.
Queue wait tăng nhanh.
Gemini timeout tăng.
Chi phí API tăng bất thường.
Nếu cần phát hiện trong vài giây/phút, streaming hữu ích.
Nhưng streaming phức tạp hơn batch.
Câu hỏi thực dụng:
> Nếu số liệu trễ 1 giờ vẫn ổn, đừng vội làm streaming phức tạp.
---
34.18. Data warehouse là gì?
Data warehouse là nơi lưu dữ liệu để phân tích.
Nó được tối ưu cho:
- Query lớn.
- Báo cáo.
- Aggregation.
- Join nhiều bảng lớn.
- BI dashboard.
- Phân tích lịch sử.
Ví dụ công nghệ:
- BigQuery.
- Snowflake.
- Redshift.
- ClickHouse.
- DuckDB cho quy mô nhỏ/local.
- PostgreSQL riêng cho analytics ở giai đoạn đầu.
Database chính trả lời:
User này có quyền nộp bài không?
Data warehouse trả lời:
Trong 90 ngày qua, thời gian chấm trung bình theo course/model/giờ trong ngày là bao nhiêu?
Hai câu hỏi khác nhau.
Một cái cần đúng ngay cho nghiệp vụ.
Một cái cần quét nhiều dữ liệu để phân tích.
---
34.19. Data lake là gì?
Data lake là nơi lưu dữ liệu thô hoặc bán thô, thường ở dạng file/object storage.
Ví dụ:
events/2026/05/12/hour=10/events.parquet
events/2026/05/12/hour=11/events.parquet
Data lake thường dùng để:
- Lưu dữ liệu thô lâu dài.
- Cho phép xử lý lại sau.
- Làm nguồn cho warehouse.
- Lưu dữ liệu nhiều dạng.
- Giảm chi phí lưu trữ.
Nếu warehouse giống kho đã sắp xếp để query tiện, thì data lake giống kho nguyên liệu.
Dữ liệu vào data lake có thể chưa sạch hoàn toàn.
Sau đó pipeline sẽ transform thành bảng dễ query trong warehouse.
---
34.20. ETL và ELT
ETL:
Extract -> Transform -> Load
Nghĩa là:
Lấy dữ liệu ra
-> biến đổi/làm sạch
-> nạp vào warehouse
ELT:
Extract -> Load -> Transform
Nghĩa là:
Lấy dữ liệu ra
-> nạp thô vào warehouse/lake
-> biến đổi sau trong đó
Không cần nhớ thuật ngữ quá nặng.
Ý chính là:
> Dữ liệu analytics thường cần một quá trình đưa từ hệ thống vận hành sang nơi phân tích, rồi làm sạch/tổng hợp để query được.
---
34.21. Một pipeline analytics vừa phải
Một thiết kế thực dụng:
App/Backend
-> Analytics event
-> Queue/Stream
-> Raw storage
-> Transform job
-> Warehouse
-> Dashboard
Cụ thể:
1. App tạo event.
2. Event được gửi bất đồng bộ.
3. Collector/queue nhận event.
4. Raw event được lưu lại.
5. Job định kỳ làm sạch/tổng hợp.
6. Warehouse có bảng phục vụ dashboard.
7. BI tool đọc warehouse.
Không phải hệ thống nào cũng cần đủ 7 bước.
Nhưng đây là bản đồ để hiểu người ta đang làm gì.
---
34.22. Raw data và cleaned data
Raw data là dữ liệu gốc.
Ví dụ:
{
"event": "submission_uploaded",
"user_id": "user_9",
"properties": {
"size": "8MB",
"assignment": 12
},
"client_time": "..."
}
Cleaned data là dữ liệu đã được chuẩn hóa.
Ví dụ:
event_name = submission_uploaded
user_id = user_9
assignment_id = assignment_12
file_size_bytes = 8388608
occurred_at = ...
received_at = ...
Raw data giúp backfill nếu logic transform sai.
Cleaned data giúp dashboard query dễ hơn.
Nếu chỉ giữ cleaned data, khi phát hiện transform sai có thể khó sửa.
Nếu chỉ giữ raw data, mọi query đều mệt.
Thường cần cả hai ở mức phù hợp.
---
34.23. Schema analytics
Analytics event cũng cần schema.
Nếu không, sau vài tháng sẽ có mớ dữ liệu kiểu:
submissionId
submission_id
sub_id
sid
Rồi không ai biết field nào đúng.
Nên định nghĩa rõ:
event_name: submission_uploaded
required properties:
user_id
assignment_id
submission_id
file_size_bytes
occurred_at
Schema giúp:
- Dashboard đáng tin hơn.
- Data team đỡ đoán.
- Event không bị vỡ khi frontend đổi.
- Dễ validate.
- Dễ viết tài liệu.
Không cần quá hình thức từ đầu.
Nhưng event quan trọng nên có định nghĩa rõ.
---
34.24. Event naming
Tên event nên mô tả hành động đã xảy ra.
Tốt:
assignment_viewed
submission_upload_started
submission_upload_completed
grading_completed
feedback_viewed
report_downloaded
Kém:
click_button
open_page
submit
success
done
Vì "submit" là submit gì?
"success" là thành công việc nào?
"done" là ai làm xong cái gì?
Tên event nên đủ cụ thể để người đọc dashboard hiểu mà không cần mở code.
---
34.25. Thời gian trong analytics
Analytics rất nhạy với thời gian.
Cần phân biệt:
occurred_at: thời điểm event xảy ra ở client/server
received_at: thời điểm hệ thống analytics nhận event
processed_at: thời điểm pipeline xử lý event
Ví dụ:
User offline.
Client lưu event tạm.
10 phút sau mới gửi lên.
Lúc này:
occurred_at khác received_at.
Nếu tính funnel theo thời gian user thật sự làm, dùng occurred_at.
Nếu tính tải hệ thống collector, dùng received_at.
Đừng coi mọi timestamp là giống nhau.
---
34.26. Dedupe event
Event có thể bị gửi trùng.
Vì:
- Retry network.
- User refresh.
- Client gửi lại.
- Queue retry.
- Worker xử lý lại.
Với analytics, trùng event làm số liệu phồng lên.
Cách xử lý:
Mỗi event có event_id.
Ví dụ:
event_id = 01HX...
Pipeline có thể dedupe theo:
event_id
Hoặc theo tổ hợp:
user_id + event_name + object_id + time window
Không phải event nào cũng cần dedupe cực chặt.
Nhưng event quan trọng như:
payment_succeeded
submission_created
grading_completed
nên cẩn thận.
---
34.27. Analytics không nên làm chậm request chính
Sai lầm:
User bấm nộp bài.
Backend phải gửi analytics thành công xong mới trả response.
Nếu analytics service chậm, user nộp bài cũng chậm.
Nếu analytics service chết, nộp bài lỗi.
Đây là coupling xấu.
Tốt hơn:
Request chính xử lý nghiệp vụ.
Analytics được gửi bất đồng bộ.
Ví dụ:
Tạo submission thành công.
Commit database.
Ghi event vào outbox hoặc queue.
Trả response cho user.
Analytics không nên là điểm nghẽn của nghiệp vụ chính.
---
34.28. Nhưng đừng để mất event quan trọng
Có event analytics chỉ để tham khảo.
Ví dụ:
tooltip_hovered
Mất vài event không sao.
Nhưng có event rất quan trọng cho báo cáo chi phí hoặc compliance.
Ví dụ:
ai_api_call_completed
payment_succeeded
grading_completed
Với event quan trọng, không nên chỉ fire-and-forget từ browser.
Nên phát sinh từ backend sau khi nghiệp vụ thật xảy ra.
Ví dụ:
Gemini API call completed
-> backend lưu usage/cost
-> phát event usage_recorded
Thông điệp:
> Event càng quan trọng, càng nên được tạo từ nguồn đáng tin, thường là backend hoặc database/outbox.
---
34.29. Client-side tracking và server-side tracking
Client-side tracking:
Browser/mobile app gửi event.
Hợp cho:
- Page view.
- Click.
- UI interaction.
- Funnel trên frontend.
- A/B test exposure.
Nhược điểm:
- Có thể bị ad blocker chặn.
- User tắt mạng.
- Client time sai.
- Dễ bị giả mạo hơn.
- Không đáng tin cho số liệu tài chính/nghiệp vụ chính thức.
Server-side tracking:
Backend gửi event.
Hợp cho:
- Submission created.
- Payment succeeded.
- Grading completed.
- AI API usage.
- Permission changed.
- Export generated.
Tư duy:
Hành vi UI: client-side.
Sự thật nghiệp vụ: server-side.
---
34.30. Privacy và dữ liệu nhạy cảm
Analytics rất dễ thu quá tay.
Không nên đưa bừa vào event:
- Mật khẩu.
- Token.
- Nội dung bài làm riêng tư.
- Email nếu không cần.
- Số điện thoại nếu không cần.
- Dữ liệu học sinh nhạy cảm.
- Nội dung feedback private.
- Thông tin thanh toán nhạy cảm.
Nguyên tắc:
> Chỉ thu dữ liệu thật sự cần cho câu hỏi phân tích.
Ví dụ không tốt:
{
"event_name": "feedback_viewed",
"feedback_text": "..."
}
Tốt hơn:
{
"event_name": "feedback_viewed",
"feedback_type": "grammar",
"assignment_id": "assignment_12"
}
Analytics càng nhiều dữ liệu cá nhân, trách nhiệm bảo mật càng lớn.
---
34.31. PII là gì?
PII là thông tin có thể nhận diện cá nhân.
Ví dụ:
- Tên thật.
- Email.
- Số điện thoại.
- Địa chỉ.
- Mã học sinh.
- IP address trong một số ngữ cảnh.
- Device id.
Không phải lúc nào cũng cấm dùng PII.
Nhưng phải biết mình đang thu gì và để làm gì.
Các cách giảm rủi ro:
- Dùng internal user_id thay vì email.
- Hash hoặc pseudonymize nếu phù hợp.
- Không gửi dữ liệu nhạy cảm lên tool bên thứ ba nếu không cần.
- Có retention.
- Giới hạn ai được xem dashboard.
- Tách quyền truy cập dữ liệu raw.
Analytics không nằm ngoài security.
---
34.32. Retention cho analytics
Không phải dữ liệu analytics nào cũng cần giữ mãi.
Ví dụ:
Raw click event giữ 90 ngày.
Daily aggregate giữ 2 năm.
Billing/usage giữ theo yêu cầu kế toán.
Retention giúp:
- Giảm chi phí.
- Giảm rủi ro dữ liệu.
- Query nhanh hơn.
- Dọn dữ liệu cũ.
Một thiết kế hay:
Raw events:
giữ ngắn hơn.
Aggregated tables:
giữ dài hơn.
Ví dụ:
Raw search events giữ 180 ngày.
Monthly search summary giữ 3 năm.
Không nên để analytics data tăng vô hạn mà không ai chịu trách nhiệm.
---
34.33. Aggregation là gì?
Aggregation là tổng hợp dữ liệu thô thành số liệu.
Raw events:
grading_completed job_1 duration=80
grading_completed job_2 duration=120
grading_completed job_3 duration=100
Aggregate:
date: 2026-05-12
course_id: course_3
grading_count: 3
avg_duration_seconds: 100
Dashboard thường không nên quét raw event khổng lồ mỗi lần mở trang.
Thay vào đó, có bảng tổng hợp:
daily_course_grading_stats
daily_ai_usage_stats
daily_submission_funnel
Aggregation giúp dashboard nhanh và rẻ hơn.
---
34.34. BI tool là gì?
BI tool là công cụ để xem dashboard, làm báo cáo, phân tích dữ liệu.
Ví dụ:
- Metabase.
- Superset.
- Looker.
- Tableau.
- Power BI.
- Redash.
BI tool thường đọc từ:
- Data warehouse.
- Database replica.
- Analytics database.
Không nên để người dùng BI chạy query nặng trực tiếp trên database production nếu query đó có thể làm ảnh hưởng hệ thống.
BI rất hữu ích, nhưng phải có ranh giới.
---
34.35. Dashboard vận hành và dashboard sản phẩm
Dashboard vận hành trả lời:
Hệ thống có đang khỏe không?
Ví dụ:
- Queue backlog.
- Error rate.
- Latency.
- Worker throughput.
- API timeout.
- Cost per hour.
Dashboard sản phẩm trả lời:
Người dùng đang dùng sản phẩm thế nào?
Ví dụ:
- Active users.
- Funnel nộp bài.
- Feedback view rate.
- Search keywords.
- Feature adoption.
- Course completion.
Hai loại dashboard có thể dùng dữ liệu khác nhau.
Đừng gom tất cả dưới chữ "analytics" rồi mất rõ ràng.
---
34.36. AI Judge cần analytics gì?
Một AI Judge thực tế có thể cần theo dõi:
Sản phẩm:
- Bao nhiêu học sinh mở assignment.
- Bao nhiêu học sinh nộp bài.
- Bao nhiêu người xem feedback.
- Feedback type nào được xem nhiều.
- Assignment nào có tỉ lệ bỏ dở cao.
Vận hành:
- Số job pending.
- Thời gian chờ trong queue.
- Thời gian gọi AI.
- Tỉ lệ timeout.
- Tỉ lệ retry.
- Tỉ lệ chấm lỗi.
Chi phí:
- Token usage.
- Cost theo model.
- Cost theo course.
- Cost theo assignment.
- Cost theo ngày.
Chất lượng:
- Tỉ lệ teacher override điểm.
- Tỉ lệ học sinh yêu cầu chấm lại.
- Rubric nào hay gây lỗi.
- Prompt version nào cho kết quả ổn hơn.
Những số này giúp cải thiện hệ thống thật.
Không phải để trang trí dashboard.
---
34.37. Ví dụ event cho AI Judge
Một số event client-side:
assignment_viewed
submission_upload_clicked
submission_upload_started
submission_upload_completed
feedback_viewed
rubric_panel_opened
report_download_clicked
Một số event server-side:
submission_created
grading_job_created
grading_started
ai_api_call_completed
grading_completed
grading_failed
teacher_score_overridden
regrade_requested
Một số metric vận hành:
queue_wait_seconds
grading_duration_seconds
ai_api_latency_seconds
ai_api_timeout_count
worker_active_count
job_retry_count
Nhìn vào đây ta thấy:
Analytics không chỉ là "click tracking".
Nó là cách hệ thống kể lại chuyện đã xảy ra bằng dữ liệu.
---
34.38. Event property nên vừa đủ
Ví dụ event:
grading_completed
Property hữu ích:
grading_job_id
submission_id
assignment_id
course_id
model
duration_seconds
input_tokens
output_tokens
cost_usd
retry_count
prompt_version
Không nên nhét:
toàn bộ bài làm
toàn bộ feedback text
toàn bộ prompt nếu chứa dữ liệu private
Event nên đủ để phân tích.
Nhưng không nên trở thành bản sao dữ liệu nhạy cảm.
---
34.39. Analytics và A/B testing
A/B testing là thử nhiều phiên bản để xem phiên bản nào tốt hơn.
Ví dụ:
Phiên bản A: nút "Nộp bài"
Phiên bản B: nút "Nộp và chấm ngay"
Muốn đo đúng, event cần ghi:
experiment_name
variant
user_id
event_name
Ví dụ:
assignment_submit_button_test
variant=B
submission_completed=true
Nếu không ghi user thuộc variant nào, sau này không biết kết quả đến từ phiên bản nào.
A/B testing không phải bắt buộc.
Nhưng khi sản phẩm lớn hơn, analytics là nền tảng để thử nghiệm có số liệu.
---
34.40. Analytics và cost control
Với AI product, analytics chi phí rất quan trọng.
Không chỉ hỏi:
Tháng này tốn bao nhiêu?
Mà cần hỏi:
- Tính năng nào tốn nhiều nhất?
- Course nào tốn nhiều nhất?
- Assignment nào có cost bất thường?
- Model nào đắt nhưng không cải thiện chất lượng?
- Retry có làm chi phí tăng không?
- Prompt version nào làm token tăng?
Ví dụ event/record:
ai_api_call_completed
model
input_tokens
output_tokens
latency_ms
cost_usd
assignment_id
course_id
prompt_version
Dữ liệu này có thể vừa phục vụ:
- Billing nội bộ.
- Cost dashboard.
- Alert bất thường.
- Tối ưu prompt/model.
Với AI hệ thống, không đo usage/cost là rất nguy hiểm.
---
34.41. Sampling là gì?
Sampling là chỉ ghi một phần event.
Ví dụ:
Ghi 10% page_view.
Ghi 100% payment_succeeded.
Sampling giúp giảm:
- Dung lượng.
- Chi phí.
- Tải pipeline.
Nhưng không nên sampling bừa.
Event quan trọng nên ghi đủ:
- Payment.
- Submission.
- Grading.
- AI usage.
- Error.
Event rất nhiều và ít quan trọng có thể sampling:
- Mouse move.
- Scroll.
- Hover.
- Page view traffic cực lớn.
Nếu dùng sampling, dashboard phải biết dữ liệu đã được sample để tính đúng.
---
34.42. Backfill là gì?
Backfill là tính lại dữ liệu quá khứ.
Ví dụ:
Bạn phát hiện công thức tính chi phí AI sai.
Bạn muốn tính lại 3 tháng trước.
Nếu còn raw data:
Đọc lại raw ai_api_call_completed events
-> tính lại cost
-> cập nhật bảng aggregate
Nếu không còn raw data, có thể không sửa được.
Backfill là lý do nhiều hệ thống giữ raw event một thời gian.
Không phải giữ mãi.
Nhưng đủ lâu để sửa lỗi phân tích.
---
34.43. Data quality
Analytics sai còn nguy hiểm hơn không có analytics.
Vì nó khiến ta tự tin vào quyết định sai.
Các lỗi data quality thường gặp:
- Event bị thiếu.
- Event bị trùng.
- Tên event đổi lung tung.
- Field lúc có lúc không.
- Timestamp sai timezone.
- Client gửi dữ liệu giả.
- Bot traffic làm lệch số.
- Internal user/test data lẫn vào production.
- Dashboard query sai.
Cần có kiểm tra:
- Event schema validation.
- Monitoring event volume.
- Alert khi event giảm đột ngột.
- Tách internal/test traffic.
- Document event meaning.
- Review dashboard quan trọng.
Dashboard đẹp không có nghĩa là số đúng.
---
34.44. Timezone
Timezone là nguồn lỗi rất phổ biến.
Nên lưu timestamp chuẩn, thường là UTC.
Khi hiển thị dashboard, chuyển sang timezone phù hợp.
Ví dụ:
stored_at: UTC
dashboard timezone: Asia/Ho_Chi_Minh
Nếu không cẩn thận, báo cáo theo ngày có thể lệch.
Ví dụ:
Một event lúc 23:30 UTC
có thể là 06:30 sáng hôm sau ở Việt Nam.
Khi tính số liệu theo ngày cho người dùng Việt Nam, phải dùng đúng timezone kinh doanh.
---
34.45. Analytics trong microservices
Trong microservices, mỗi service có dữ liệu riêng.
Ví dụ:
User Service
Course Service
Submission Service
Grading Service
Billing Service
Muốn làm báo cáo tổng hợp:
Chi phí AI theo course theo tháng
có thể cần dữ liệu từ:
- Course.
- Submission.
- Grading.
- AI usage.
- Billing.
Không nên để dashboard query trực tiếp xuyên qua database của nhiều service.
Thường có pipeline đưa dữ liệu cần phân tích về warehouse.
Warehouse là nơi join và phân tích.
Service database là nơi vận hành nghiệp vụ.
---
34.46. CDC trong analytics
CDC là Change Data Capture.
Nó đọc thay đổi từ database và đưa sang nơi khác.
Ví dụ:
orders table changed
-> CDC stream
-> warehouse
CDC hữu ích khi muốn đồng bộ dữ liệu vận hành sang analytics mà không sửa quá nhiều code.
Ví dụ:
Submission inserted
GradingResult updated
Payment succeeded
CDC có thể đưa các thay đổi đó sang warehouse.
Nhưng CDC không thay thế mọi analytics event.
Vì có hành vi không nằm trong database:
- User hover.
- User view page.
- User click button nhưng không submit.
- Search không có kết quả.
- Upload started nhưng không completed.
Vì vậy thường có cả:
CDC cho dữ liệu nghiệp vụ.
Event tracking cho hành vi.
---
34.47. Không phải số nào cũng đáng đo
Một lỗi khác là đo quá nhiều.
Dashboard đầy số nhưng không ai dùng.
Trước khi thêm event, hỏi:
Số này giúp quyết định gì?
Nếu nó tăng/giảm, ta sẽ làm gì?
Ai xem số này?
Bao lâu xem một lần?
Nếu không trả lời được, có thể chưa cần đo.
Analytics tốt không phải là thu hết.
Analytics tốt là thu đúng thứ giúp hiểu và hành động.
---
34.48. Một lộ trình thực dụng
Giai đoạn 1: rất nhỏ.
Ghi vài business event quan trọng.
Dashboard đơn giản.
Có retention.
Giai đoạn 2: bắt đầu có traffic.
Tách analytics table hoặc database riêng.
Gửi event async.
Có schema rõ hơn.
Có aggregate hằng ngày.
Giai đoạn 3: event nhiều.
Collector/queue/stream.
Raw storage.
Warehouse.
BI tool.
Monitoring pipeline.
Giai đoạn 4: dữ liệu trở thành năng lực chính.
Data contracts.
Data quality checks.
Experimentation.
Cost analytics.
Near real-time analytics nếu cần.
Đi từng bước.
Đừng dựng kiến trúc data lớn khi chưa có câu hỏi lớn.
---
34.49. Bảng chọn nhanh
| Tình huống | Cách làm thường hợp | |---|---| | App nhỏ, ít event | Ghi event đơn giản vào DB hoặc analytics SaaS | | Dashboard làm chậm DB chính | Tách analytics DB/read replica/warehouse | | Cần báo cáo hằng ngày | Batch job + aggregate table | | Cần dashboard gần real-time | Queue/stream + processing nhanh | | Cần phân tích nhiều nguồn dữ liệu | Data warehouse | | Cần lưu raw event rẻ, xử lý lại sau | Data lake/object storage | | Cần đo UI click/page view | Client-side tracking | | Cần đo nghiệp vụ quan trọng | Server-side event/outbox | | Event quá nhiều nhưng không quá quan trọng | Sampling | | AI cost control | Server-side usage event có token/cost/model | | Microservices cần báo cáo chung | Đưa dữ liệu sang warehouse, không query chéo production DB |
---
34.50. Tóm tắt bằng AI Judge
Trong AI Judge, dữ liệu vận hành là:
User
Course
Assignment
Submission
GradingJob
GradingResult
Permission
Dữ liệu này nằm trong database chính và phải đúng.
Dữ liệu analytics là:
assignment_viewed
submission_upload_started
submission_upload_completed
grading_completed
feedback_viewed
ai_api_call_completed
teacher_score_overridden
Dữ liệu này giúp trả lời:
- Học sinh bỏ dở ở bước nào?
- Chấm bài mất bao lâu?
- Course nào tốn nhiều chi phí AI?
- Prompt/model nào hay lỗi?
- Teacher có dùng feedback không?
- Học sinh có mở feedback không?
Luồng ban đầu có thể đơn giản:
Backend ghi event quan trọng vào analytics table.
Dashboard đọc bảng aggregate.
Khi lớn hơn:
Backend/frontend gửi event
-> collector/queue
-> raw storage
-> warehouse
-> dashboard
Điểm quan trọng:
Submission/điểm/quyền vẫn lấy từ database vận hành.
Analytics chỉ giúp nhìn và phân tích.
Không dùng analytics event làm source of truth cho điểm chính thức.
---
34.51. Kết luận của chương
Analytics không phải là phần trang trí.
Nó là cách hệ thống tự kể lại:
Người dùng đang làm gì?
Hệ thống đang tốn gì?
Chỗ nào đang nghẽn?
Tính năng nào thật sự có giá trị?
Nhưng analytics cũng không nên phá hệ thống vận hành.
Nguyên tắc cốt lõi:
> Dữ liệu vận hành để chạy đúng. Dữ liệu analytics để hiểu và cải thiện. Hai loại dữ liệu này nên được thiết kế với mức độ đúng, độ trễ, chi phí và hạ tầng khác nhau.
Bắt đầu đơn giản là đúng.
Nhưng khi event tăng, dashboard nặng, hoặc cần phân tích sâu, hãy tách pipeline dữ liệu riêng:
event -> queue/stream -> storage/warehouse -> dashboard
Ở chương tiếp theo, ta sẽ nói về replication, sharding và những thứ chưa nên vội: vì sao read replica có ích, replication lag là gì, sharding đau ở đâu, và tại sao đa số hệ thống nên tối ưu database hiện tại trước khi nghĩ đến chia dữ liệu.