Firebase 将于 5 月 10 日重返 Google I/O 大会!立即报名

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

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 ứng dụng sử dụng Cloud Firestore.

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

Khi bạn tạo phiên bản cơ sở dữ liệu của mình, 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ính toán tài nguyên. Các bước nhảy mạng xa hơn dễ bị lỗi hơn và tăng độ trễ truy vấn.

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

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

ID tài liệu

  • Tránh các ID tài liệu ... .
  • Tránh sử dụng / chuyển tiếp dấu gạch chéo trong ID tài liệu.
  • Không sử dụng ID tài liệu tăng dần đơn điệu, chẳng hạn như:

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

    Các ID 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ì chúng yêu cầu thoát thêm:

    • . Giai đoạn
    • [ dấu ngoặc trái
    • ] dấu ngoặc phải
    • * dấu hoa thị
    • ` đánh dấu ngược

chỉ mục

  • Tránh sử dụng quá nhiều chỉ mục. Quá nhiều chỉ mục có thể làm tăng độ trễ ghi và tăng chi phí lưu trữ cho các mục nhập chỉ mục.

  • Xin lưu ý rằng việc lập chỉ mục các trường có giá trị tăng dần đều, chẳng hạn như dấu thời gian, có thể dẫn đến các điểm nóng ảnh hưởng đến độ trễ đối với các ứng dụng có tốc độ đọc và ghi cao.

miễn trừ chỉ số

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

Trường hợp Sự miêu 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 sử 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 cho trường đó.

Tỷ lệ ghi cao vào một bộ sưu tậ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 bộ sưu tập, chẳng hạn như dấu thời gian, thì tốc độ ghi tối đa cho bộ sưu tập là 500 lần 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 cho trường để 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 bộ sưu tập chứa tài liệu có trường dấu thời gian có thể đạt đến giới hạn 500 lần 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. 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ốc độ lưu lượng truy cập cao hơn. Cách tốt nhất là thêm các trường hợp miễn trừ một trường cho các trường TTL của bạn.

Mảng lớn hoặc trường bản đồ

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

Thao tác đọc 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 Cập nhật cho một tài liệu .

  • Sử dụng cuộc gọi không đồng bộ nếu có thay vì cuộc gọi đồng bộ. Các cuộc gọi không đồng bộ 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 tra cứu và truy vấn không có phần phụ thuộc dữ liệu, thì không cần đợi đồng bộ cho đến khi tra cứu hoàn tất trước khi bắt đầu truy vấn.

  • Không sử dụng offset. Thay vào đó, hãy sử dụng con trỏ . Việc sử dụng phần bù chỉ tránh trả lại tài liệu bị bỏ qua cho ứng dụng của bạn, nhưng những 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 được lập hóa đơn cho các thao tác đọc cần thiết để truy xuất chúng.

Giao dịch thử lại

Thư viện máy khách và SDK Cloud Firestore 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 thực hiện các lần thử lại giao dịch để tăng độ tin cậy.

Cập nhật theo thời gian thực

Để có hiệu suất trình nghe ảnh chụp nhanh tốt nhất, hãy giữ cho tài liệu của bạn ở kích thước nhỏ và kiểm soát tốc độ đọc của khách hàng. Các đề xuất sau đây cung cấp hướng dẫn để tối đa hóa hiệu suất. Vượt quá các đề xuất này có thể dẫn đến độ trễ thông báo tăng lên.

Sự giới thiệu Chi tiết
Giảm tỷ lệ rời người nghe ảnh chụp nhanh

Tránh thường xuyên khuấy động người nghe, đặc biệt là khi cơ sở dữ liệu của bạn đang chịu tải ghi đáng kể

Lý tưởng nhất là ứng dụng của bạn nên thiết lập tất cả các trình xử lý ảnh chụp nhanh cần thiết ngay sau khi mở kết nối với Cloud Firestore. Sau khi thiết lập trình xử lý ảnh chụp nhanh ban đầu, bạn nên tránh nhanh chóng thêm hoặc xóa trình xử lý ảnh chụp nhanh trong cùng một kết nối.

Để đảm bảo tính nhất quán của dữ liệu, Cloud Firestore cần chuẩn bị từng trình xử lý ảnh chụp nhanh mới từ dữ liệu nguồn của nó và sau đó bắt kịp các thay đổi mới. Tùy thuộc vào tốc độ ghi của cơ sở dữ liệu của bạn, đây có thể là một thao tác tốn kém.

Trình nghe ảnh chụp nhanh của bạn có thể gặp phải độ trễ tăng lên nếu bạn thường xuyên thêm hoặc xóa trình nghe ảnh chụp nhanh vào tài liệu tham khảo. Nói chung, một trình lắng nghe được gắn liên tục hoạt động tốt hơn việc gắn và tách một trình lắng nghe tại vị trí đó cho cùng một lượng dữ liệu. Để có hiệu suất tốt nhất, trình nghe ảnh chụp nhanh phải có thời gian tồn tại từ 30 giây trở lên. Nếu bạn gặp sự cố về hiệu suất của trình nghe trong ứng dụng của mình, hãy thử theo dõi số lần nghe và không nghe của ứng dụng để xác định xem chúng có xảy ra quá thường xuyên không.

Giới hạn người nghe ảnh chụp nhanh trên mỗi khách hàng

100

Giữ số lượng người nghe ảnh chụp nhanh trên mỗi khách hàng dưới 100.

Giới hạn tỷ lệ ghi bộ sưu tập

1.000 thao tác/giây

Giữ tốc độ thao tác ghi cho một bộ sưu tập riêng lẻ dưới 1.000 thao tác/giây.

Hạn chế tỷ lệ đẩy khách hàng cá nhân

1 tài liệu/giây

Giữ tốc độ tài liệu mà cơ sở dữ liệu đẩy tới một khách hàng cá nhân dưới 1 tài liệu/giây.

Hạn chế tỷ lệ đẩy khách hàng toàn cầu

1.000.000 tài liệu/giây

Giữ tốc độ tài liệu mà cơ sở dữ liệu đẩy tới tất cả các máy khách dưới 1.000.000 tài liệu/giây.

Đây là một giới hạn mềm. Cloud Firestore không ngăn bạn vượt qua ngưỡng này nhưng nó ảnh hưởng rất nhiều đến hiệu suất.

Giới hạn tải trọng tài liệu cá nhân

10 KiB/giây

Giữ kích thước tài liệu tối đa được tải xuống bởi một khách hàng cá nhân dưới 10 KiB/giây.

Giới hạn tải trọng tài liệu toàn cầu

1 GiB/giây

Giữ kích thước tài liệu tối đa được tải xuống trên tất cả các máy khách dưới 1 GiB/giây.

Giới hạn số lượng trường trên mỗi tài liệu

100

Tài liệu của bạn nên có ít hơn 100 trường.

Hiểu các giới hạn tiêu chuẩn của Cloud Firestore

Hãy ghi nhớ các giới hạn tiêu chuẩn cho Cloud Firestore .

Đặc biệt chú ý đến giới hạn 1 lần ghi mỗi giây đối với tài liệu và giới hạn 1.000.000 kết nối đồng thời trên mỗi cơ sở dữ liệu. Đây là những giới hạn mềm mà Cloud Firestore không ngăn bạn vượt quá. Tuy nhiên, việc vượt quá các giới hạn này có thể ảnh hưởng đến hiệu suất, tùy thuộc vào tổng tỷ lệ đọc và ghi của bạn.

Thiết kế theo quy mô

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 các vấn đề gây tranh cãi.

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

Khi bạn thiết kế ứng dụng của mình, hãy cân nhắc xem ứng dụng của bạn cập nhật các tài liệu đơn lẻ nhanh như thế nào. Cách tốt nhất để mô tả hiệu suất khối lượng công việc của bạn là thực hiện 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, sự tranh chấp giữa các yêu cầu và số lượng các chỉ mục bị ảnh hưởng.

Một 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 áp dụng đồng bộ thao tác ghi trên một nhóm các bản sao. Ở tốc độ ghi đủ cao, cơ sở dữ liệu sẽ bắt đầu gặp phải sự tranh chấp, độ trễ cao hơn hoặc các lỗi khác.

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

Tránh tốc độ đọc hoặc ghi cao đối với các tài liệu đóng theo thứ tự từ điển, nếu không ứng dụng của bạn sẽ gặp lỗi tranh chấp. Sự cố này được gọi là phát điểm truy cập và ứng dụng của bạn có thể gặp phải điểm phát sóng nếu 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ổ ID tăng dần đơn điệu của riêng nó.

    Cloud Firestore phân bổ ID tài liệu bằng thuật toán phân tán. Bạn sẽ không gặp phải điểm nóng khi ghi nếu bạn tạo tài liệu mới bằng cách sử dụng ID 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 với trường tăng dần đều, như dấu thời gian, với tốc độ rất cao.

  • Xóa tài liệu trong 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 đã xóa

Tránh các truy vấn bỏ qua dữ liệu đã xóa 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 các kết quả truy vấn ban đầu gần đây đã bị xóa.

Một ví dụ về khối lượng công việc có thể phải bỏ qua nhiều dữ liệu đã xóa là một khối lượng công việc cố gắng tìm các mục công việc đã xếp hàng cũ nhất. Truy vấn có thể giống như:

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, nó sẽ quét các mục nhập chỉ mục cho trường created trên bất kỳ tài liệu nào đã xóa 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 nơi 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 phản mẫu để có 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ự từ điển để 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. Chúng tôi khuyên bạn nên bắt đầu với tối đa 500 thao tác mỗi giây cho bộ sưu tập mới và sau đó tăng lưu lượng truy cập lên 50% cứ sau 5 phút. Bạn có thể tăng lưu lượng ghi của mình theo cách tương tự, nhưng hãy ghi nhớ Giới hạn tiêu chuẩn của Cloud Firestore . Đảm bảo rằng các thao tác được phân bổ tương đối đồng đều trong phạm vi phím. Đây được gọi là quy tắc "500/50/5".

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

Việc tăng dần dần đặ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ì hãy đọc từ bộ sưu tập mới. Tuy nhiên, điều này có thể gây ra sự gia tăng đột ngột về lưu lượng truy cập vào các tài liệu đóng theo thứ tự từ điển trong bộ sưu tập mới. Cloud Firestore có thể không 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 ID 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 bộ sưu tập mới tùy thuộc vào mô hình dữ liệu của bạn. Dưới đây là một chiến lược ví dụ đượ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 về 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 từ bộ sưu tập mới. Tỷ lệ đọc các tài liệu không tồn tại cao có thể dẫn đến việc phát điểm truy cập, vì vậy hãy đảm bảo tăng dần tải cho bộ sưu tậ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, sau đó xóa tài liệu cũ. Tăng dần số lần đọc song song để đảm bảo rằng Cloud Firestore có thể xử lý lưu lượng truy cập vào bộ sưu tập mới.

Một chiến lược khả thi để tăng dần số lần đọc hoặc ghi vào một bộ sưu tập mới là sử dụng hàm băm xác định của ID người dùng để chọn một tỷ lệ phần trăm ngẫu nhiên người dùng đang cố viết tài liệu mới. Đảm bảo rằng kết quả băm ID người dùng không bị sai lệch bởi chức năng của bạn hoặc bởi 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 ID tài liệu tuần tự để ngăn các điểm phát só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ải tiến của chiến lược này là di chuyển từng 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 để di chuyển dựa trên hàm băm của ID người dùng. Sử dụng một công việc theo lô để di chuyển tài liệu cho nhóm người dùng đó và sử dụng các lần đọc song song cho người dùng ở giữa quá trình di chuyển.

Lưu ý rằng bạn không thể dễ dàng khôi phục trừ khi 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í Cloud Firestore phát sinh.

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ụ: sử dụng các quy tắc có thể tránh được trường hợp người dùng có ác ý tải xuống liên tục toàn bộ cơ sở dữ liệu của bạn.

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

,

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 ứng dụng sử dụng Cloud Firestore.

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

Khi bạn tạo phiên bản cơ sở dữ liệu của mình, 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ính toán tài nguyên. Các bước nhảy mạng xa hơn dễ bị lỗi hơn và tăng độ trễ truy vấn.

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

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

ID tài liệu

  • Tránh các ID tài liệu ... .
  • Tránh sử dụng / chuyển tiếp dấu gạch chéo trong ID tài liệu.
  • Không sử dụng ID tài liệu tăng dần đơn điệu, chẳng hạn như:

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

    Các ID 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ì chúng yêu cầu thoát thêm:

    • . Giai đoạn
    • [ dấu ngoặc trái
    • ] dấu ngoặc phải
    • * dấu hoa thị
    • ` đánh dấu ngược

