Sổ cái phân tán cho xe lăn: Trải nghiệm với Hyperledger Fabric

Xin chào, tôi làm việc trong nhóm của dự án DRD KP (đăng ký dữ liệu phân tán để theo dõi vòng đời của bộ bánh xe). Ở đây tôi muốn chia sẻ kinh nghiệm của nhóm chúng tôi trong việc phát triển chuỗi khối doanh nghiệp cho dự án này trong điều kiện hạn chế về công nghệ. Tôi chủ yếu sẽ nói về Hyperledger Fabric, nhưng cách tiếp cận được mô tả ở đây có thể được ngoại suy cho bất kỳ chuỗi khối được cấp phép nào. Mục tiêu cuối cùng trong nghiên cứu của chúng tôi là chuẩn bị các giải pháp blockchain dành cho doanh nghiệp để sản phẩm cuối cùng dễ sử dụng và không quá khó bảo trì.

Sẽ không có khám phá, giải pháp bất ngờ nào và không có sự phát triển độc đáo nào được nêu bật ở đây (vì tôi không có cái nào cả). Tôi chỉ muốn chia sẻ kinh nghiệm khiêm tốn của mình, chứng tỏ rằng “điều đó là có thể” và có lẽ, đọc về kinh nghiệm của người khác trong việc đưa ra những quyết định tốt và không quá tốt trong các nhận xét.

Vấn đề: Blockchain chưa mở rộng quy mô

Ngày nay, nỗ lực của nhiều nhà phát triển đều nhằm mục đích biến blockchain thành một công nghệ thực sự tiện lợi chứ không phải là một quả bom hẹn giờ được gói gọn trong một lớp vỏ đẹp đẽ. Các kênh trạng thái, tổng hợp lạc quan, plasma và sharding có thể sẽ trở nên phổ biến. Một ngày nào đó. Hoặc có lẽ TON sẽ lại hoãn việc ra mắt trong sáu tháng và Nhóm Plasma tiếp theo sẽ không còn tồn tại. Chúng ta có thể tin vào lộ trình tiếp theo và đọc các sách trắng tuyệt vời vào ban đêm, nhưng ở đây và bây giờ chúng ta cần phải làm gì đó với những gì chúng ta có. Hãy hoàn thành công việc đi.

Nhiệm vụ đặt ra cho nhóm của chúng tôi trong dự án hiện tại nhìn chung như thế này: có nhiều đối tượng, tiếp cận hàng nghìn người, không muốn xây dựng mối quan hệ dựa trên sự tin cậy; Cần phải xây dựng một giải pháp trên DLT có thể hoạt động trên PC thông thường mà không có yêu cầu đặc biệt về hiệu suất và cung cấp trải nghiệm người dùng không thua kém bất kỳ hệ thống kế toán tập trung nào. Công nghệ đằng sau giải pháp phải giảm thiểu khả năng thao túng dữ liệu một cách độc hại - đó là lý do tại sao blockchain lại xuất hiện.

Những khẩu hiệu từ sách trắng và các phương tiện truyền thông hứa hẹn với chúng ta rằng sự phát triển tiếp theo sẽ cho phép chúng ta thực hiện hàng triệu giao dịch mỗi giây. Nó thực sự là gì?

Mainnet Ethereum hiện đang chạy ở tốc độ ~30 tps. Chỉ vì điều này mà khó có thể coi nó là blockchain theo bất kỳ cách nào phù hợp với nhu cầu của công ty. Trong số các giải pháp được cấp phép, có điểm chuẩn hiển thị 2000 tps (Quorum) hoặc 3000 giao dịch/giây (Vải Hyperledger, có ít hơn một chút trong ấn phẩm, nhưng bạn cần tính đến việc điểm chuẩn được thực hiện trên công cụ đồng thuận cũ). Đã từng là một nỗ lực xử lý vải triệt để, không mang lại kết quả tệ nhất, 20000 tps, nhưng cho đến nay đây chỉ là nghiên cứu học thuật, chờ triển khai ổn định. Khó có khả năng một tập đoàn có đủ khả năng để duy trì một bộ phận gồm các nhà phát triển blockchain sẽ đưa ra những chỉ số như vậy. Nhưng vấn đề không chỉ ở thông lượng mà còn ở độ trễ.

Độ trễ

