Các phương pháp hay nhất cho Cloud Firestore

Hãy tham khảo nhanh các phương pháp hay nhất được liệt kê tại đây khi tạo một ứng dụng sử dụng Cloud Firestore.

Vị trí cơ sở dữ liệu

Khi bạn tạo thực thể cơ sở dữ liệu, hãy chọn vị trí cơ sở dữ liệu gần người dùng nhất của bạn và tài nguyên điện toán. Bước mạng sâu rộng dễ gặp lỗi hơn và làm tăng độ trễ truy vấn.

Để tối đa hoá khả năng cung cấp và độ bền vững của ứng dụng, hãy chọn một vị trí trên nhiều vùng và đặt các tài nguyên điện toán quan trọng ở ít nhất 2 khu vực.

Hãy chọn một địa điểm theo khu vực để có chi phí thấp hơn, để giảm độ trễ ghi nếu ứng dụng của bạn nhạy cảm với độ trễ, hoặc để cùng bố trí với các tài nguyên khác trên GCP.

Mã tài liệu

  • Tránh dùng các mã nhận dạng tài liệu ....
  • Tránh sử dụng / dấu gạch chéo lên trong mã tài liệu.
  • Bạn không được dùng mã nhận dạng tài liệu tăng đơn điệu, chẳng hạn như:

    • Customer1, Customer2, Customer3, ...
    • Product 1, Product 2, Product 3, ...

    Mã tuần tự như vậy có thể dẫn đến các điểm nóng ảnh hưởng đến độ trễ.