chỉ mục

  • Tránh sử dụng quá nhiều chỉ mục. Quá nhiều chỉ mục có thể làm tăng độ trễ ghi và tăng chi phí lưu trữ cho các mục nhập chỉ mục.

  • Xin lưu ý rằng việc lập chỉ mục các trường có giá trị tăng dần đều, chẳng hạn như dấu thời gian, có thể dẫn đến các điểm nóng ảnh hưởng đến độ trễ đối với các ứng dụng có tốc độ đọc và ghi cao.

miễn trừ chỉ số

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

Trường hợp Sự miêu 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 sử 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 cho trường đó.

Tỷ lệ ghi cao vào một bộ sưu tậ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 bộ sưu tập, chẳng hạn như dấu thời gian, thì tốc độ ghi tối đa cho bộ sưu tập là 500 lần 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 cho trường để 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 bộ sưu tập chứa tài liệu có trường dấu thời gian có thể đạt đến giới hạn 500 lần 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. 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ốc độ lưu lượng truy cập cao hơn. Cách tốt nhất là thêm các trường hợp miễn trừ một trường cho các trường TTL của bạn.

Mảng lớn hoặc trường bản đồ

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

Thao tác đọc 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 Cập nhật cho một tài liệu .

  • Sử dụng cuộc gọi không đồng bộ nếu có thay vì cuộc gọi đồng bộ. Các cuộc gọi không đồng bộ 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 tra cứu và truy vấn không có phần phụ thuộc dữ liệu, thì không cần đợi đồng bộ cho đến khi tra cứu hoàn tất trước khi bắt đầu truy vấn.

  • Không sử dụng offset. Thay vào đó, hãy sử dụng con trỏ . Việc sử dụng phần bù chỉ tránh trả lại tài liệu bị bỏ qua cho ứng dụng của bạn, nhưng những 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 được lập hóa đơn cho các thao tác đọc cần thiết để truy xuất chúng.

