我正在运行一个链码应用程序,它基本上返回许多历史版本(针对一系列键的 getHistoryForKey )。我在插入账本的 300 万个键:值对上运行该链代码。我正在使用 HLF 2.3.3。
链码执行失败并出现以下错误:
[fabsdk/core] 2023/08/16 03:22:32 UTC - cryptosuite.GetDefault -> INFO No default cryptosuite found, using default SW implementation
[fabsdk/fab] 2023/08/16 03:25:29 UTC - peer.(*peerEndorser).sendProposal -> ERRO process proposal failed [rpc error: code = ResourceExhausted desc = grpc: received message larger than max (122477059 vs. 104857600)]
[fabsdk/fab] 2023/08/16 03:25:30 UTC - peer.(*peerEndorser).sendProposal -> ERRO process proposal failed [rpc error: code = ResourceExhausted desc = grpc: received message larger than max (122477059 vs. 104857600)]
2023/08/15 21:25:30 Failed to evaluate transaction: Failed to evaluate: Multiple errors occurred: - Transaction processing for endorser [localhost:9051]: gRPC Transport Status Code: (8) ResourceExhausted. Description: grpc: received message larger than max (122477059 vs. 104857600) - Transaction processing for endorser [localhost:7051]: gRPC Transport Status Code: (8) ResourceExhausted. Description: grpc: received message larger than max (122477059 vs. 104857600)
exit status 1
我相信会发生这种情况是因为查询结果超过 100Mb。我应该改变什么才能使其真正发挥作用?有 core.yaml、configtx.yaml 等文件,我该如何修改它们以更改 100MB 限制?
此外,如果我尝试执行相同的链码查询,但对于插入的 400 万个键:值对,链码执行在执行大约 180 秒后会因超时错误而中断。如何修复/更改超时?
gRPC 并不是为非常大的消息大小而设计的。在定制应用程序中,您可以使用 gRPC 服务器流将较大的数据集作为一系列较小的消息流式传输回客户端 - 这实际上是在 Fabric 中实现块和链码事件的方式 - 但 Fabric 使用简单的请求/响应消息传递进行事务调用,所以这不是这里的一个选项。
我认为您可以采取两种明显的方法:
为了减少数据大小,您可以考虑让单个事务调用仅对数据的子集进行操作。要取回所有数据,客户端需要多次调用事务函数,每次都提供参数来指示要检索数据(或结果)的哪一部分。
如果您必须一次性处理数据,或者可能需要一种性能更高的机制来索引和处理大部分账本数据,您可以使用链下数据存储。由于这是您自己的数据存储,保存账本数据的副本,因此您可以使用适合您的用例的任何工具来存储和访问数据。请参阅 off_chain_data 示例,了解如何使用区块事件来构建和维护链下数据存储的示例。