FDE PulseViệc làm FDE đang mở 316Mới đăng 7 ngày qua 10Chủ đề nổi bật: Đào tạo kỹ năng FDE tại Đông Nam Á

Tờ báo của nghề Forward Deployed Engineer

Bách khoa

Lần đầu vào database của khách hàng: đọc schema, truy vấn trên bản sao và khoá phiên chỉ đọc

Trước khi gõ truy vấn đầu tiên ở khách hàng, hãy tìm một bản sao để đọc; nếu buộc phải dùng primary, hãy khoá phiên ở chế độ chỉ đọc và đặt thời hạn cho mọi câu lệnh.

Đồ hoạNăm bước để truy vấn database của khách an toàn
  1. 1Chọn bản saoKết nối vào hot standby của PostgreSQL hoặc đổi read preference MongoDB sang secondary
  2. 2Khoá phiênBật read-only cùng statement_timeout, lock_timeout và idle_in_transaction_session_timeout
  3. 3Đọc schema SQLBắt đầu từ information_schema, xuống pg_catalog khi cần tính năng riêng của PostgreSQL
  4. 4Lấy mẫu NoSQLDùng $sample rồi đếm số lần mỗi field xuất hiện để thấy cấu trúc thật
  5. 5Ghi rõ nguồn số liệuNói rõ số đọc từ bản sao nào và vào lúc nào, vì dữ liệu trên đó có thể đã cũ

Phải chọn đúng nơi truy vấn và khoá phiên làm việc trước, rồi mới bắt đầu đọc schema.

Đồ hoạ: FDE Times

Tóm tắt nhanh

  • Hãy xin quyền vào hot standby của PostgreSQL hoặc secondary của MongoDB trước khi nghĩ tới primary.
  • Bật read-only cùng ba loại timeout ngay đầu phiên: read-only chặn sửa dữ liệu, còn timeout giới hạn thời gian truy vấn chiếm CPU, I/O và khoá.
  • Schema của NoSQL không nằm trong tài liệu nào cả, bạn phải lấy mẫu document để biết cấu trúc thật.
Chia sẻLinkedInFacebookX

Sáng thứ hai ở văn phòng khách hàng. Đội IT đưa bạn một connection string kèm lời dặn: “Database đây, anh cứ xem thoải mái”. Bạn mở DBeaver, thấy hơn 200 bảng không có tài liệu, và việc đầu tiên bạn muốn làm là SELECT COUNT(*) trên bảng lớn nhất.

Bạn nên dừng tay ở đây. Nếu connection string trỏ vào primary, câu lệnh vô hại đó vẫn chạy chung tài nguyên với đơn hàng thật của khách. Lời “cứ xem thoải mái” là phép lịch sự của đội IT, còn hệ thống của họ thì không vì thế mà chịu tải tốt hơn.

Ở một khách hàng mới, bạn cần hiểu dữ liệu của họ thật nhanh nhưng không được làm hỏng thứ gì. Bài này hướng dẫn một quy trình bạn dùng được ngay ngày mai: chọn đúng nơi để truy vấn, khoá phiên làm việc, đọc schema của PostgreSQL và của NoSQL, rồi tránh những lỗi mà người mới hay mắc.

Truy vấn ở đâu là câu hỏi đầu tiên

PostgreSQL có một chế độ gọi là hot standby. Ở chế độ này bạn kết nối được vào máy chủ bản sao và chạy truy vấn chỉ đọc trong lúc nó vẫn đang nhận dữ liệu từ primary. Đây là nơi FDE nên làm việc, và ngay từ buổi đầu bạn nên hỏi đội IT: “Bên mình có standby nào cho em kết nối không?”

Hot standby còn cho bạn một lớp bảo vệ có sẵn. Tài liệu PostgreSQL nói mọi kết nối vào standby đều chỉ đọc tuyệt đối, đến bảng tạm cũng không ghi được. Lỡ tay chạy một câu UPDATE thì câu đó bị từ chối chứ không chạm vào dữ liệu.