Giao dịch thử lại

Thư viện máy khách và SDK Cloud Firestore 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 thực hiện các lần thử lại giao dịch để tăng độ tin cậy.

Cập nhật theo thời gian thực

Để có hiệu suất trình nghe ảnh chụp nhanh tốt nhất, hãy giữ cho tài liệu của bạn ở kích thước nhỏ và kiểm soát tốc độ đọc của khách hàng. Các đề xuất sau đây cung cấp hướng dẫn để tối đa hóa hiệu suất. Vượt quá các đề xuất này có thể dẫn đến độ trễ thông báo tăng lên.

Sự giới thiệu Chi tiết
Giảm tỷ lệ rời người nghe ảnh chụp nhanh

Tránh thường xuyên khuấy động người nghe, đặc biệt là khi cơ sở dữ liệu của bạn đang chịu tải ghi đáng kể

Lý tưởng nhất là ứng dụng của bạn nên thiết lập tất cả các trình xử lý ảnh chụp nhanh cần thiết ngay sau khi mở kết nối với Cloud Firestore. Sau khi thiết lập trình xử lý ảnh chụp nhanh ban đầu, bạn nên tránh nhanh chóng thêm hoặc xóa trình xử lý ảnh chụp nhanh trong cùng một kết nối.

Để đảm bảo tính nhất quán của dữ liệu, Cloud Firestore cần chuẩn bị từng trình xử lý ảnh chụp nhanh mới từ dữ liệu nguồn của nó và sau đó bắt kịp các thay đổi mới. Tùy thuộc vào tốc độ ghi của cơ sở dữ liệu của bạn, đây có thể là một thao tác tốn kém.

