1. Trang chủ
  2. » Luận Văn - Báo Cáo

Tiểu Luận - Thiết Kế Ngoại Vi Và Kỹ Thuật Ghép Nối - Đề Tài - Tìm Hiểu Về Chuẩn Đóng Gói Protocol Buffer

28 15 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Tìm Hiểu Về Chuẩn Đóng Gói Protocol Buffer
Trường học Học Viện Công Nghệ Bưu Chính Viễn Thông
Thể loại báo cáo
Định dạng
Số trang 28
Dung lượng 1,42 MB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Protocol buffer dùng vào việc gì?Protocol buffers cung cấp định dạng tuần tự hóa cho các gói dữ liệu đã nhập, có cấu trúc có kích thước lên tới vài megabyte.. Chúng được sử dụng rộng rãi

Trang 1

BỘ THÔNG TIN VÀ TRUYỀN THÔNG

HỌC VIỆN CÔNG NGHỆ BƯU CHÍNH VIỄN THÔNG

BÁO CÁO Tìm hiểu về chuẩn đóng gói Protocol Buffer

Trang 3

1 Google protocol buffer là gì ?

Protocol buffer còn được biết như protobuf là language-neutral,

platform-neutral của google phiên bản nội bộ được công bố vào năm 2001 và phiên bản công khai đầu tiên được giới thiệu vào năm 2008 ( Repository ), mục tiêu của nó là để giảm số lượng byte cần thiết để biểu diễn một gói tin,

từ đó tăng tốc độ gửi nhận qua network vốn dĩ vẫn chậm chạp Và cho đến thời điểm này, protobuf vẫn là một trong những giao thức nhẹ nhàng và tiết kiệm được nhiều byte nhất Nó được thiết kế để trở thành language/platform neutral và có thể mở rộng Hiện tại, protobuf có hỗ trợ cho C ++, C, Go, Java

và Python

Protobuf là một open source dùng để encode dữ liệu có cấu trúc được phát triển tại google Nó rất hữu ích trong việc phát triển các chương trình để giao tiếp với nhau qua một wire hoặc để lưu trữ dữ liệu Tất cả những gì bạn phải làm là chỉ định một thông báo cho từng cấu trúc dữ liệu mà bạn muốn Serialize (theo định dạng giống như lớp Java) bằng cách sử dụng file đặc

Trang 4

2 Protocol buffer dùng vào việc gì?

Protocol buffers cung cấp định dạng tuần tự hóa cho các gói dữ liệu đã nhập, có cấu trúc có kích thước lên tới vài megabyte Định dạng phù hợp cho

cả lưu lượng mạng tạm thời và lưu trữ dữ liệu dài hạn Bộ đệm giao thức có thể được mở rộng với thông tin mới mà không làm mất hiệu lực dữ liệu hiện

có hoặc yêu cầu cập nhật mã

Protocol buffers là định dạng dữ liệu được sử dụng phổ biến nhất tại Google Chúng được sử dụng rộng rãi trong giao tiếp giữa các máy chủ cũng như để lưu trữ dữ liệu lưu trữ trên đĩa Protocol

buffer messages and services được mô tả bưởi file proto

Ví dụ message:

Trình biên dịch proto được gọi tại thời điểm xây dựng trên các

tệp proto để tạo mã bằng các ngôn ngữ lập trình khác nhau (được đề cập

3

Trang 5

trong Khả năng tương thích đa ngôn ngữ ở phần sau của chủ đề này) để thaotác với protocol buffer tương ứng Mỗi lớp được tạo chứa các bộ truy cập đơn giản cho từng trường và các phương thức để tuần tự hóa và phân tích cú pháp toàn bộ cấu trúc đến và từ các byte thô Phần sau đây cho bạn thấy một

ví dụ sử dụng các phương thức được tạo đó:

Bởi vì bộ đệm giao thức được sử dụng rộng rãi trên tất cả các loại dịch