MongoDB thì khác. Theo mặc định, ứng dụng gửi mọi thao tác đọc tới primary của replica set, nên bạn phải tự đổi read preference sang secondary để không đè thêm tải lên production. Việc này chỉ cần một dòng, như bạn sẽ thấy trong ví dụ ở phần sau.

Khoá phiên làm việc trước khi gõ câu đầu tiên

Có những khách hàng không có standby, hoặc chỉ đưa bạn một user trên primary. Lúc đó bạn phải tự dựng hàng rào, và nên dán bốn dòng sau vào đầu mọi phiên làm việc:

SET default_transaction_read_only = on;
SET statement_timeout = '30s';
SET lock_timeout = '2s';
SET idle_in_transaction_session_timeout = '60s';

Mỗi dòng chặn một kiểu tai nạn. default_transaction_read_only mặc định là off, tức là mọi transaction đều được ghi, nên phải bật lên để transaction mới mặc định chỉ đọc. statement_timeout huỷ mọi câu lệnh chạy quá thời gian bạn đặt, nhờ vậy một phép JOIN thiếu điều kiện không thể chạy suốt buổi chiều.

Hai dòng còn lại xử lý vấn đề khoá. lock_timeout huỷ câu lệnh nếu nó chờ khoá trên bảng, index hay dòng quá lâu, để truy vấn của bạn không nằm trong hàng đợi chặn đường giao dịch thật. idle_in_transaction_session_timeout ngắt phiên nào mở transaction rồi bỏ đó, chẳng hạn khi bạn mở công cụ GUI, chạy một câu, rồi đi ăn trưa.

Tài liệu PostgreSQL còn ghi rõ READ ONLY chỉ là khái niệm chỉ đọc ở mức cao, không chặn mọi thao tác ghi xuống đĩa. Nhưng lý do chính để cần cả bốn dòng nằm ở chỗ khác: read-only không giới hạn một truy vấn được chiếm CPU, I/O hay chờ khoá trong bao lâu. Ba dòng timeout mới đặt ra giới hạn đó.

Ví dụ: đọc schema của một công ty giao hàng

Thử hình dung khách hàng là một công ty giao hàng. Đơn hàng nằm trong PostgreSQL, còn log sự kiện của tài xế nằm trong MongoDB. Bạn được nhờ tìm hiểu vì sao báo cáo tỉ lệ giao trễ không khớp giữa hai phòng ban.

Với PostgreSQL, bạn bắt đầu từ information_schema. Đây là tập view theo chuẩn SQL nên câu truy vấn quen thuộc với bất kỳ ai từng làm việc với RDBMS:

SELECT table_name, column_name, data_type, is_nullable
FROM information_schema.columns
WHERE table_schema = 'public'
ORDER BY table_name, ordinal_position;

Xuất kết quả ra file rồi đọc từng cột theo tên. Trong ví dụ này, cặp orders.driver_id và drivers.id đã gợi ra quan hệ giữa hai bảng dù không có foreign key. Có một giới hạn: information_schema không chứa những tính năng riêng của PostgreSQL, muốn tìm hiểu chúng bạn phải truy vấn system catalogs trong pg_catalog.

MongoDB thì không có bảng nào để liệt kê. Schema của NoSQL linh hoạt, mỗi document có thể chứa kiểu dữ liệu khác nhau, vì vậy cấu trúc thật chỉ hiện ra khi bạn lấy mẫu:

db.getMongo().setReadPref("secondaryPreferred")
db.driver_events.aggregate([
  { $sample: { size: 1000 } },
  { $project: { kv: { $objectToArray: "$$ROOT" } } },
  { $unwind: "$kv" },
  { $group: { _id: "$kv.k", n: { $sum: 1 } } },
  { $sort: { n: -1 } }
])