Trình nghe ảnh chụp nhanh của bạn có thể gặp phải độ trễ tăng lên nếu bạn thường xuyên thêm hoặc xóa trình nghe ảnh chụp nhanh vào tài liệu tham khảo. Nói chung, một trình lắng nghe được gắn liên tục hoạt động tốt hơn việc gắn và tách một trình lắng nghe tại vị trí đó cho cùng một lượng dữ liệu. Để có hiệu suất tốt nhất, trình nghe ảnh chụp nhanh phải có thời gian tồn tại từ 30 giây trở lên. Nếu bạn gặp sự cố về hiệu suất của trình nghe trong ứng dụng của mình, hãy thử theo dõi số lần nghe và không nghe của ứng dụng để xác định xem chúng có xảy ra quá thường xuyên không.

Giới hạn người nghe ảnh chụp nhanh trên mỗi khách hàng

100

Giữ số lượng người nghe ảnh chụp nhanh trên mỗi khách hàng dưới 100.

Giới hạn tỷ lệ ghi bộ sưu tập

1.000 thao tác/giây

Giữ tốc độ thao tác ghi cho một bộ sưu tập riêng lẻ dưới 1.000 thao tác/giây.

Hạn chế tỷ lệ đẩy khách hàng cá nhân

1 tài liệu/giây

Giữ tốc độ tài liệu mà cơ sở dữ liệu đẩy tới một khách hàng cá nhân dưới 1 tài liệu/giây.

Hạn chế tỷ lệ đẩy khách hàng toàn cầu

1.000.000 tài liệu/giây

Giữ tốc độ tài liệu mà cơ sở dữ liệu đẩy tới tất cả các máy khách dưới 1.000.000 tài liệu/giây.

Đây là một giới hạn mềm. Cloud Firestore không ngăn bạn vượt qua ngưỡng này nhưng nó ảnh hưởng rất nhiều đến hiệu suất.

Giới hạn tải trọng tài liệu cá nhân

10 KiB/giây

Giữ kích thước tài liệu tối đa được tải xuống bởi một khách hàng cá nhân dưới 10 KiB/giây.

Giới hạn tải trọng tài liệu toàn cầu

1 GiB/giây

Giữ kích thước tài liệu tối đa được tải xuống trên tất cả các máy khách dưới 1 GiB/giây.

Giới hạn số lượng trường trên mỗi tài liệu

100

Tài liệu của bạn nên có ít hơn 100 trường.

Hiểu các giới hạn tiêu chuẩn của Cloud Firestore

Hãy ghi nhớ các giới hạn tiêu chuẩn cho Cloud Firestore .

Đặc biệt chú ý đến giới hạn 1 lần ghi mỗi giây đối với tài liệu và giới hạn 1.000.000 kết nối đồng thời trên mỗi cơ sở dữ liệu. Đây là những giới hạn mềm mà Cloud Firestore không ngăn bạn vượt quá. Tuy nhiên, việc vượt quá các giới hạn này có thể ảnh hưởng đến hiệu suất, tùy thuộc vào tổng tỷ lệ đọc và ghi của bạn.

Thiết kế theo quy mô

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 các vấn đề gây tranh cãi.

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

Khi bạn thiết kế ứng dụng của mình, hãy cân nhắc xem ứng dụng của bạn cập nhật các tài liệu đơn lẻ nhanh như thế nào. Cách tốt nhất để mô tả hiệu suất khối lượng công việc của bạn là thực hiện 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, sự tranh chấp giữa các yêu cầu và số lượng các chỉ mục bị ảnh hưởng.

Một 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 áp dụng đồng bộ thao tác ghi trên một nhóm các bản sao. Ở tốc độ ghi đủ cao, cơ sở dữ liệu sẽ bắt đầu gặp phải sự tranh chấp, độ trễ cao hơn hoặc các lỗi khác.

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

Tránh tốc độ đọc hoặc ghi cao đối với các tài liệu đóng theo thứ tự từ điển, nếu không ứng dụng của bạn sẽ gặp lỗi tranh chấp. Sự cố này được gọi là phát điểm truy cập và ứng dụng của bạn có thể gặp phải điểm phát sóng nếu 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ổ ID tăng dần đơn điệu của riêng nó.

    Cloud Firestore phân bổ ID tài liệu bằng thuật toán phân tán. Bạn sẽ không gặp phải điểm nóng khi ghi nếu bạn tạo tài liệu mới bằng cách sử dụng ID 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 với trường tăng dần đều, như dấu thời gian, với tốc độ rất cao.

  • Xóa tài liệu trong 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 đã xóa

Tránh các truy vấn bỏ qua dữ liệu đã xóa 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 các kết quả truy vấn ban đầu gần đây đã bị xóa.

Một ví dụ về khối lượng công việc có thể phải bỏ qua nhiều dữ liệu đã xóa là một khối lượng công việc cố gắng tìm các mục công việc đã xếp hàng cũ nhất. Truy vấn có thể giống như:

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, nó sẽ quét các mục nhập chỉ mục cho trường created trên bất kỳ tài liệu nào đã xóa 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 nơi 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 phản mẫu để có 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ự từ điển để 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. Chúng tôi khuyên bạn nên bắt đầu với tối đa 500 thao tác mỗi giây cho bộ sưu tập mới và sau đó tăng lưu lượng truy cập lên 50% cứ sau 5 phút. Bạn có thể tăng lưu lượng ghi của mình theo cách tương tự, nhưng hãy ghi nhớ Giới hạn tiêu chuẩn của Cloud Firestore . Đảm bảo rằng các thao tác được phân bổ tương đối đồng đều trong phạm vi phím. Đây được gọi là quy tắc "500/50/5".

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