Tên trường

  • Tránh các ký tự sau trong tên trường vì các ký tự này yêu cầu thoát bổ sung:

    • Hiệp .
    • [ dấu ngoặc đơn trái
    • ] dấu ngoặc đơn phải
    • Dấu hoa thị *
    • ` dấu phẩy ngược

Chỉ số

Giảm độ trễ ghi

Yếu tố chính góp phần tạo ra độ trễ khi viết là lập chỉ mục fanout. Các phương pháp hay nhất để giảm tình trạng rời bỏ chỉ mục là:

  • Thiết lập trường hợp miễn trừ chỉ mục ở cấp bộ sưu tập. Một chế độ mặc định dễ dàng là tắt tính năng Lập chỉ mục giảm dần và mảng. Việc xoá những giá trị được lập chỉ mục không dùng đến cũng sẽ giúp giảm chi phí lưu trữ.

  • Giảm số lượng chứng từ trong một giao dịch. Để viết một số lượng lớn tài liệu, hãy cân nhắc sử dụng trình ghi hàng loạt thay vì trình ghi lô nguyên tử.

Trường hợp miễn trừ chỉ mục

Đối với hầu hết ứng dụng, bạn có thể dựa vào tính năng tự động lập chỉ mục cũng như mọi đường liên kết thông báo lỗi để quản lý chỉ mục của mình. Tuy nhiên, bạn nên thêm trường hợp miễn trừ một trường trong các trường hợp sau:

Cách Mô tả
Trường chuỗi lớn

Nếu bạn có một trường chuỗi thường chứa các giá trị chuỗi dài mà bạn không dùng để truy vấn, thì bạn có thể cắt giảm chi phí lưu trữ bằng cách miễn lập chỉ mục trường này.

Tốc độ ghi cao vào bộ sưu tập chứa tài liệu có giá trị tuần tự

Nếu bạn lập chỉ mục một trường tăng hoặc giảm tuần tự giữa các tài liệu trong một tập hợp (chẳng hạn như dấu thời gian), thì tốc độ ghi tối đa vào tập hợp đó là 500 lượt ghi/giây. Nếu không truy vấn dựa trên trường có giá trị tuần tự, bạn có thể miễn lập chỉ mục cho trường này để bỏ qua giới hạn này.

Trong một trường hợp sử dụng IoT có tốc độ ghi cao, chẳng hạn như một tập hợp chứa tài liệu có trường dấu thời gian có thể đạt tới giới hạn 500 lần ghi/giây.

Trường TTL

Nếu bạn sử dụng chính sách TTL (thời gian tồn tại), hãy lưu ý rằng trường TTL phải là một dấu thời gian. Tính năng lập chỉ mục trên các trường TTL được bật theo mặc định và có thể ảnh hưởng đến hiệu suất ở tỷ lệ lưu lượng truy cập cao hơn. Tốt nhất là bạn nên thêm các trường hợp miễn trừ một trường cho các trường TTL.

Các trường lớn liên quan đến bản đồ hoặc mảng

Các trường mảng hoặc bản đồ lớn có thể đạt đến giới hạn 40.000 mục nhập chỉ mục trên mỗi tài liệu. Nếu không truy vấn dựa trên một mảng lớn hoặc trường ánh xạ, bạn không nên lập chỉ mục mảng hoặc trường đó.

Thao tác đọc và ghi

  • Tốc độ tối đa chính xác mà một ứng dụng có thể cập nhật một tài liệu phụ thuộc nhiều vào khối lượng công việc. Để biết thêm thông tin, hãy xem bài viết Cập nhật cho một tài liệu.

  • Sử dụng lệnh gọi không đồng bộ (nếu có) thay vì lệnh gọi đồng bộ. Lệnh gọi không đồng bộ sẽ giảm thiểu tác động đến độ trễ. Ví dụ: hãy xem xét một ứng dụng cần kết quả của quá trình tra cứu tài liệu và kết quả của truy vấn trước khi hiển thị phản hồi. Nếu quá trình tra cứu và truy vấn không có phần phụ thuộc dữ liệu, thì bạn không cần đợi một cách đồng bộ cho đến khi quá trình tra cứu hoàn tất trước khi bắt đầu truy vấn.

  • Không sử dụng giá trị bù trừ. Thay vào đó, hãy sử dụng con trỏ. Việc sử dụng giá trị bù trừ sẽ giúp tránh trả về các tài liệu bị bỏ qua cho ứng dụng, nhưng các tài liệu này vẫn được truy xuất nội bộ. Các tài liệu bị bỏ qua ảnh hưởng đến độ trễ của truy vấn và ứng dụng của bạn sẽ được tính phí cho các thao tác đọc cần thiết để truy xuất các tài liệu đó.

Thử lại giao dịch

Các SDK và thư viện ứng dụng của Cloud Firestore sẽ tự động thử lại các giao dịch không thành công để xử lý các lỗi tạm thời. Nếu ứng dụng của bạn truy cập trực tiếp vào Cloud Firestore thông qua API REST hoặc RPC thay vì thông qua SDK, thì ứng dụng của bạn nên triển khai các lần thử giao dịch lại để tăng độ tin cậy.

Thông tin cập nhật theo thời gian thực

Để biết các phương pháp hay nhất liên quan đến thông tin cập nhật theo thời gian thực, hãy xem bài viết Tìm hiểu về truy vấn theo thời gian thực trên quy mô lớn.

Thiết kế để điều chỉnh quy mô

Các phương pháp hay nhất sau đây mô tả cách tránh những tình huống gây ra vấn đề tranh chấp.

Cập nhật một tài liệu

Khi bạn thiết kế ứng dụng, hãy cân nhắc tốc độ mà ứng dụng cập nhật từng tài liệu. Cách tốt nhất để mô tả hiệu suất của khối lượng công việc là kiểm thử tải. Tốc độ tối đa chính xác mà một ứng dụng có thể cập nhật một tài liệu phụ thuộc nhiều vào khối lượng công việc. Các yếu tố bao gồm tốc độ ghi, tranh chấp giữa các yêu cầu và số lượng chỉ mục bị ảnh hưởng.

Thao tác ghi tài liệu sẽ cập nhật tài liệu và mọi chỉ mục liên quan, đồng thời Cloud Firestore sẽ áp dụng đồng bộ thao tác ghi trên một tập hợp các bản sao. Ở tốc độ ghi đủ cao, cơ sở dữ liệu sẽ bắt đầu gặp phải tình trạng tranh chấp, độ trễ cao hơn hoặc các lỗi khác.

Tỷ lệ đọc, ghi và xoá cao đối với một phạm vi tài liệu hẹp

Tránh việc đóng tài liệu về mặt từ ngữ có tỷ lệ đọc hoặc ghi cao, nếu không ứng dụng của bạn sẽ gặp phải lỗi tranh chấp. Sự cố này được gọi là điểm phát sóng và ứng dụng của bạn có thể gặp phải sự cố điểm phát sóng nếu thực hiện bất kỳ điều nào sau đây:

  • Tạo tài liệu mới với tốc độ rất cao và phân bổ mã nhận dạng tăng dần đơn điệu.

    Cloud Firestore phân bổ mã tài liệu bằng thuật toán tán xạ. Bạn sẽ không gặp phải điểm tương tác trong quá trình ghi nếu tạo tài liệu mới bằng mã nhận dạng tài liệu tự động.

  • Tạo tài liệu mới với tốc độ cao trong một bộ sưu tập có ít tài liệu.

  • Tạo tài liệu mới bằng trường tăng đơn điệu (chẳng hạn như dấu thời gian) với tốc độ rất cao.

  • Xoá tài liệu trong một bộ sưu tập với tần suất cao.

  • Ghi vào cơ sở dữ liệu với tốc độ rất cao mà không cần tăng dần lưu lượng truy cập.

Tránh bỏ qua phần dữ liệu đã xoá

Tránh các truy vấn bỏ qua dữ liệu đã xoá gần đây. Một truy vấn có thể phải bỏ qua một số lượng lớn các mục nhập chỉ mục nếu kết quả truy vấn ban đầu đã bị xoá gần đây.

Ví dụ về khối lượng công việc có thể phải bỏ qua nhiều dữ liệu đã xoá: cố gắng tìm các mục công việc cũ nhất trong hàng đợi. Cụm từ tìm kiếm có thể có dạng như sau:

docs = db.collection('WorkItems').order_by('created').limit(100)
delete_batch = db.batch()
for doc in docs.stream():
  finish_work(doc)
  delete_batch.delete(doc.reference)
delete_batch.commit()

Mỗi lần truy vấn này chạy, truy vấn này sẽ quét qua các mục nhập chỉ mục cho trường created trên mọi tài liệu đã xoá gần đây. Điều này làm chậm tốc độ truy vấn.

Để cải thiện hiệu suất, hãy sử dụng phương thức start_at để tìm vị trí tốt nhất để bắt đầu. Ví dụ:

completed_items = db.collection('CompletionStats').document('all stats').get()
docs = db.collection('WorkItems').start_at(
    {'created': completed_items.get('last_completed')}).order_by(
        'created').limit(100)
delete_batch = db.batch()
last_completed = None
for doc in docs.stream():
  finish_work(doc)
  delete_batch.delete(doc.reference)
  last_completed = doc.get('created')

if last_completed:
  delete_batch.update(completed_items.reference,
                      {'last_completed': last_completed})
  delete_batch.commit()

LƯU Ý: Ví dụ ở trên sử dụng trường tăng đơn điệu. Đây là trường hợp chống mẫu cho tốc độ ghi cao.

Tăng lưu lượng truy cập

Bạn nên từng bước tăng cường lưu lượng truy cập vào các bộ sưu tập mới hoặc các tài liệu ký tự chính tả để Cloud Firestore có đủ thời gian chuẩn bị tài liệu cho lưu lượng truy cập tăng. Bạn nên bắt đầu với tối đa 500 thao tác mỗi giây cho một bộ sưu tập mới, sau đó tăng lưu lượng truy cập lên 50% mỗi 5 phút. Tương tự, bạn cũng có thể tăng lưu lượng truy cập ghi, nhưng hãy lưu ý đến Giới hạn thông thường của Cloud Firestore. Hãy đảm bảo rằng các thao tác được phân phối tương đối đồng đều trong suốt phạm vi khoá. Đây được gọi là quy tắc "500/50/5".

Di chuyển lưu lượng truy cập sang một tập hợp mới

Việc tăng dần mức độ ưu tiên là đặc biệt quan trọng nếu bạn di chuyển lưu lượng truy cập ứng dụng từ bộ sưu tập này sang bộ sưu tập khác. Một cách đơn giản để xử lý việc di chuyển này là đọc từ bộ sưu tập cũ và nếu tài liệu không tồn tại, thì đọc từ bộ sưu tập mới. Tuy nhiên, điều này có thể làm tăng đột ngột lưu lượng truy cập để đóng các tài liệu theo từ điển trong bộ sưu tập mới. Cloud Firestore có thể không chuẩn bị được tập hợp mới một cách hiệu quả cho việc tăng lưu lượng truy cập, đặc biệt là khi tập hợp này chứa ít tài liệu.

Vấn đề tương tự có thể xảy ra nếu bạn thay đổi mã nhận dạng tài liệu của nhiều tài liệu trong cùng một bộ sưu tập.

Chiến lược tốt nhất để di chuyển lưu lượng truy cập sang một tập hợp mới phụ thuộc vào mô hình dữ liệu của bạn. Dưới đây là một chiến lược mẫu, còn gọi là đọc song song. Bạn sẽ cần xác định xem chiến lược này có hiệu quả đối với dữ liệu của mình hay không, và một yếu tố quan trọng cần cân nhắc là tác động đến chi phí của các hoạt động song song trong quá trình di chuyển.

Đọc song song

Để triển khai các lượt đọc song song khi bạn di chuyển lưu lượng truy cập sang một bộ sưu tập mới, trước tiên, hãy đọc từ bộ sưu tập cũ. Nếu tài liệu bị thiếu, hãy đọc trong bộ sưu tập mới. Việc các tài liệu không tồn tại với tần suất cao có thể gây ra điểm nóng, vì vậy hãy nhớ tăng dần mức tải cho bộ sưu tập mới. Chiến lược hay hơn là sao chép tài liệu cũ vào bộ sưu tập mới rồi xoá tài liệu cũ. Tăng dần số lượng đọc song song để đảm bảo rằng Cloud Firestore có thể xử lý lưu lượng truy cập vào tập hợp mới.

Để dần dần tăng tốc độ đọc hoặc ghi vào một bộ sưu tập mới, bạn có thể sử dụng hàm băm xác định của mã nhận dạng người dùng để chọn một tỷ lệ phần trăm ngẫu nhiên những người dùng cố gắng viết tài liệu mới. Hãy đảm bảo rằng kết quả của hàm băm mã nhận dạng người dùng không bị sai lệch bởi hàm của bạn hoặc hành vi của người dùng.

Trong khi đó, hãy chạy một công việc theo lô để sao chép tất cả dữ liệu của bạn từ các tài liệu cũ sang bộ sưu tập mới. Công việc hàng loạt của bạn nên tránh ghi vào các mã nhận dạng tài liệu tuần tự để ngăn chặn các điểm phát sóng. Khi tác vụ hàng loạt kết thúc, bạn chỉ có thể đọc từ tập hợp mới.

Việc tinh chỉnh chiến lược này nhằm di chuyển một nhóm nhỏ người dùng cùng một lúc. Thêm một trường vào tài liệu người dùng để theo dõi trạng thái di chuyển của người dùng đó. Chọn một loạt người dùng cần di chuyển dựa trên hàm băm của mã nhận dạng người dùng. Sử dụng một công việc theo lô để di chuyển tài liệu cho lô người dùng đó, đồng thời sử dụng tính năng đọc song song cho người dùng ở giữa quá trình di chuyển.

Xin lưu ý rằng bạn không thể dễ dàng khôi phục trừ phi bạn ghi kép cả thực thể cũ và thực thể mới trong giai đoạn di chuyển. Điều này sẽ làm tăng chi phí phát sinh của Cloud Firestore.

Quyền riêng tư

  • Tránh lưu trữ thông tin nhạy cảm trong mã dự án trên đám mây. Mã dự án trên đám mây có thể được giữ lại sau khi dự án của bạn kết thúc.
  • Để tuân thủ quy định về dữ liệu, bạn không nên lưu trữ thông tin nhạy cảm trong tên tài liệu và tên trường của tài liệu.

Ngăn chặn truy cập trái phép

Ngăn chặn các hoạt động trái phép trên cơ sở dữ liệu của bạn bằng Quy tắc bảo mật của Cloud Firestore. Ví dụ: việc sử dụng các quy tắc có thể tránh được trường hợp người dùng có ý đồ xấu liên tục tải toàn bộ cơ sở dữ liệu của bạn xuống.

Tìm hiểu thêm về cách sử dụng Quy tắc bảo mật của Cloud Firestore.