vụ tại Google và dữ liệu trong protocol buffer có thể tồn tại trong một thời gian, nên việc duy trì khả năng tương thích ngược là rất quan trọng Protocol buffer cho phép hỗ trợ liền mạch các thay đổi, bao gồm thêm các trường mới

và xóa các trường hiện có, vào bất kì bộ đệm giao thức nào mà không phá vỡcác dịch vụ hiện có

Protocol Buffers ( Protobuf) là một cơ chế có thể mở rộng, trung lập về ngôn ngữ, trung lập với nền tảng, có thể mở rộng để tuần tự hóa dữ liệu có cấu trúc để sử dụng trong các giao thức truyền thông, lưu trữ dữ liệu, v.v Đây là một dự án nguồn mở do Google phát triển nhằm cung cấp một phươngtiện hiệu quả và đáng tin cậy để trao đổi thông tin giữa các ứng dụng Bạn cóthể quyết định cách mã nguồn được tạo đặc biệt có thể đọc dữ liệu

Protobuf lưu trữ dữ liệu có cấu trúc ở dạng nhị phân một cách hiệu quả

và nhỏ gọn, cho phép truyền nhanh hơn qua các kết nối mạng Protobuf hỗ trợ nhiều loại ngôn ngữ lập trình đã chọn và không phụ thuộc vào nền tảng, nghĩa là các chương trình được viết bằng ngôn ngữ này có thể dễ dàng

chuyển sang các nền tảng khác

Ngoài ra, đây là một cách hiệu quả và mạnh mẽ để tạo dữ liệu có cấu trúc có thể được sử dụng trong các ứng dụng khác nhau, chẳng hạn như dịch

vụ web, cơ sở dữ liệu, hệ thống RPC và định dạng tệp Nó hỗ trợ nhiều loại

dữ liệu, bao gồm chuỗi, số nguyên, số float, booleans, enums (liệt kê), bản đồ(mảng kết hợp), v.v Cú pháp độc lập với ngôn ngữ cho phép các chương trình được viết bằng các ngôn ngữ lập trình được chọn khác nhau giao tiếp với nhau một cách đáng tin cậy

Trang 6

Hơn nữa, định dạng Protobuf cung cấp một số lợi thế so với các định dạng khác, chẳng hạn như XML hoặc JSON Do dữ liệu có cấu trúc được lưu trữ ở định dạng nhị phân nên dữ liệu này nhỏ hơn nhiều so với các định dạng dựa trên văn bản như định dạng XML hoặc JSON, giúp truyền qua mạng nhanh hơn Ngoài ra, Protobuf được thiết kế để dễ dàng mở rộng, khiến nó trở nên lý tưởng để xử lý các cấu trúc dữ liệu thay đổi nhanh chóng và các tính năng mới Cuối cùng, mã nguồn được tạo đặc biệt từ Protobuf có thể được tối ưu hóa về tốc độ, dẫn đến các ứng dụng nhanh hơn sử dụng ít bộ nhớ hơn.

Protobuf có thể được sử dụng để tạo các API hiệu quả có thể được sử dụng làm luồng dữ liệu giữa các hệ thống Bộ đệm giao thức là một cách tuyệt vời để giúp trao đổi dữ liệu hiệu quả hơn, vì chúng yêu cầu ít băng thông hơn và có kích thước thông báo nhỏ hơn so với các giải pháp XML hoặc JSON tiêu chuẩn

Nó cũng có thể lưu trữ dữ liệu có cấu trúc một cách có tổ chức Nó cho phép các nhà phát triển xác định cấu trúc dữ liệu và sau đó tuần tự hóa nó thành định dạng nhị phân, làm cho dữ liệu có thể di chuyển trên các hệ

thống Điều này giúp dễ dàng lưu trữ dữ liệu trong cơ sở dữ liệu hoặc các hệ thống phân tán khác Nó cũng đảm bảo khả năng tương thích ngược khi thay đổi cấu trúc dữ liệu

Hơn nữa, nó có thể được sử dụng để giao tiếp RPC giữa các ứng dụng