Việc tăng dần dần đặ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ì hãy đọc từ bộ sưu tập mới. Tuy nhiên, điều này có thể gây ra sự gia tăng đột ngột về lưu lượng truy cập vào các tài liệu đóng theo thứ tự từ điển trong bộ sưu tập mới. Cloud Firestore có thể không 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 ID 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 bộ sưu tập mới tùy thuộc vào mô hình dữ liệu của bạn. Dưới đây là một chiến lược ví dụ đượ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 về 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 từ bộ sưu tập mới. Tỷ lệ đọc các tài liệu không tồn tại cao có thể dẫn đến việc phát điểm truy cập, vì vậy hãy đảm bảo tăng dần tải cho bộ sưu tậ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, sau đó xóa tài liệu cũ. Tăng dần số lần đọc song song để đảm bảo rằng Cloud Firestore có thể xử lý lưu lượng truy cập vào bộ sưu tập mới.

Một chiến lược khả thi để tăng dần số lần đọc hoặc ghi vào một bộ sưu tập mới là sử dụng hàm băm xác định của ID người dùng để chọn một tỷ lệ phần trăm ngẫu nhiên người dùng đang cố viết tài liệu mới. Đảm bảo rằng kết quả băm ID người dùng không bị sai lệch bởi chức năng của bạn hoặc bởi 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 ID tài liệu tuần tự để ngăn các điểm phát só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ải tiến của chiến lược này là di chuyển từng 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 để di chuyển dựa trên hàm băm của ID người dùng. Sử dụng một công việc theo lô để di chuyển tài liệu cho nhóm người dùng đó và sử dụng các lần đọc song song cho người dùng ở giữa quá trình di chuyển.

Lưu ý rằng bạn không thể dễ dàng khôi phục trừ khi 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í Cloud Firestore phát sinh.

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ụ: sử dụng các quy tắc có thể tránh được trường hợp người dùng có ác ý tải xuống liên tục toàn bộ cơ sở dữ liệu của bạn.

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

,

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 ứng dụng sử dụng Cloud Firestore.

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

Khi bạn tạo phiên bản cơ sở dữ liệu của mình, 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ính toán tài nguyên. Các bước nhảy mạng xa hơn dễ bị lỗi hơn và tăng độ trễ truy vấn.

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

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