Độ trễ từ thời điểm giao dịch được bắt đầu đến khi hệ thống phê duyệt cuối cùng không chỉ phụ thuộc vào tốc độ thông báo đi qua tất cả các giai đoạn xác thực và đặt hàng mà còn phụ thuộc vào các tham số hình thành khối. Ngay cả khi blockchain của chúng tôi cho phép chúng tôi cam kết ở tốc độ 1000000 tps, nhưng cần 10 phút để tạo khối 488 MB, liệu điều đó có trở nên dễ dàng hơn cho chúng tôi không?

Chúng ta hãy xem xét kỹ hơn vòng đời giao dịch trong Hyperledger Fabric để hiểu thời gian được sử dụng vào đâu và nó liên quan như thế nào đến các tham số tạo khối.

Sổ cái phân tán cho xe lăn: Trải nghiệm với Hyperledger Fabric
lấy từ đây: hyperledger-fabric.readthedocs.io/en/release-1.4/arch-deep-dive.html#swimlane

(1) Khách hàng tạo một giao dịch, gửi nó đến các đồng nghiệp chứng thực, sau đó mô phỏng giao dịch (áp dụng các thay đổi do mã chuỗi thực hiện cho trạng thái hiện tại, nhưng không cam kết với sổ cái) và nhận RWSet - tên khóa, phiên bản và giá trị ​​lấy từ bộ sưu tập trong CouchDB, (2) người chứng thực gửi lại RWSet đã ký cho khách hàng, (3) khách hàng kiểm tra sự hiện diện chữ ký của tất cả các đồng nghiệp cần thiết (người chứng thực), sau đó gửi giao dịch đến dịch vụ đặt hàng , hoặc gửi mà không xác minh (việc kiểm tra vẫn sẽ diễn ra sau), dịch vụ đặt hàng sẽ tạo thành một khối và ( 4) gửi lại cho tất cả các bên ngang hàng, không chỉ người chứng thực; các đồng nghiệp kiểm tra xem các phiên bản chính trong tập đọc có khớp với các phiên bản trong cơ sở dữ liệu hay không, tất cả những người xác nhận đều có chữ ký và cuối cùng cam kết chặn.

Nhưng đó không phải là tất cả. Dòng chữ “người đặt hàng tạo thành một khối” không chỉ ẩn giấu thứ tự giao dịch mà còn ẩn chứa 3 yêu cầu mạng tuần tự từ người đứng đầu đến người theo dõi và ngược lại: người đứng đầu thêm một tin nhắn vào nhật ký, gửi cho người theo dõi, người sau thêm nó vào vào nhật ký của họ, gửi xác nhận sao chép thành công cho người lãnh đạo, người lãnh đạo cam kết tin nhắn, gửi xác nhận cam kết cho người theo dõi, người theo dõi cam kết. Kích thước và thời gian hình thành khối càng nhỏ thì dịch vụ đặt hàng sẽ phải thiết lập sự đồng thuận thường xuyên hơn. Hyperledger Fabric có hai tham số để hình thành khối: BatchTimeout - thời gian hình thành khối và BatchSize - kích thước khối (số lượng giao dịch và kích thước của chính khối tính bằng byte). Ngay khi một trong các tham số đạt đến giới hạn, một khối mới sẽ được giải phóng. Càng nhiều nút đặt hàng, việc này sẽ càng mất nhiều thời gian. Vì vậy, bạn cần tăng BatchTimeout và BatchSize. Nhưng vì RWSets được lập phiên bản nên khối chúng ta tạo ra càng lớn thì khả năng xảy ra xung đột MVCC càng cao. Ngoài ra, khi BatchTimeout tăng lên, UX sẽ xuống cấp nghiêm trọng. Sơ đồ sau đây để giải quyết những vấn đề này có vẻ hợp lý và rõ ràng đối với tôi.

Làm thế nào để tránh phải chờ hoàn thiện khối và không mất khả năng theo dõi trạng thái giao dịch

Thời gian hình thành và kích thước khối càng dài thì thông lượng của blockchain càng cao. Một bên không trực tiếp theo dõi bên kia, nhưng cần nhớ rằng việc thiết lập sự đồng thuận trong RAFT yêu cầu ba yêu cầu mạng từ người dẫn đầu đến những người theo dõi và ngược lại. Càng nhiều nút đặt hàng, việc này sẽ càng mất nhiều thời gian. Kích thước và thời gian hình thành khối càng nhỏ thì càng có nhiều tương tác như vậy. Làm cách nào để tăng thời gian tạo và kích thước khối mà không tăng thời gian phản hồi của hệ thống cho người dùng cuối?