Ví dụ: bạn có thể sử dụng định dạng Protobuf để xác định thông báo được gửi giữa hai ứng dụng Điều này giúp các ứng dụng dễ dàng giao tiếp với nhau một cách hiệu quả, vì chúng có thể đơn giản tuần tự hóa và giải tuần tựhóa dữ liệu bằng cách sử dụng cùng một cấu trúc thông báo [2]

5

Trang 7

Vi dụ Compile and run Protobuf on Ubuntu use C++:

Nguồn: How to Install, Compile and run Protobuf on Ubuntu

Trang 8

3.1 Giao tiếp RPC giữa các ứng dụng là gì?

● RPC (Cuộc gọi thủ tục từ xa) là một loại giao tiếp cho phép các ứng dụng giao tiếp với nhau qua mạng Nó cho phép các chức năng hoặc thủ tục từ một ứng dụng được gọi từ một ứng dụng khác, cho phép tính toán phân tán và khả năng mở rộng lớn hơn

● RPC hoạt động bằng cách gửi các yêu cầu từ ứng dụng gọi điện (còn được gọi là máy khách) đến một ứng dụng khác (được gọi là máy chủ)

và nhận phản hồi Yêu cầu thường được gửi dưới dạng gói dữ liệu chứathông tin về thủ tục cần được thực thi, chẳng hạn như tham số và giá trị trả về

● Sau khi máy chủ nhận được gói, nó sẽ xử lý gói đó và trả về phản hồi với bất kì dữ liệu hoặc kết quả có liên quan nào

Protobuf cũng cho phép các nhà phát triển tạo các ứng dụng máy

khách/máy chủ có thể tương tác với nhau mà không phải lo lắng về các sắc thái của các giao thức truyền thông khác nhau Nó giúp dễ dàng viết các ứng dụng đa nền tảng có thể giao tiếp với nhau bằng cùng một định dạng thông báo

Nhìn chung, Protocol Buffers là một cách mạnh mẽ và hiệu quả để trao đổithông tin giữa các hệ thống

● Nó cho phép các nhà phát triển tạo các API hiệu quả để truyền dữ liệu

có cấu trúc

● Lưu trữ dữ liệu một cách có tổ chức

● Và tạo các ứng dụng máy khách/máy chủ có thể giao tiếp với nhau [2]

3.2 Làm việc với Protocol Buffers

Theo mặc định, gRPC sử dụng Protocol Buffer, là cơ chế nguồn mở hoàn thiện của Google để tuần tự hóa (serializing) dữ liệu có cấu trúc (mặc dù

nó có thể được sử dụng với các định dạng dữ liệu khác như JSON) Dưới đây

là phần giới thiệu nhanh về cách hoạt động

7

Trang 9

Bước đầu tiên khi làm việc với protocol bufffer (bộ đệm giao thức) là xác định cấu trúc cho dữ liệu muốn tuần tự hóa trong 1 proto file: đây là file văn bản thông thường có phần mở rộng là proto Dữ liệu protocol buffer được cấu trúc như các message, trong đó mỗi message là một bản ghi

(record) logic nhỏ chứa một loạt các cặp key-value được gọi là các fields Đây

là một ví dụ đơn giản:

Sau đó, khi đã chỉ định cấu trúc dữ liệu của mình, ta sử dụng trình biên dịch protocol buffer (protoc) để sinh ra các lớp truy cập dữ liệu (data access classes) bằng ngôn ngữ ưa thích từ định nghĩa proto Chúng cung cấp các accessor đơn giản cho mỗi trường, như name() và set_name(), cũng như các phương thức (method) để tuần tự hóa/phân tích cú pháp toàn bộ cấu trúc đến/từ các byte thô Vì vậy, chẳng hạn, nếu ngôn ngữ được chọn là C++ thì việc chạy trình biên dịch trong ví dụ trên sẽ tạo ra một lớp (class) có tên là Person Sau đó, ta có thể sử dụng class này trong ứng dụng của mình để điền(populate), tuần tự hóa và lấy về Person protocol buffer message