ID tài liệu

  • Tránh các ID tài liệu ... .
  • Tránh sử dụng / chuyển tiếp dấu gạch chéo trong ID tài liệu.
  • Không sử dụng ID tài liệu tăng dần đơn điệu, chẳng hạn như:

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

    Các ID 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ì chúng yêu cầu thoát thêm:

    • . Giai đoạn
    • [ dấu ngoặc trái
    • ] dấu ngoặc phải
    • * dấu hoa thị
    • ` đánh dấu ngược

chỉ mục

  • Tránh sử dụng quá nhiều chỉ mục. Quá nhiều chỉ mục có thể làm tăng độ trễ ghi và tăng chi phí lưu trữ cho các mục nhập chỉ mục.

  • Xin lưu ý rằng việc lập chỉ mục các trường có giá trị tăng dần đều, chẳng hạn như dấu thời gian, có thể dẫn đến các điểm nóng ảnh hưởng đến độ trễ đối với các ứng dụng có tốc độ đọc và ghi cao.

miễn trừ chỉ số

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

Trường hợp Sự miêu 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 sử 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 cho trường đó.

Tỷ lệ ghi cao vào một bộ sưu tậ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 bộ sưu tập, chẳng hạn như dấu thời gian, thì tốc độ ghi tối đa cho bộ sưu tập là 500 lần 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 cho trường để 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 bộ sưu tập chứa tài liệu có trường dấu thời gian có thể đạt đến giới hạn 500 lần 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. 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ốc độ lưu lượng truy cập cao hơn. Cách tốt nhất là thêm các trường hợp miễn trừ một trường cho các trường TTL của bạn.

Mảng lớn hoặc trường bản đồ

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

Thao tác đọc 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 Cập nhật cho một tài liệu .

  • Sử dụng cuộc gọi không đồng bộ nếu có thay vì cuộc gọi đồng bộ. Các cuộc gọi không đồng bộ 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 tra cứu và truy vấn không có phần phụ thuộc dữ liệu, thì không cần đợi đồng bộ cho đến khi tra cứu hoàn tất trước khi bắt đầu truy vấn.

  • Không sử dụng offset. Thay vào đó, hãy sử dụng con trỏ . Việc sử dụng phần bù chỉ tránh trả lại tài liệu bị bỏ qua cho ứng dụng của bạn, nhưng những 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 được lập hóa đơn cho các thao tác đọc cần thiết để truy xuất chúng.

Giao dịch thử lại

Thư viện máy khách và SDK Cloud Firestore 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 thực hiện các lần thử lại giao dịch để tăng độ tin cậy.

Cập nhật theo thời gian thực

Để có hiệu suất trình nghe ảnh chụp nhanh tốt nhất, hãy giữ cho tài liệu của bạn ở kích thước nhỏ và kiểm soát tốc độ đọc của khách hàng. Các đề xuất sau đây cung cấp hướng dẫn để tối đa hóa hiệu suất. Vượt quá các đề xuất này có thể dẫn đến độ trễ thông báo tăng lên.

Sự giới thiệu Chi tiết
Giảm tỷ lệ rời người nghe ảnh chụp nhanh

Tránh thường xuyên khuấy động người nghe, đặc biệt là khi cơ sở dữ liệu của bạn đang chịu tải ghi đáng kể

Lý tưởng nhất là ứng dụng của bạn nên thiết lập tất cả các trình xử lý ảnh chụp nhanh cần thiết ngay sau khi mở kết nối với Cloud Firestore. Sau khi thiết lập trình xử lý ảnh chụp nhanh ban đầu, bạn nên tránh nhanh chóng thêm hoặc xóa trình xử lý ảnh chụp nhanh trong cùng một kết nối.

Để đảm bảo tính nhất quán của dữ liệu, Cloud Firestore cần chuẩn bị từng trình xử lý ảnh chụp nhanh mới từ dữ liệu nguồn của nó và sau đó bắt kịp các thay đổi mới. Tùy thuộc vào tốc độ ghi của cơ sở dữ liệu của bạn, đây có thể là một thao tác tốn kém.

Trình nghe ảnh chụp nhanh của bạn có thể gặp phải độ trễ tăng lên nếu bạn thường xuyên thêm hoặc xóa trình nghe ảnh chụp nhanh vào tài liệu tham khảo. Nói chung, một trình lắng nghe được gắn liên tục hoạt động tốt hơn việc gắn và tách một trình lắng nghe tại vị trí đó cho cùng một lượng dữ liệu. Để có hiệu suất tốt nhất, trình nghe ảnh chụp nhanh phải có thời gian tồn tại từ 30 giây trở lên. Nếu bạn gặp sự cố về hiệu suất của trình nghe trong ứng dụng của mình, hãy thử theo dõi số lần nghe và không nghe của ứng dụng để xác định xem chúng có xảy ra quá thường xuyên không.

Giới hạn người nghe ảnh chụp nhanh trên mỗi khách hàng

100

Giữ số lượng người nghe ảnh chụp nhanh trên mỗi khách hàng dưới 100.

Giới hạn tỷ lệ ghi bộ sưu tập

1.000 thao tác/giây

Keep the rate of write operations for an individual collection under 1,000 operations/second.

Limit the individual client push rate

1 document/second

Keep the rate of documents the database pushes to an individual client under 1 document/second.

Limit the global client push rate

1,000,000 documents/second

Keep the rate of documents the database pushes to all clients under 1,000,000 documents/second.

This is a soft limit. Cloud Firestore does not stop you from surpassing this threshold but it greatly affects performance.

Limit the individual document payload

10 KiB/second

Keep the maximum document size downloaded by an individual client under 10 KiB/second.

Limit the global document payload

1 GiB/second

Keep the maximum document size downloaded across all clients under 1 GiB/second.

Limit the number of fields per document

100

Your documents should have fewer than 100 fields.

Understand the Cloud Firestore standard limits

Keep in mind the standard limits for Cloud Firestore .

Pay special attention to the 1 write per second limit for documents and the limit of 1,000,000 concurrent connections per database. These are soft limits that Cloud Firestore does not stop you from exceeding. However, going over these limits might affect performance, depending on your total read and write rates.

Designing for scale

The following best practices describe how to avoid situations that create contention issues.

Updates to a single document

As you design your app, consider how quickly your app updates single documents. The best way to characterize your workload's performance is to perform load testing. The exact maximum rate that an app can update a single document depends highly on the workload. Factors include the write rate, contention among requests, and the number affected indexes.

A document write operation updates the document and any associated indexes, and Cloud Firestore synchronously applies the write operation across a quorum of replicas. At high enough write rates, the database will start to encounter contention, higher latency, or other errors.

High read, write, and delete rates to a narrow document range

Avoid high read or write rates to lexicographically close documents, or your application will experience contention errors. This issue is known as hotspotting, and your application can experience hotspotting if it does any of the following:

  • Creates new documents at a very high rate and allocates its own monotonically increasing IDs.

    Cloud Firestore allocates document IDs using a scatter algorithm. You should not encounter hotspotting on writes if you create new documents using automatic document IDs.

  • Creates new documents at a high rate in a collection with few documents.

  • Creates new documents with a monotonically increasing field, like a timestamp, at a very high rate.

  • Deletes documents in a collection at a high rate.

  • Writes to the database at a very high rate without gradually increasing traffic.

Avoid skipping over deleted data

Avoid queries that skip over recently deleted data. A query may have to skip over a large number of index entries if the early query results have recently been deleted.

An example of a workload that might have to skip over a lot of deleted data is one that tries to find the oldest queued work items. The query might look like:

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()

Each time this query runs it scans over the index entries for the created field on any recently deleted documents. This slows down queries.

To improve the performance, use the start_at method to find the best place to start. For example:

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()

NOTE: The example above uses a monotonically increasing field which is an anti-pattern for high write rates.

Ramping up traffic

You should gradually ramp up traffic to new collections or lexicographically close documents to give Cloud Firestore sufficient time to prepare documents for increased traffic. We recommend starting with a maximum of 500 operations per second to a new collection and then increasing traffic by 50% every 5 minutes. You can similarly ramp up your write traffic, but keep in mind the Cloud Firestore Standard Limits . Be sure that operations are distributed relatively evenly throughout the key range. This is called the "500/50/5" rule.

Migrating traffic to a new collection

Gradual ramp up is particularly important if you migrate app traffic from one collection to another. A simple way to handle this migration is to read from the old collection, and if the document does not exist, then read from the new collection. However, this could cause a sudden increase of traffic to lexicographically close documents in the new collection. Cloud Firestore may be unable to efficiently prepare the new collection for increased traffic, especially when it contains few documents.

A similar problem can occur if you change the document IDs of many documents within the same collection.

The best strategy for migrating traffic to a new collection depends on your data model. Below is an example strategy known as parallel reads . You will need to determine whether or not this strategy is effective for your data, and an important consideration will be the cost impact of parallel operations during the migration.

Parallel reads

To implement parallel reads as you migrate traffic to a new collection, read from the old collection first. If the document is missing, then read from the new collection. A high rate of reads of non-existent documents can lead to hotspotting, so be sure to gradually increase load to the new collection. A better strategy is to copy the old document to the new collection then delete the old document. Ramp up parallel reads gradually to ensure that Cloud Firestore can handle traffic to the new collection.

A possible strategy for gradually ramping up reads or writes to a new collection is to use a deterministic hash of the user ID to select a random percentage of users attempting to write new documents. Be sure that the result of the user ID hash is not skewed either by your function or by user behavior.

Meanwhile, run a batch job that copies all your data from the old documents to the new collection. Your batch job should avoid writes to sequential document IDs in order to prevent hotspots. When the batch job finishes, you can read only from the new collection.

A refinement of this strategy is to migrate small batches of users at a time. Add a field to the user document which tracks migration status of that user. Select a batch of users to migrate based on a hash of the user ID. Use a batch job to migrate documents for that batch of users, and use parallel reads for users in the middle of migration.

Note that you cannot easily roll back unless you do dual writes of both the old and new entities during the migration phase. This would increase Cloud Firestore costs incurred.

Prevent unauthorized access

Prevent unauthorized operations on your database with Cloud Firestore Security Rules. For example, using rules could avoid a scenario where a malicious user repeatedly downloads your entire database.

Learn more about using Cloud Firestore Security Rules .

,

Use the best practices listed here as a quick reference when building an application that uses Cloud Firestore.

Database location

When you create your database instance, select the database location closest to your users and compute resources. Far-reaching network hops are more error-prone and increase query latency.

To maximize the availability and durability of your application, select a multi-region location and place critical compute resources in at least two regions.

Select a regional location for lower costs, for lower write latency if your application is sensitive to latency, or for co-location with other GCP resources .

Document IDs

  • Avoid the document IDs . and .. .
  • Avoid using / forward slashes in document IDs.
  • Do not use monotonically increasing document IDs such as:

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

    Such sequential IDs can lead to hotspots that impact latency.

Field Names

  • Avoid the following characters in field names because they require extra escaping:

    • . period
    • [ left bracket
    • ] right bracket
    • * asterisk
    • ` backtick

