2015-12-07 28 views
11

Tôi có một số yếu tố lặp lại trong thông điệp protobuf của mình. Khi thời lượng chạy của thư có thể là bất cứ điều gì - tôi thấy một số câu hỏi đã được hỏi như thế này - [1]: Maximum serialized Protobuf message sizegoogle protobuf kích thước tối đa

  1. Tôi có một câu hỏi hơi khác ở đây. Nếu nhà cung cấp dịch vụ JMS (dịch vụ nhắn tin Java) của tôi (trong trường hợp này máy chủ web của tôi hoặc máy chủ tibco jms) không có bất kỳ giới hạn nào về kích thước thư tối đa, thì trình biên dịch đệm giao thức có thể phàn nàn về kích thước thư tối đa không?
  2. Hiệu suất mã hóa/giải mã có bị khủng khiếp ở kích thước lớn (khoảng ~ 10MB) ..?

Trả lời

22

10MB đang đẩy nó nhưng có thể bạn sẽ ổn.

Protobuf có giới hạn cứng 2GB, bởi vì nhiều triển khai sử dụng số học ký 32 bit. Vì lý do bảo mật, nhiều triển khai (đặc biệt là các trang do Google cung cấp) áp đặt giới hạn kích thước 64MB theo mặc định, mặc dù bạn có thể tăng giới hạn này theo cách thủ công nếu cần.

Việc triển khai sẽ không "chậm lại" với các thư lớn, nhưng vấn đề là bạn phải luôn phân tích toàn bộ thư cùng một lúc trước khi bạn có thể bắt đầu sử dụng bất kỳ nội dung nào. Điều này có nghĩa là toàn bộ tin nhắn phải phù hợp với RAM (lưu ý rằng sau khi phân tích cú pháp các đối tượng tin nhắn trong bộ nhớ lớn hơn nhiều so với thông báo gốc) và thậm chí nếu bạn chỉ quan tâm đến một trường, bạn phải đợi toàn bộ để phân tích cú pháp.

Nói chung, tôi khuyên bạn nên cố gắng giới hạn mình là 1MB theo quy tắc chung. Ngoài ra, hãy suy nghĩ về việc tách thông điệp thành nhiều phần có thể được phân tích cú pháp độc lập. Tuy nhiên, mỗi ứng dụng - đối với một số, 10MB là không lớn, đối với những người khác 1MB đã quá lớn. Bạn sẽ phải lập hồ sơ ứng dụng của riêng mình để tìm hiểu.

Tôi đã thực sự thấy các trường hợp mọi người vui vẻ gửi tin nhắn lớn hơn 1GB, vì vậy ... nó "hoạt động".

Trên một mặt lưu ý, Cap'n Proto có thiết kế rất giống với Protobuf nhưng có thể hỗ trợ thư lên tới 2^64 byte (2^32 phân đoạn 4GB) và thực tế cho phép bạn đọc một trường từ thư không phân tích cú pháp toàn bộ thư (nếu nó nằm trong một tệp trên đĩa, hãy sử dụng mmap() để tránh đọc toàn bộ nội dung).

(Tiết lộ:. Tôi là tác giả của Cap'n Proto cũng như hầu hết các mã nguồn mở của Google đang Protobuf)

+0

gì nếu tôi có vài ints và 1 mảng byte lớn trong protobuf. Nó vẫn còn là một vấn đề? –

+1

@MuditJain Trình phân tích cú pháp sẽ phân bổ mảng byte thứ hai và sao chép các byte từ thư của bạn vào mảng byte đó. Bản sao phải khá nhanh nhưng nó vẫn là một bản sao.Nếu bạn thay vào đó đã viết một protobuf * theo sau là * mảng byte của bạn (mà không đặt mảng byte vào bản thân thông điệp), bạn có thể làm cho nó nhanh hơn - nhưng ít thuận tiện hơn. Bạn nên đo lường hiệu suất và quyết định xem bạn có cần nó nhanh hơn không. –

+0

Tôi có một bảng lớn với 10 triệu hàng dữ liệu nhị phân blob. Do cơ sở hạ tầng giảm bản đồ, tôi phải tuần tự hóa bảng này trên nhiều máy độc lập, ví dụ: mỗi máy xuất 100K hàng. Ý tưởng ban đầu của tôi để sắp xếp thứ tự này là để sản xuất trên mỗi máy (row_binary_size_uint64, actual_binary_blob), (row_binary_size_uint64, actual_binary_blob), ... và chỉ dữ liệu concat được tạo trên mỗi máy. Bây giờ cho khả năng mở rộng trong tương lai, tôi muốn chuyển đổi mỗi hàng sang định dạng protobuf (câu hỏi ban đầu của tôi). Vì vậy, có một cách để phát hiện ranh giới của tin nhắn protobuf và gửi cho phân tích cú pháp? –

3
  1. Tôi không nghĩ trình biên dịch protobuf sẽ từng phàn nàn về kích thước thư. Ít nhất là không cho đến khi bạn đạt đến 18 exabyte tối đa là uint64_t.

  2. Đối với hầu hết các triển khai, hiệu suất bắt đầu bị ảnh hưởng tại thời điểm thư không thể khớp với RAM cùng một lúc. Vì vậy, 10 MB nên được tốt, 10 GB không. Một vấn đề khác có thể là nếu bạn không cần tất cả dữ liệu - protobuf không hỗ trợ truy cập ngẫu nhiên, vì vậy bạn cần phải giải mã toàn bộ tin nhắn ngay cả khi bạn chỉ cần một phần của nó.

Các vấn đề liên quan