Ta định nghĩa các gRPC service trong các file proto thông thường, với các tham số của phương thức RPC và kiểu trả về được chỉ định làm protocol buffer message:

GRPC sử dụng protoc với một plugin gRPC đặc biệt để sinh ra mã

(code) từ proto file: ta nhận được mã đã được sinh ra đó từ gRPC client và

Trang 10

server cũng như mã protocol buffer thông thường để điền (populate), tuần tự hóa và truy xuất các loại message của mình [3]

*Bài toán thực tế

Chúng ta đang cần gửi con số int: 300 qua socket, ồ thật đơn giản chỉ cần gửi

4 bytes:

Như thế này đi thôi đúng không? Nhưng nhìn lại 1 chút, có cái gì đó không ổn

ở đây? hình như thừa 2 số 0 ở đầu? Đúng vậy, chúng ta không cần thiết phải dùng đến 4 bytes để mô tả số 300, chúng ta chỉ cần dùng tối đa 2 bytes là 1

và 44 là đủ

Ồ, nhưng trong thực tế chẳng bao giờ chúng ta lại đi gửi 1 con số 300 vô nghĩa qua socket cả, thường thì chúng ta sẽ gửi một message kiểu:

Ý nghĩa ở đây là: trừ 100đ trong tài khoản của user có id là 300 Vậy thì phải

mô tả cái message này kiểu gì giờ? Nếu mà để kiểu

Lúc đọc chúng ta sẽ hiểu nhầm là số 76900, phải cần một cái gì đó thể phân tách ra được thành 2 số 300 và 100 Lúc này một kĩ sư đã có ý tưởng và Protobuf ra đời

*Ý tưởng ban đầu

Ý tưởng của protobuf rất đơn giản, đó là sử dụng 1 bit đầu tiên của 1 byte

để đánh dấu rằng có dữ liệu ở byte tiếp theo không, nghĩa là cứ 1 byte,

chúng ta lại mất 1 bit để để đánh dấu và chỉ có 7 bit cho phần dữ liệu mà thôi Ồ vậy đối với kiểu dữ liệu string thì sao, cứ mỗi 1 byte cũng lại mất 1 bit à? Không phải, đối với từng kiểu dữ liệu lại có đối ứng khác nhau:

1 Đối với kiểu dữ liệu số nguyên (int, long): có thể mỗi byte sẽ cần mất 1bit

2 Đối với kiểu dữ liệu kiểu string: phần độ dài của string (int) có thể mỗi byte sẽ cần mất 1 bit, còn phần nội dung sẽ được dữ nguyên

3 Đối với kiểu dữ liệu mảng (array, list) hay map: phần size int) có thể mỗi byte sẽ cần mất 1 bit, còn phần nội dung sẽ tuần theo 1 và 2

*Cơ chế hoạt động

Ví dụ con số 300 sẽ có dãy bit là: 100101100, viết ở dạng 2 byte sẽ là:

9

Trang 11

Viết ở dạng 7 bit chúng ta có:

Đảo ngược lại chúng ta có:

Chúng ta có thể thấy dãy bit có 2 phần, vậy ta sẽ bổ sung bit 1 vào 7 bit đầu (đánh dấu là có dữ liệu ở phía sau), và bit 0 vào 7 bit cuối (không còn dữ liệu

ở phía sau nữa), và chúng ta có

*file.proto

Chúng ta có thể thấy, protobuf chỉ đơn thuần là các byte[] nằm cạnh nhau, và

nó chẳng thể nào biết kiểu dữ liệu là gì để mà parse ra, chính vì vậy mà nó cần file.proto để định nghĩa kiểu Ví dụ chúng ta có file proto:

Để đọc được mảng byte [2, 172, 2, 100] ra thành đối tượng:

● Bước 1: khởi tạo đối tượng UpdateUserMoney obj = new

UpdateUserMoney()

● Bước 2: đọc byte đầu tiên là 2 chúng ta thấy 2 được biểu diễn dưới dạng bit là 00000010 vậy không có thêm byte nào tiếp theo, giá trị chúng ta nhận được sẽ là 2, vậy đối tượng của chúng ta sẽ có 2 trường