Giả sử kết quả cho thấy delivered_at có trong 1.000 document, còn delivered_ts chỉ có trong 300. Nhiều khả năng ứng dụng đã đổi tên field ở một phiên bản nào đó, và hai phòng ban đang đọc hai field khác nhau. Đó là giả thuyết đầu tiên bạn mang đến cuộc họp, kèm con số cụ thể để mọi người kiểm tra lại.

Cái giá của việc đọc trên bản sao

Bản sao an toàn hơn primary nhưng vẫn có những giới hạn riêng. Trên hot standby, một truy vấn dài có thể xung đột với thay đổi mà standby đang replay từ primary, chẳng hạn một lệnh DROP TABLE. Khi thời gian chờ vượt quá max_standby_streaming_delay hoặc max_standby_archive_delay, PostgreSQL sẽ huỷ truy vấn của bạn.

Gặp lỗi đó thì đừng nhờ DBA tăng tham số. Hãy chia truy vấn nhỏ lại, chẳng hạn chạy theo từng tuần thay vì cả năm. Truy vấn ngắn ít bị huỷ hơn, và nếu bị huỷ thì bạn cũng mất ít công hơn.

Với MongoDB, mọi read preference trừ primary đều có thể trả về dữ liệu cũ, vì secondary sao chép từ primary theo cơ chế bất đồng bộ. Bạn có thể đặt maxStalenessSeconds để giới hạn độ trễ chấp nhận được.

Nói rộng hơn, đa số NoSQL chỉ đảm bảo eventual consistency, nên khi báo con số cho khách, hãy ghi rõ số đó được đọc từ đâu và vào lúc nào.

Những lỗi khiến FDE mất lòng tin

Lỗi phổ biến nhất là tin vào connection string mà không kiểm tra. Hãy chạy SELECT pg_is_in_recovery(); để biết mình đang ở standby hay primary, mất có hai giây.

Kế đến là kết luận về schema NoSQL chỉ từ vài document mở bằng find(). Vì mỗi document có thể mang cấu trúc khác nhau, hãy dùng $sample hoặc sắp xếp theo _id để nhìn thấy cả document cũ lẫn mới trước khi kết luận.

Một lỗi khác là dùng số liệu đọc từ secondary trong một cuộc họp cần số liệu thời gian thực mà không nói trước. Khi khách phát hiện con số lệch, họ dễ nghi ngờ cả những phân tích khác của bạn. Còn chuyện để transaction treo trong công cụ GUI thì idle_in_transaction_session_timeout sẽ tự xử lý giúp bạn, miễn là bạn đã cài nó.

Biến kỹ năng này thành điểm cộng khi đi phỏng vấn

Khi đọc JD của một vị trí FDE, hãy để ý những cụm như “work directly with customer data” hay “integrate with existing systems”. Đó là dấu hiệu tuần đầu tiên của bạn sẽ trông giống như cảnh mở đầu bài này.

Trong CV, đừng chỉ ghi “thành thạo SQL”. Hãy viết rằng bạn đã xây một quy trình truy cập chỉ đọc gồm phiên có timeout, truy vấn trên replica và lấy mẫu schema NoSQL. Một dòng như vậy cho thấy cụ thể bạn đã làm gì với dữ liệu thật, điều mà “thành thạo SQL” không nói được.

Khách hàng có thể quên bạn đã viết bao nhiêu truy vấn hay. Nhưng nếu bạn từng làm chậm hệ thống đặt hàng của họ dù chỉ một lần, họ sẽ nhớ chuyện đó rất lâu.

7 nguồn
Đọc tiếp trên lộ trình · Chặng 2: Kỹ thuật rộngĐọc codebase Java, Go hay Node.js của khách khi bạn chỉ quen PythonTrước buổi review tích hợp, bạn chưa cần học thêm ngôn ngữ mới. Bạn cần biết mở ba file nào trước, rồi lần theo một request cho tới tận database.