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

Hãy sử dụng các phương pháp hay nhất được liệt kê ở đây làm tài liệu tham khảo nhanh khi xây dựng 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 nhất với người dùng và tài nguyên điện toán. Các bước nhảy mạng có phạm vi xa dễ xảy ra lỗi hơn và làm tăng độ trễ truy vấn.

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

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

Mã tài liệu

  • Tránh mã nhận dạng tài liệu ....
  • Tránh sử dụng dấu gạch chéo lên / trong mã nhận dạng tài liệu.
  • Không sử dụng mã tài liệu tăng dần như:

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

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

Tên trường

  • Tránh sử dụng các ký tự sau trong tên trường vì các ký tự này yêu cầu thêm dấu thoát:

    • Kỳ kinh .
    • 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ỉ mục

Giảm độ trễ ghi

Nguyên nhân chính gây ra độ trễ khi ghi là sự phân tán chỉ mục. Sau đây là các phương pháp hay nhất để giảm mức độ phân tán chỉ mục:

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

  • Giảm số lượng tài liệu trong một giao dịch. Để ghi một 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 hàng loạt nguyên tử.

Miễn trừ việc lập chỉ mục

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

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

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

Tốc độ ghi cao vào một tập hợp chứa các 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 mỗi 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 trường này để bỏ qua giới hạn này.

Ví dụ: trong trường hợp sử dụng IoT có tốc độ ghi cao, một tập hợp chứa các tài liệu có trường dấu thời gian có thể đạt đến giới hạn 500 lượt ghi mỗi 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à dấu thời gian. Theo mặc định, tính năng lập chỉ mục trên các trường TTL sẽ được bật và có thể ảnh hưởng đến hiệu suất ở tốc độ lưu lượng truy cập cao hơn. Phương pháp hay nhất là thêm trường miễn trừ một trường cho các trường TTL.

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

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 bản đồ, bạn nên loại trừ trường đó khỏi việc lập chỉ mục.

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 rất nhiều vào khối lượng công việc. Để biết thêm thông tin, hãy xem phần Cập nhật 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ộ giúp giảm thiểu tác động của độ trễ. Ví dụ: hãy xem xét một ứng dụng cần kết quả tra cứu tài liệu và kết quả truy vấn trước khi hiển thị phản hồi. Nếu lượt tra cứu và truy vấn không có phần phụ thuộc dữ liệu, bạn không cần phải đồng bộ chờ cho đến khi lượt tra cứu hoàn tất trước khi bắt đầu truy vấn.

  • Không sử dụng độ dời. Thay vào đó, hãy sử dụng con trỏ. Việc sử dụng độ dời chỉ giúp tránh trả về các tài liệu đã 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ẽ bị tính phí cho các thao tác đọc cần thiết để truy xuất các tài liệu đó.

Giao dịch thử lại

SDK và thư viện ứng dụng 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 vào Cloud Firestore thông qua các API REST hoặc RPC trực tiếp thay vì thông qua SDK, thì ứng dụng của bạn nên triển khai tính năng thử lại giao dịch để 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 nội dung 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 theo tỷ lệ

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

Nội dung cập nhật cho một tài liệu

Khi thiết kế ứng dụng, hãy cân nhắc tốc độ cập nhật tài liệu của ứng dụng. 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 rất nhiều vào khối lượng công việc. Các yếu tố bao gồm tốc độ ghi, xung đột 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ẽ đồng bộ áp dụng thao tác ghi trên một số lượng đủ của 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ốc độ đọc, ghi và xoá cao đối với một phạm vi tài liệu hẹp

Tránh tốc độ đọc hoặc ghi cao để đóng tài liệu theo thứ tự bảng chữ cái, nếu không ứng dụng của bạn sẽ gặp lỗi tranh chấp. Vấn đề 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 điểm phát sóng nếu ứng dụng đó thực hiện bất kỳ thao tác 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 của riêng mình.

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

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

  • Tạo tài liệu mới có trường tăng dần, 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ốc độ cao.

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

Tránh bỏ qua 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 mục nhập chỉ mục nếu các kết quả truy vấn ban đầu gần đây đã bị xoá.

Ví dụ về một khối lượng công việc có thể phải bỏ qua nhiều dữ liệu đã xoá là khối lượng công việc cố gắng tìm các mục công việc lâu đời nhất trong hàng đợi. Truy vấn 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 khi truy vấn này chạy, truy vấn 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 cá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 một trường tăng dần đơn điệu, đây là một mẫu chống lại tốc độ ghi cao.

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

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

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

Việc tăng dầ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ừ một bộ sưu tập sang một bộ sưu tập khác. Một cách đơn giản để xử lý quá trình 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, hãy đọc từ bộ sưu tập mới. Tuy nhiên, điều này có thể làm tăng đột biến lưu lượng truy cập đến các tài liệu gần nhau theo thứ tự bảng chữ cái trong bộ sưu tập mới. Cloud Firestore có thể không thể chuẩn bị hiệu quả bộ sưu tập mới để tăng lưu lượng truy cập, đặc biệt là khi bộ sưu tập đó chứa ít tài liệu.

Sự cố 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 bộ sưu tậ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 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ả 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 của chi phí đối với các hoạt động song song trong quá trình di chuyển.

Đọc song song

Để triển khai tính năng đọ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 từ bộ sưu tập mới. Tỷ lệ đọc cao của các tài liệu không tồn tại có thể dẫn đến tình trạng điểm nóng, vì vậy, hãy nhớ tăng dần tải cho tập hợp mới. Một chiến lược tốt 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ượt đọc song song để đảm bảo rằng Cloud Firestore có thể xử lý lưu lượng truy cập đến bộ sưu tập mới.

Một chiến lược có thể áp dụng để tăng dần số lượt đọc hoặc ghi vào một tập hợp mới là 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 của người dùng đang cố gắng ghi 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 do 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 hàng loạt để 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 mã nhận dạng tài liệu tuần tự để ngăn chặn các điểm nóng. Khi công việc hàng loạt kết thúc, bạn chỉ có thể đọc từ bộ sưu tập mới.

Một cách tinh chỉnh chiến lược này là di chuyển từng nhóm nhỏ người dùng một lần. 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 lô người dùng để 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 công việc theo lô để di chuyển tài liệu cho lô người dùng đó và sử dụng tính năng đọc song song cho người dùng đang di chuyển.

Xin lưu ý rằng bạn không thể dễ dàng quay lại trừ phi bạn thực hiện ghi kép cho cả thực thể cũ và mới trong giai đoạn di chuyển. Điều này sẽ làm tăng chi phí 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 Google Cloud. Mã dự án trên Google Cloud có thể được giữ lại sau khi dự án của bạn kết thúc.
  • Để tuân thủ các 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 tài liệu.

Ngăn chặn hành vi truy cập trái phép

Ngăn chặn các thao tác trái phép trên cơ sở dữ liệu bằng Cloud Firestore Security Rules. Ví dụ: việc sử dụng quy tắc có thể tránh được trường hợp một người dùng độc hại tải toàn bộ cơ sở dữ liệu của bạn xuống nhiều lần.

Tìm hiểu thêm về cách sử dụng Cloud Firestore Security Rules.