Trước tiên, chúng ta cần giải quyết bằng cách nào đó xung đột MVCC do kích thước khối lớn gây ra, có thể bao gồm các RWSets khác nhau có cùng phiên bản. Rõ ràng, về phía khách hàng (liên quan đến mạng blockchain, đây cũng có thể là phần phụ trợ và ý tôi là vậy) bạn cần Trình xử lý xung đột MVCC, có thể là một dịch vụ riêng biệt hoặc một trình trang trí thông thường phía trên lệnh gọi bắt đầu giao dịch bằng logic thử lại.

Việc thử lại có thể được thực hiện bằng chiến lược theo cấp số nhân, nhưng sau đó độ trễ sẽ giảm theo cấp số nhân. Vì vậy, bạn nên sử dụng thử lại ngẫu nhiên trong các giới hạn nhỏ nhất định hoặc một giới hạn không đổi. Để mắt đến những va chạm có thể xảy ra trong tùy chọn đầu tiên.

Bước tiếp theo là làm cho tương tác của máy khách với hệ thống không đồng bộ để nó không phải đợi 15, 30 hoặc 10000000 giây mà chúng tôi sẽ đặt là BatchTimeout. Nhưng đồng thời, cần duy trì khả năng xác minh rằng những thay đổi do giao dịch bắt đầu có/không được ghi lại trong blockchain hay không.
Một cơ sở dữ liệu có thể được sử dụng để lưu trữ trạng thái giao dịch. Tùy chọn đơn giản nhất là CouchDB do tính dễ sử dụng: cơ sở dữ liệu có giao diện người dùng sẵn có, API REST và bạn có thể dễ dàng thiết lập sao chép và phân chia cho nó. Bạn có thể chỉ cần tạo một bộ sưu tập riêng trong cùng một phiên bản CouchDB sử dụng Fabric để lưu trữ trạng thái thế giới của nó. Chúng ta cần lưu trữ những loại tài liệu này.

{
 Status string // Статус транзакции: "pending", "done", "failed"
 TxID: string // ID транзакции
 Error: string // optional, сообщение об ошибке
}

Tài liệu này được ghi vào cơ sở dữ liệu trước khi giao dịch được gửi đến các đồng nghiệp, ID thực thể được trả về cho người dùng (cùng một ID được sử dụng làm khóa) nếu đây là thao tác tạo và sau đó các trường Trạng thái, TxID và Lỗi sẽ được được cập nhật khi nhận được thông tin liên quan từ các đồng nghiệp.

Sổ cái phân tán cho xe lăn: Trải nghiệm với Hyperledger Fabric

Trong sơ đồ này, người dùng không đợi khối hình thành cuối cùng, quan sát bánh xe quay trên màn hình trong 10 giây, anh ta sẽ nhận được phản hồi ngay lập tức từ hệ thống và tiếp tục làm việc.

Chúng tôi chọn BoltDB để lưu trữ trạng thái giao dịch vì chúng tôi cần tiết kiệm bộ nhớ và không muốn lãng phí thời gian tương tác mạng với một máy chủ cơ sở dữ liệu riêng biệt, đặc biệt khi tương tác này xảy ra bằng giao thức văn bản thuần túy. Nhân tiện, cho dù bạn sử dụng CouchDB để triển khai sơ đồ được mô tả ở trên hay chỉ đơn giản là để lưu trữ trạng thái thế giới, thì trong mọi trường hợp, việc tối ưu hóa cách lưu trữ dữ liệu trong CouchDB là điều hợp lý. Theo mặc định, trong CouchDB, kích thước của các nút cây b là 1279 byte, nhỏ hơn nhiều so với kích thước cung trên đĩa, nghĩa là cả việc đọc và cân bằng lại cây sẽ yêu cầu nhiều quyền truy cập vật lý hơn vào đĩa. Kích thước tối ưu tương ứng với tiêu chuẩn Định dạng nâng cao và là 4 kilobyte. Để tối ưu chúng ta cần thiết lập tham số btree_chunk_size bằng 4096 trong tệp cấu hình CouchDB. Đối với BoltDB sự can thiệp thủ công như vậy không yêu cầu.

Áp lực ngược: chiến lược đệm