Indexes

  • Avoid using too many indexes. An excessive number of indexes can increase write latency and increases storage costs for index entries.

  • Be aware that indexing fields with monotonically increasing values, such as timestamps, can lead to hotspots which impact latency for applications with high read and write rates.

Index exemptions

For most apps, you can rely on automatic indexing as well as any error message links to manage your indexes. However, you may want to add single-field exemptions in the following cases:

Case Description
Large string fields

If you have a string field that often holds long string values that you don't use for querying, you can cut storage costs by exempting the field from indexing.

High write rates to a collection containing documents with sequential values

If you index a field that increases or decreases sequentially between documents in a collection, like a timestamp, then the maximum write rate to the collection is 500 writes per second. If you don't query based on the field with sequential values, you can exempt the field from indexing to bypass this limit.

In an IoT use case with a high write rate, for example, a collection containing documents with a timestamp field might approach the 500 writes per second limit.

TTL fields

If you use TTL (time-to-live) policies , note that the TTL field must be a timestamp. Indexing on TTL fields is enabled by default and can affect performance at higher traffic rates. As a best practice, add single-field exemptions for your TTL fields.

Large array or map fields

Large array or map fields can approach the limit of 40,000 index entries per document. If you are not querying based on a large array or map field, you should exempt it from indexing.

Read and write operations

  • The exact maximum rate that an app can update a single document depends highly on the workload. For more information, see Updates to a single document .

  • Use asynchronous calls where available instead of synchronous calls. Asynchronous calls minimize latency impact. For example, consider an application that needs the result of a document lookup and the results of a query before rendering a response. If the lookup and the query do not have a data dependency, there is no need to synchronously wait until the lookup completes before initiating the query.

  • Do not use offsets. Instead, use cursors . Using an offset only avoids returning the skipped documents to your application, but these documents are still retrieved internally. The skipped documents affect the latency of the query, and your application is billed for the read operations required to retrieve them.

Transactions retries

The Cloud Firestore SDKs and client libraries automatically retry failed transactions to deal with transient errors. If your application accesses Cloud Firestore through the REST or RPC APIs directly instead of through an SDK, your application should implement transaction retries to increase reliability.

Realtime updates

For the best snapshot listener performance, keep your documents small and control the read rate of your clients. The following recommendations provide guidelines for maximizing performance. Exceeding these recommendations can result in increased notification latency.

Recommendation Details
Reduce snapshot listener churn rate

Avoid frequently churning listeners, especially when your database is under significant write load

Ideally, your application should set up all the required snapshot listeners soon after opening a connection to Cloud Firestore. After setting up your initial snapshot listeners, you should avoid quickly adding or removing snapshot listeners in the same connection.

To ensure data consistency, Cloud Firestore needs to prime each new snapshot listener from its source data and then catch up to new changes. Depending on your database's write rate, this can be an expensive operation.

Your snapshot listeners can experience increased latency if you frequently add or remove snapshot listeners to references. In general, a constantly-attached listener performs better than attaching and detaching a listener at that location for the same amount of data. For best performance, snapshot listeners should have a lifetime of 30 seconds or longer. If you encounter listener performance issues in your app, try tracking your app's listens and unlistens to determine if they may be happening too frequently.