● Bước 3: đọc byte 172 dưới dạng bit 10101100 chúng ta thấy có bit 1 ở đầu, vậy cần phải đọc tiếp, trước khi đọc tiếp bỏ số 1 đi, lưu lại 7

bit 0101100

● Bước 4: đọc bye 2 dưới dạng bit 00000010 chúng không thấy có bit 1 ởđầu, vậy dừng lại việc đọc

Trang 12

● Bước 5: ghép 2 dãy bít ta được 00000010 0101100, đọc thành số ta được 300

● Bước 6: gán 300 vào userId: `obj.setUserId(300)

● Bước 7: Đọc 100 thành bit chúng ta có 01100100, không có bit 1 ở đầu vậy chúng ta có giá trị 100

● Bước 8: set 100 vào balance: obj.setBalance(100)

● Bước 9: không còn byte nào nữa kết thục tại đây và trả về obj

Protobuf cũng cho phép chúng ta chưa cần thiết phải parse ra kiểu cụ thể, chúng ta có thể đọc ra giá trị ở runtime, bằng cách thêm optional khi khai báotrường dữ liệu:

[4]

4 Lợi ích của việc sử dụng P rotocol buffer là gì?

Protocol buffer thức là lý tưởng cho mọi tình huống mà bạn cần tuần tự hóa dữ liệu đã nhập, có cấu trúc, giống như bản ghi theo cách trung lập về ngôn ngữ, trung lập với nền tảng và có thể mở rộng Chúng thường được sử dụng để xác định các giao thức truyền thông (cùng với gRPC) và để lưu trữ

dữ liệu

Một số ưu điểm của việc sử dụng Protocol buffer bao gồm:

-Lưu trữ dữ liệu nhỏ gọn

-phân tích cú pháp nhanh

-Có sẵn trong nhiều ngôn ngữ lập trình

-Chức năng được tối ưu hóa thông qua các lớp được tạo tự động

5 Khi nào Protocol buffer không phù hợp?

Protocol buffer có xu hướng giả định rằng toàn bộ thông báo có thể được tải vào bộ nhớ cùng một lúc và không lớn hơn biểu đồ đối tượng Đối với dữ liệu vượt quá vài megabyte, hãy xem xét một giải pháp khác; khi làm việc với dữ liệu lớn hơn, bạn có thể kết thúc với một số bản sao dữ liệu do cácbản sao được đánh số thứ tự, điều này có thể gây ra mức tăng đột biến đáng ngạc nhiên trong việc sử dụng bộ nhớ

11

Trang 13

Khi Protocol bufferc được tuần tự hóa, cùng một dữ liệu có thể có nhiều tuần tự hóa nhị phân khác nhau Bạn không thể so sánh hai thông báo bằng nhau mà không phân tích cú pháp đầy đủ của chúng.

Messages không được nén Mặc dù thư có thể được nén hoặc gzip giống như bất kì tệp nào khác, nhưng các thuật toán nén có mục đích đặc biệt như thuật toán được sử dụng bởi JPEG và PNG sẽ tạo ra các tệp nhỏ hơn nhiều cho dữ liệu thuộc loại thích hợp

Thông báo Protocol buffer kém hiệu quả tối đa cả về kích thước và tốc

độ đối với nhiều mục đích sử dụng khoa học và kĩ thuật liên quan đến các mảng số dấu phẩy động lớn, đa chiều Đối với các ứng dụng này, FITS và các định dạng tương tự có ít chi phí hơn

Protocol buffer không được hỗ trợ tốt trong các ngôn ngữ không hướngđối tượng phổ biến trong điện toán khoa học, chẳng hạn như Fortran và IDL

Protocol buffer messages vốn không tự mô tả dữ liệu của chúng, nhưngchúng có lược đồ phản ánh đầy đủ mà bạn có thể sử dụng để triển khai tự

mô tả Nghĩa là, bạn không thể giải thích đầy đủ một cái mà không có quyền truy cập vào tệp proto tương ứng của nó

Protocol buffer không phải là tiêu chuẩn chính thức của bất kì tổ chức nào Điều này làm cho chúng không phù hợp để sử dụng trong môi trường cóyêu cầu pháp lý hoặc các yêu cầu khác để xây dựng dựa trên tiêu chuẩn

6 Protobuf so sánh một số định dạng kiểu dữ liệu khác.

Dưới đây chúng ta sẽ đề cập đến ưu và nhược điểm của Protocol buffer và một số kiểu khác

10 lần so với XML hoặc JSON

–Không dành cho con người vì

–Con người có thể đọc và chỉnh sửa

dễ dàng

–Có thể phân tích cúpháp mà không cầnbiết lược đồ

–Các trình duyệt được hỗ trợ rất tốt

–Ít dài dòng hơn

– Con người có thể đọc

và chỉnh sửa dễ dàng

– Có thể phân tích cú pháp mà không cần biết lược đồ

– Tiêu chuẩn cho SOAP…

– Hỗ trợ tốt các công cụnhư xsd, xslt, sax,

Trang 14

nó là Binary.

–Tạo mã truy cập dữ liệu dễ

sử dụng hơn theo chương

trình

Protobuf rất nhanh nhưng nhưng nhưng có những những tình huống chúng takhông nên sử dụng nó Ví dụ như các tình huống dưới đây

1 Khi bạn cần hoặc muốn dữ liệu con người có thể đọc dễ dàng

2 Dữ liệu từ Service được sử dụng trực tiếp bởi Browser

3 Server của bạn viết bằng ngôn ngư khác như Javascript

4 Gánh nặng hoạt động của việc vận hành một loại dịch vụ mạng khác là quá lớn [1]

6.1 Sự khác biệt giữa định dạng Protobuf và JSON là gì?

– Protobuf là định dạng trao đổi dữ liệu nhị phân do Google phát triển, trong khi JSON là định dạng trao đổi dữ liệu mà con người có thể đọc được JSON có nguồn gốc từ JavaScript nhưng như tên gợi ý, nó không chỉ giới hạn ở

JavaScript Nó được thiết kế theo cách có thể được sử dụng bằng nhiều ngôn ngữ

– Protobuf hỗ trợ định dạng tuần tự hóa nhị phân, trong khi JSON dành cho định dạng tuần tự hóa văn bản đơn giản

– JSON hữu ích cho các tác vụ thông thường và chỉ giới hạn ở một số loại dữ liệu nhất định Điều đó có nghĩa là JSON không thể tuần tự hóa và hủy tuần tự hóa mọi đối tượng python Trong khi Protobuf bao gồm nhiều loại dữ liệu khi so sánh

13

Ngày đăng: 13/12/2023, 09:43

Nguồn tham khảo

Tài liệu tham khảo Loại Chi tiết
[1] C. t. tung, “VIBLO,” [Trực tuyến]. Available: https://viblo.asia/p/protocol-buffers-la-gi-va-nhung-dieu-can-ban-can-biet-ve-no-maGK7D99Zj2 Sách, tạp chí
Tiêu đề: VIBLO
[2] “appmaster,” [Trực tuyến]. Available: https://appmaster.io/vi/blog/protobuf-la-gi Sách, tạp chí
Tiêu đề: appmaster
[3] “Protocol Buffers Documentation,” [Trực tuyến]. Available: https://protobuf.dev/overview/?fbclid=IwAR0pymBBVoAyCQifyfFu_-vKBSZTnXpVdiHH5SDQw0x9qNrIg7cva_4mFgo#common-types Sách, tạp chí
Tiêu đề: Protocol Buffers Documentation
[4] “grpc,” [Trực tuyến]. Available: https://grpc.io/docs/what-is-grpc/introduction/ Sách, tạp chí
Tiêu đề: grpc
[5] “tvd,” [Trực tuyến]. Available: https://tvd12.com/protobuf/ Sách, tạp chí
Tiêu đề: tvd

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

🧩 Sản phẩm bạn có thể quan tâm

w