Nhưng có thể có rất nhiều tin nhắn. Nhiều hơn những gì hệ thống có thể xử lý, chia sẻ tài nguyên với hàng tá dịch vụ khác ngoài những dịch vụ được hiển thị trong sơ đồ - và tất cả điều này sẽ hoạt động hoàn hảo ngay cả trên các máy chạy Intellij Idea sẽ cực kỳ tẻ nhạt.

Vấn đề về năng lực khác nhau của các hệ thống truyền thông, nhà sản xuất và người tiêu dùng, được giải quyết theo những cách khác nhau. Hãy xem chúng ta có thể làm gì.

Rơi: Chúng tôi có thể khẳng định rằng chúng tôi có khả năng xử lý tối đa X giao dịch trong T giây. Tất cả các yêu cầu vượt quá giới hạn này đều bị loại bỏ. Điều này khá đơn giản, nhưng bạn có thể quên UX đi.

Kiểm soát: người tiêu dùng phải có một số loại giao diện mà qua đó, tùy thuộc vào tải, anh ta có thể kiểm soát TPS của nhà sản xuất. Không tệ, nhưng nó áp đặt nghĩa vụ đối với các nhà phát triển ứng dụng khách khi tạo tải để triển khai giao diện này. Điều này là không thể chấp nhận được đối với chúng tôi, vì blockchain trong tương lai sẽ được tích hợp vào một số lượng lớn các hệ thống tồn tại lâu dài.

Bộ đệm: Thay vì cố gắng chống lại luồng dữ liệu đầu vào, chúng ta có thể đệm luồng này và xử lý nó ở tốc độ yêu cầu. Rõ ràng đây là giải pháp tốt nhất nếu chúng ta muốn mang lại trải nghiệm tốt cho người dùng. Chúng tôi đã triển khai bộ đệm bằng hàng đợi trong RabbitMQ.

Sổ cái phân tán cho xe lăn: Trải nghiệm với Hyperledger Fabric

Hai hành động mới đã được thêm vào lược đồ: (1) sau khi có yêu cầu API đến, một thông báo có các tham số cần thiết để gọi một giao dịch sẽ được đặt vào hàng đợi và khách hàng nhận được thông báo rằng giao dịch đã được chấp nhận bởi hệ thống, (2) phần phụ trợ đọc dữ liệu ở tốc độ được chỉ định trong cấu hình từ hàng đợi; bắt đầu một giao dịch và cập nhật dữ liệu trong kho trạng thái.
Giờ đây, bạn có thể tăng thời gian hình thành và dung lượng khối theo ý muốn, ẩn sự chậm trễ với người dùng.

Các công cụ khác

Không có gì được nói ở đây về chaincode, bởi vì, theo quy luật, không có gì để tối ưu hóa trong đó. Chuỗi mã phải đơn giản và an toàn nhất có thể - đó là tất cả những gì được yêu cầu. Framework giúp chúng ta viết chaincode đơn giản và an toàn CCKit từ S7 Techlab và máy phân tích tĩnh hồi sinh^CC.

Ngoài ra, nhóm của chúng tôi đang phát triển một bộ tiện ích giúp làm việc với Fabric trở nên đơn giản và thú vị: nhà thám hiểm blockchain, một tiện ích dành cho thay đổi cấu hình mạng tự động (thêm/xóa tổ chức, nút RAFT), tiện ích cho thu hồi chứng chỉ và xóa danh tính. Nếu bạn muốn đóng góp, bạn đều được chào đón.

Kết luận

Cách tiếp cận này cho phép bạn dễ dàng thay thế Hyperledger Fabric bằng Quorum, các mạng Ethereum riêng khác (PoA hoặc thậm chí PoW), giảm đáng kể thông lượng thực tế, nhưng đồng thời duy trì UX bình thường (cho cả người dùng trong trình duyệt và hệ thống tích hợp). Khi thay thế Fabric bằng Ethereum trong sơ đồ, bạn sẽ chỉ cần thay đổi logic của dịch vụ/trang trí thử lại từ việc xử lý xung đột MVCC sang tăng số nguyên tử và gửi lại. Bộ đệm và lưu trữ trạng thái giúp tách thời gian phản hồi khỏi thời gian hình thành khối. Giờ đây, bạn có thể thêm hàng nghìn nút đặt hàng mà không sợ các khối được hình thành quá thường xuyên và tải dịch vụ đặt hàng.

Về cơ bản, đó là tất cả những gì tôi muốn chia sẻ. Tôi sẽ rất vui nếu điều này giúp được ai đó trong công việc của họ.

Nguồn: www.habr.com

Thêm một lời nhận xét