Limit snapshot listeners per client

100

Keep the number of snapshot listeners per client under 100.

Limit the collection write rate

1,000 operations/second

Keep the rate of write operations for an individual collection under 1,000 operations/second.

Limit the individual client push rate

1 document/second

Keep the rate of documents the database pushes to an individual client under 1 document/second.

Limit the global client push rate

1,000,000 documents/second

Keep the rate of documents the database pushes to all clients under 1,000,000 documents/second.

This is a soft limit. Cloud Firestore does not stop you from surpassing this threshold but it greatly affects performance.

Limit the individual document payload

10 KiB/second

Keep the maximum document size downloaded by an individual client under 10 KiB/second.

Limit the global document payload

1 GiB/second

Keep the maximum document size downloaded across all clients under 1 GiB/second.

Limit the number of fields per document

100

Your documents should have fewer than 100 fields.

Understand the Cloud Firestore standard limits

Keep in mind the standard limits for Cloud Firestore .

Pay special attention to the 1 write per second limit for documents and the limit of 1,000,000 concurrent connections per database. These are soft limits that Cloud Firestore does not stop you from exceeding. However, going over these limits might affect performance, depending on your total read and write rates.

Designing for scale

The following best practices describe how to avoid situations that create contention issues.

Updates to a single document

As you design your app, consider how quickly your app updates single documents. The best way to characterize your workload's performance is to perform load testing. The exact maximum rate that an app can update a single document depends highly on the workload. Factors include the write rate, contention among requests, and the number affected indexes.

A document write operation updates the document and any associated indexes, and Cloud Firestore synchronously applies the write operation across a quorum of replicas. At high enough write rates, the database will start to encounter contention, higher latency, or other errors.

High read, write, and delete rates to a narrow document range

Avoid high read or write rates to lexicographically close documents, or your application will experience contention errors. This issue is known as hotspotting, and your application can experience hotspotting if it does any of the following:

  • Creates new documents at a very high rate and allocates its own monotonically increasing IDs.

    Cloud Firestore allocates document IDs using a scatter algorithm. You should not encounter hotspotting on writes if you create new documents using automatic document IDs.

  • Creates new documents at a high rate in a collection with few documents.

  • Creates new documents with a monotonically increasing field, like a timestamp, at a very high rate.

  • Deletes documents in a collection at a high rate.

  • Writes to the database at a very high rate without gradually increasing traffic.

Avoid skipping over deleted data

Avoid queries that skip over recently deleted data. A query may have to skip over a large number of index entries if the early query results have recently been deleted.

An example of a workload that might have to skip over a lot of deleted data is one that tries to find the oldest queued work items. The query might look like:

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()

Each time this query runs it scans over the index entries for the created field on any recently deleted documents. This slows down queries.

To improve the performance, use the start_at method to find the best place to start. For example:

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()

NOTE: The example above uses a monotonically increasing field which is an anti-pattern for high write rates.

Ramping up traffic

You should gradually ramp up traffic to new collections or lexicographically close documents to give Cloud Firestore sufficient time to prepare documents for increased traffic. We recommend starting with a maximum of 500 operations per second to a new collection and then increasing traffic by 50% every 5 minutes. You can similarly ramp up your write traffic, but keep in mind the Cloud Firestore Standard Limits . Be sure that operations are distributed relatively evenly throughout the key range. This is called the "500/50/5" rule.

Migrating traffic to a new collection

Gradual ramp up is particularly important if you migrate app traffic from one collection to another. A simple way to handle this migration is to read from the old collection, and if the document does not exist, then read from the new collection. However, this could cause a sudden increase of traffic to lexicographically close documents in the new collection. Cloud Firestore may be unable to efficiently prepare the new collection for increased traffic, especially when it contains few documents.

A similar problem can occur if you change the document IDs of many documents within the same collection.

The best strategy for migrating traffic to a new collection depends on your data model. Below is an example strategy known as parallel reads . You will need to determine whether or not this strategy is effective for your data, and an important consideration will be the cost impact of parallel operations during the migration.

Parallel reads

To implement parallel reads as you migrate traffic to a new collection, read from the old collection first. If the document is missing, then read from the new collection. A high rate of reads of non-existent documents can lead to hotspotting, so be sure to gradually increase load to the new collection. A better strategy is to copy the old document to the new collection then delete the old document. Ramp up parallel reads gradually to ensure that Cloud Firestore can handle traffic to the new collection.

A possible strategy for gradually ramping up reads or writes to a new collection is to use a deterministic hash of the user ID to select a random percentage of users attempting to write new documents. Be sure that the result of the user ID hash is not skewed either by your function or by user behavior.

Meanwhile, run a batch job that copies all your data from the old documents to the new collection. Your batch job should avoid writes to sequential document IDs in order to prevent hotspots. When the batch job finishes, you can read only from the new collection.

A refinement of this strategy is to migrate small batches of users at a time. Add a field to the user document which tracks migration status of that user. Select a batch of users to migrate based on a hash of the user ID. Use a batch job to migrate documents for that batch of users, and use parallel reads for users in the middle of migration.

Note that you cannot easily roll back unless you do dual writes of both the old and new entities during the migration phase. This would increase Cloud Firestore costs incurred.

Prevent unauthorized access

Prevent unauthorized operations on your database with Cloud Firestore Security Rules. For example, using rules could avoid a scenario where a malicious user repeatedly downloads your entire database.

Learn more about using Cloud Firestore Security Rules .