node.jshyperledger-fabricblockchainhyperledgerhyperledger-fabric-ca

Network Configuration to achieve high throughput in HyperLedger Fabric


I have improvised fabcar example of hyperledger fabric samples and build my express application over it. But according to my use case, I need at least 100-200 Tps but currently getting around 3.5 seconds for an insert operation. Looking for a network configuration that can help me achieve the desired throughput. :) Written my chaincode in javascript and using CouchDB as world state database. My system config: i5-6th Gen 16GB Ram Arch: x86


Solution

  • Submitting transactions serially will yield very low performance as, for each transaction, the orderer will wait a while in case more transactions arrive before cutting block and distributing to peers. Your client is also waiting for the block to be cut, distributed to peers, and to receive confirmation of a successful ledger update before starting on the next transaction. To drive any kind of transaction rate, you need to be submitting transactions in parallel. This results in less waiting and more transactions included in each block.

    Just as a point of reference, I used the asset-transfer-basic sample chaincode and a simple Node client application that ran 1000 Promises in parallel, each sequentially submitting 10 CreateAsset transactions. Running on a 7 year-old (mid-2015) Macbook hosting both the client and Fabric network in Docker containers, I got these results:

    10000 transactions in 70.969 seconds
    Transaction rate: 141 / second
    

    Your data model and workload pattern are real factors as two transactions in flight that modify overlapping ledger keys may cause transactions to fail due to MVCC read conflicts, which may really hurt your throughput.

    You might want to experiment with different chaincode languages as that might impact performance. You may also be able to significantly affect performance by "batching" multiple updates into a single Fabric transaction, although there may a tradeoff here with the chance of a MVCC read conflict and the amount of work that would be rejected.

    Another approach that likely will be more difficult to manage but might help in some circumstances is not to block waiting for transaction commit status after a submit, and check for commit status (and deal with any recovery from rejected transactions) asynchronously.