在現有Fabric網路上設定和運行Caliper性能基準測驗
- 1.概述
- 2.步驟1-創建Caliper作業區
- 3.步驟2-構建網路組態檔
- 創建模板網路組態檔
- 填充模板檔案
- 完整的網路組態檔
- 4.步驟3-構建測驗作業負載模塊
- 創建模板作業負載模塊
- 填充模板檔案
- 完整作業負載模塊
- 5.步驟4-構建基準組態檔
- 創建模板基準組態檔
- 填充模板檔案
- 6.第5步-運行Caliper基準測驗
此檔案是官方的操作檔案, 實戰請參考 這篇博客,
1.概述
本教程將帶您完成在預先存在的Fabric網路上使用Caliper對智能合約進行性能測驗,
要完成本教程,您需要安裝NodeJS,為此,我們建議使用nvm,
本教程基于官方Hyperledger Fabric檔案中提供的資源,假設一個由兩個組織和一個單獨排序者組成的網路,具有asset-transfer-basic的javascript智能合約,假定已經建立并準備好進行性能測驗,
下面的命令串列是一個最簡單的快速步驟指南,用于啟動和運行所需的Fabric網路,我們在顯式級別使用可用的Hyperledger Fabric資源,要了解并排除創建測驗網路期間發生的情況,請參閱上面鏈接的Fabric檔案!
# 克隆Hyperledger Fabric samples repo的固定版本
git clone https://github.com/hyperledger/fabric-samples.git
cd fabric-samples
git checkout 22393b629bcac7f7807cc6998aa44e06ecc77426
# 安裝Fabric工具并將其添加到PATH
curl -sSL https://bit.ly/2ysbOFE | bash -s -- 2.2.0 1.4.8 -s
export PATH=$PATH:$(pwd)/bin
# 創建并初始化網路
cd test-network
./network.sh up createChannel
./network.sh deployCC -ccn basic -ccl javascript
2.步驟1-創建Caliper作業區
在fabric-samples目錄的同一級別創建一個名為caliper-workspace的檔案夾,然后在caliper-workspace檔案夾中,分別創建三個名為networks、benchmarks和workload的檔案夾
Caliper的安裝和使用將基于當地的npm安裝,在caliper-workspace目錄中,使用以下終端命令安裝caliper CLI:
npm install --only=prod @hyperledger/caliper-cli@0.4.0
使用以下終端命令系結SDK:
npx caliper bind --caliper-bind-sut fabric:2.1
有關Caliper安裝和捆綁的更多資訊,請參見相關檔案頁,
Caliper需要兩個組態檔:
- 網路組態檔,它描述被測網路并提供要使用的測驗標識,
- 基準檔案,它定義了要通過一組有序的測驗回圈來完成的性能測驗,每個測驗輪都指定了一個作業負載模塊和一系列選項,以在一個時間間隔內驅動作業負載,
現在我們將用Caliper所需的資源填充這些檔案夾,
3.步驟2-構建網路組態檔
網路組態檔是Caliper作業人員創建到現有Fabric網路的連接所需的檔案,以便他們可以提交交易,它類似于Fabric公共連接組態檔,并添加了其他必需欄位,檔案可以是YAML或JSON格式,本教程顯示JSON格式,
創建模板網路組態檔
在“networks”檔案夾下創建一個名為networkConfig.json包括以下內容:
{
"version" : "1.0",
"name": "Caliper test",
"caliper" : {
"blockchain": "fabric"
},
"clients" : {
},
"channels" : {
},
"organizations" : {
},
"peers" : {
}
}
版本:正在使用的組態檔的版本,只接受“1.0”,
名稱:配置的名稱,在本例中為“Caliper測驗”,
Caliper:指示對目標的SUT進行Caliper,可能包含本教程中不需要的其他開始/結束命令,在本教程中,我們以Fabric網路為目標,
客戶端:列出要在性能測驗中使用的標識
通道:描述可用的Hyperledger Fabric通道、它們的狀態以及在這些通道上部署的智能合約
組織:要在基準測驗中使用的超級賬本Fabric組織
節點:要在基準測驗中使用的Hyperledger Fabric節點
填充模板檔案
在測驗網路教程之后,將生成一個公共連接組態檔(CCP);我們將使用此檔案幫助填充Caliper網路組態檔的特定于Hyperledger Fabric的元素,模板將為所創建的Hyperledger Fabric網路提供一些唯一的證書,因此您將注意到后續階段中顯示的內容的差異;您必須使用為與您希望目標的測驗網路進行互動而創建的證書,
在本例中,我們將使用Org1進行連接,要查找生成的JSON或yamlccp檔案,請查看fabric-samples -> test-network -> organizations -> peerOrganizations -> org1.example.com, 我們假設使用json CCP connection-org1.json,
組織和同行
使用CCP的內容進行填充:
將CCP的organizations和peers元素復制到Caliper網路組態檔中,
在organizations.Org1物件,洗掉certificateAuthorities串列,這樣做有兩個原因:
i) 我們不會使用證書頒發機構注冊或注冊
ii)向CCP提交的變更與組態檔中的驗證Caliper不兼容,
Caliper網路組態檔現在應該類似于:
{
"version" : "1.0",
"name": "Caliper test",
"caliper" : {
"blockchain": "fabric"
},
"clients" : {
},
"channels" : {
},
"organizations": {
"Org1": {
"mspid": "Org1MSP",
"peers": [
"peer0.org1.example.com"
]
}
},
"peers": {
"peer0.org1.example.com": {
"url": "grpcs://localhost:7051",
"tlsCACerts": {
"pem": "-----BEGIN CERTIFICATE-----<UNIQUE CONTENT>-----END CERTIFICATE-----\n"
},
"grpcOptions": {
"ssl-target-name-override": "peer0.org1.example.com",
"hostnameOverride": "peer0.org1.example.com"
}
}
}
}
客戶端
指定執行基準測驗時Caliper要使用的標識,身份必須有效,這意味著它們必須為Fabric網路所知,并且具有相應的加密材料以供使用,標識在clients節中列出,這里我們使用單一身份Admin@org1.example.com,我們在其中嵌套來自CCP的client物件,以指示標識所屬的組織,并提供基本的連接超時資訊,
"clients": {
"Admin@org1.example.com": {
"client": {
"organization": "Org1",
"connection": {
"timeout": {
"peer": {
"endorser": "300"
}
}
}
}
}
}
在client物件下,添加一個名為credentialStore的屬性,在該屬性下添加一個名為path的屬性,該屬性具有一個字串變數,該變數指向作業區中名為/tmp/org1的臨時檔案,另外,在credentialStore屬性下添加一個名為cryptoStore的屬性,并在該屬性下添加另一個指向上面相同臨時檔案/tmp/org1的路徑屬性,
以下是應該添加到client的內容:
"credentialStore": {
"path": "/tmp/org1",
"cryptoStore": {
"path": "/tmp/org1"
}
}
在client物件下添加一個名為clientPrivateKey的屬性,在此屬性下添加一個名為path的屬性,該屬性具有一個字串變數,該變數指向標識的私鑰,請注意,提供的路徑是相對于作業區的,在本例中,私鑰位于fabric-samples -> test-network -> organizations -> peerOrganizations -> org1.example.com -> users -> Admin@org1.example.com -> msp -> keystore -> priv_sk,
client應添加到的物件是:
"clientPrivateKey": {
"path": "../fabric-samples/test-network/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/keystore/priv_sk"
}
另外,在client物件下添加另一個名為clientSignedCert的屬性,并在該屬性下添加一個名為path的屬性,該屬性具有一個字串變數,該變數指向標識的簽名證書,再次注意,提供的路徑是相對于作業區的,在本例中,它位于fabric-samples -> test-network -> organizations -> peerOrganizations -> org1.example.com -> users -> Admin@org1.example.com -> msp -> signedcerts -> admin@org1.example.com-cert.pem
client應添加到的物件是:
"clientSignedCert": {
"path": "../fabric-samples/test-network/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/signcerts/Admin@org1.example.com-cert.pem"
}
clients物件現在應該如下所示:
"clients": {
"Admin@org1.example.com": {
"client": {
"organization": "Org1",
"connection": {
"timeout": {
"peer": {
"endorser": "300"
}
}
},
"credentialStore": {
"path": "tmp/hfc-kvs/org1",
"cryptoStore": {
"path": "tmp/hfc-kvs/org1"
}
},
"clientPrivateKey": {
"path": "../fabric-samples/test-network/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/keystore/priv_sk"
},
"clientSignedCert": {
"path": "../fabric-samples/test-network/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/signcerts/Admin@org1.example.com-cert.pem"
}
}
}
}
通道物件
在創建與Fabric網路的連接時,Caliper的織物連接器需要幫助,必須提供一個channels物件,該物件列出可能與之互動的智能合約,
將由test-network創建的已知通道mychannel添加到Caliper網路組態檔的channels部分,并賦予它一個布林值true創建的屬性,我們必須將此通道上可用的智能合約列為名為contracts的陣列中的物件,每個智能合約物件都有兩個屬性,id和version,id指定合同ID;在本例中,它是basic,版本是特定的合同版本;在本例中是1.0.0,將其作為陣列中的一個物件添加,以使Caliper網路組態檔中的結果通道物件變為:
"channels": {
"mychannel": {
"created" : true,
"contracts": [
{
"id":"basic",
"version":"1.0.0"
}
]
}
}
完整的網路組態檔
Caliper網路組態檔現在應該完全填充,花點時間檢查并確保證書和密鑰的路徑是正確的,這是很有用的,
{
"version" : "1.0",
"name": "Caliper test",
"caliper" : {
"blockchain": "fabric"
},
"clients": {
"Admin@org1.example.com": {
"client": {
"credentialStore": {
"path": "/tmp/org1",
"cryptoStore": {
"path": "/tmp/org1"
}
},
"organization": "Org1",
"clientPrivateKey": {
"path": "../fabric-samples/test-network/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/keystore/priv_sk"
},
"clientSignedCert": {
"path": "../fabric-samples/test-network/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/signcerts/Admin@org1.example.com-cert.pem"
},
"connection": {
"timeout": {
"peer": {
"endorser": "300"
}
}
}
}
}
},
"channels": {
"mychannel": {
"created" : true,
"contracts": [
{
"id":"basic",
"version":"1.0.0"
}
]
}
},
"organizations":{
"Org1": {
"mspid": "Org1MSP",
"peers": [
"peer0.org1.example.com"
]
}
},
"peers": {
"peer0.org1.example.com": {
"url": "grpcs://localhost:7051",
"tlsCACerts": {
"pem": "-----BEGIN CERTIFICATE-----\n<UNIQUE CONTENT>\n-----END CERTIFICATE-----\n"
},
"grpcOptions": {
"ssl-target-name-override": "peer0.org1.example.com",
"hostnameOverride": "peer0.org1.example.com"
}
}
}
}
4.步驟3-構建測驗作業負載模塊
在基準測驗期間,作業負載模塊與部署的智能合約進行互動,workload模塊從Caliper-core擴展了Caliper類WorkloadModuleBase,作業負載模塊提供三個覆寫:
initializeWorkloadModule-用于初始化基準測驗所需的任何項submitTransaction-用于在基準的監視階段與智能合約方法互動cleanupWorkloadModule—用于在完成基準測驗后進行清理
有關更多資訊,請參閱左側選單上有關作業負載配置的特定檔案,
我們將推動的作業負載旨在對世界狀態資料庫中現有資產的查詢進行基準測驗,因此,我們將使用workload模塊中提供的所有三個階段:
initializeWorkloadModule-創建可在submitTransaction階段查詢的資產submitTransaction-查詢在initializeWorkloadModule階段創建的資產cleanuWorkloadModule-用于移除在initializeWorkloadModule階段創建的資產,以便可以重復基準測驗
創建模板作業負載模塊
在workload檔案夾中,創建一個名為readAsset.js的檔案,其中包含以下內容:
'use strict';
const { WorkloadModuleBase } = require('@hyperledger/caliper-core');
class MyWorkload extends WorkloadModuleBase {
constructor() {
super();
}
async initializeWorkloadModule(workerIndex, totalWorkers, roundIndex, roundArguments, sutAdapter, sutContext) {
await super.initializeWorkloadModule(workerIndex, totalWorkers, roundIndex, roundArguments, sutAdapter, sutContext);
}
async submitTransaction() {
// NOOP
}
async cleanupWorkloadModule() {
// NOOP
}
}
function createWorkloadModule() {
return new MyWorkload();
}
module.exports.createWorkloadModule = createWorkloadModule;
填充模板檔案
填充此檔案時,我們參考已部署智能合約中的可用方法資產轉讓可在以下位置找到的檔案:fabric-samples -> asset-transfer-basic -> chaincode-javascript -> lib -> assetTransfer.js
填充initializeWorkloadModule
此方法用于在基準完成時準備主submitTransaction方法所需的任何項,
要創建的資產數量將給出如下roundArguments.assets,我們通過填充arguments物件(定義交易體)和使用Caliper API sendRequests(需要了解以下知識)來創建資產:
- contractId,要使用的智能合約的名稱,它存在于Caliper網路組態檔中
- contractFunction,智能合約中要呼叫的特定函式
- contractArguments,傳遞給智能合約函式的引數
- invokerIdentity,Caliper網路組態檔中存在的要使用的標識
- readOnly,如果是否執行查詢操作
方法應該如下所示:
async initializeWorkloadModule(workerIndex, totalWorkers, roundIndex, roundArguments, sutAdapter, sutContext) {
await super.initializeWorkloadModule(workerIndex, totalWorkers, roundIndex, roundArguments, sutAdapter, sutContext);
for (let i=0; i<this.roundArguments.assets; i++) {
const assetID = `${this.workerIndex}_${i}`;
console.log(`Worker ${this.workerIndex}: Creating asset ${assetID}`);
const request = {
contractId: this.roundArguments.contractId,
contractFunction: 'CreateAsset',
invokerIdentity: 'Admin@org1.example.com',
contractArguments: [assetID,'blue','20','penguin','500'],
readOnly: false
};
await this.sutAdapter.sendRequests(request);
}
}
在上面的示例中,將創建具有相同引數的不同資產(blue,20,penguin,500),將上述內容與智能合約方法本身相比較,可以明顯看出,契約引數與方法引數之間存在1:1的映射關系,
填充submitTransaction
此方法在基準測驗階段重復運行,我們將通過查詢在initializeWorkloadModule方法中創建的資產來評估ReadAsset智能合約方法,
首先,為要查詢的資產創建一個字串標識,該標識由worker索引和一個介于0和已創建資產數量之間的隨機整數串聯而成,
然后等待對sendRequests的呼叫,傳遞一個物件,該物件包含:從round引數傳入的contractId集;設定為ReadAsset的contractFunction;設定為invokerIdentity的admin@org1.example.com;和chaincodeArguments設定為一個陣列,其中包含要在此運行中查詢的資產,
方法應該如下所示:
async submitTransaction() {
const randomId = Math.floor(Math.random()*this.roundArguments.assets);
const myArgs = {
contractId: this.roundArguments.contractId,
contractFunction: 'ReadAsset',
invokerIdentity: 'Admin@org1.example.com',
contractArguments: [`${this.workerIndex}_${randomId}`],
readOnly: true
};
await this.sutAdapter.sendRequests(myArgs);
}
填充cleanupWorkloadModule
此函式用于在測驗后進行清理,因為它通過使用智能合約函式DeleteAsset洗掉在initializeWorkloadModule函式中創建的資產,該實作類似于initializeWorkloadModule中的實作,注意可以重構initializeWorkloadModule和cleanupWorkloadModule,以使用執行創建/洗掉操作的通用方法,這將留給感興趣的讀者,
async cleanupWorkloadModule() {
for (let i=0; i<this.roundArguments.assets; i++) {
const assetID = `${this.workerIndex}_${i}`;
console.log(`Worker ${this.workerIndex}: Deleting asset ${assetID}`);
const request = {
contractId: this.roundArguments.contractId,
contractFunction: 'DeleteAsset',
invokerIdentity: 'Admin@org1.example.com',
contractArguments: [assetID],
readOnly: false
};
await this.sutAdapter.sendRequests(request);
}
}
完整作業負載模塊
現在應該完全填充測驗回呼檔案:
'use strict';
const { WorkloadModuleBase } = require('@hyperledger/caliper-core');
class MyWorkload extends WorkloadModuleBase {
constructor() {
super();
}
async initializeWorkloadModule(workerIndex, totalWorkers, roundIndex, roundArguments, sutAdapter, sutContext) {
await super.initializeWorkloadModule(workerIndex, totalWorkers, roundIndex, roundArguments, sutAdapter, sutContext);
for (let i=0; i<this.roundArguments.assets; i++) {
const assetID = `${this.workerIndex}_${i}`;
console.log(`Worker ${this.workerIndex}: Creating asset ${assetID}`);
const request = {
contractId: this.roundArguments.contractId,
contractFunction: 'CreateAsset',
invokerIdentity: 'Admin@org1.example.com',
contractArguments: [assetID,'blue','20','penguin','500'],
readOnly: false
};
await this.sutAdapter.sendRequests(request);
}
}
async submitTransaction() {
const randomId = Math.floor(Math.random()*this.roundArguments.assets);
const myArgs = {
contractId: this.roundArguments.contractId,
contractFunction: 'ReadAsset',
invokerIdentity: 'Admin@org1.example.com',
contractArguments: [`${this.workerIndex}_${randomId}`],
readOnly: true
};
await this.sutAdapter.sendRequests(myArgs);
}
async cleanupWorkloadModule() {
for (let i=0; i<this.roundArguments.assets; i++) {
const assetID = `${this.workerIndex}_${i}`;
console.log(`Worker ${this.workerIndex}: Deleting asset ${assetID}`);
const request = {
contractId: this.roundArguments.contractId,
contractFunction: 'DeleteAsset',
invokerIdentity: 'Admin@org1.example.com',
contractArguments: [assetID],
readOnly: false
};
await this.sutAdapter.sendRequests(request);
}
}
}
function createWorkloadModule() {
return new MyWorkload();
}
module.exports.createWorkloadModule = createWorkloadModule;
5.步驟4-構建基準組態檔
基準組態檔定義基準輪次并參考定義的作業負載模塊,它將指定在生成負載時要使用的測驗作業者的數量、測驗輪的數量、每輪的持續時間、在每輪期間應用于交易負載的速率控制以及與監視器相關的選項,本教程不會使用任何可用的監視器或交易觀察程式;有關這些詳細資訊,請參閱檔案,
基準組態檔可能以yaml或json格式提供:這里我們將使用yaml格式,請注意,yaml檔案區分大小寫,所有標簽都是小寫,
基準組態檔有一個必需的節:
test:
創建模板基準組態檔
在benchmarks檔案夾下創建一個名為myAssetBenchmark.yaml包括以下內容:
test:
name: basic-contract-benchmark
description: A test benchmark
workers:
rounds:
test:包含基準測驗資訊的根級塊,
name:測驗的名稱,在本例中為“基本合同基準”,
description:對基準的描述,在本例中為“測驗基準”,
workers:一組鍵,用于定義后續基準中使用的worker(獨立的worker客戶端實體)的數量,
rounds:將按順序進行的不同測驗回合的陣列,輪次可用于對不同的智能合約方法進行基準測驗,或以不同的方式對同一方法進行基準測驗,
填充模板檔案
現在,我們將填充模板檔案以指定作業人員的數量以及使用我們創建的作業負載模塊的測驗回合,
填充workers
我們將使用兩個單獨的工人,這是通過工人規范完成的:
type: local
number: 2
填充rounds
每個round塊包含以下內容:
label- 用于回合的唯一標題標簽,description- 正在運行的回合的描述,txDuration- 測驗持續時間的規范,以秒為單位rateControl- 一種速率控制型別,帶有選項,workload- 要使用的作業負載模塊,帶有要傳遞給模塊的引數,傳遞的所有引數都可以作為roundArguments在workload模塊中使用,
我們將指定一個標記為readAsset的基準輪,并使用description Query asset benchmark運行30秒,使用一個fixed-load速率控制器來保持2的恒定交易壓力,此外,我們將提供一個作業負載通過規范我們的readAsset.js作業負載檔案,我們將傳遞引數{assets:10,compactId:asset-transfer-basic},
以上是通過round規范來實作的:
- label: readAsset
description: Read asset benchmark
txDuration: 30
rateControl:
type: fixed-load
opts:
transactionLoad: 2
workload:
module: workload/readAsset.js
arguments:
assets: 10
contractId: basic
完整的基準組態檔
現在應該完全填充基準組態檔:
test:
name: basic-contract-benchmark
description: test benchmark
workers:
type: local
number: 2
rounds:
- label: readAsset
description: Read asset benchmark
txDuration: 30
rateControl:
type: fixed-load
opts:
transactionLoad: 2
workload:
module: workload/readAsset.js
arguments:
assets: 10
contractId: basic
6.第5步-運行Caliper基準測驗
我們現在可以使用上面的組態檔和測驗模塊來運行性能基準測驗了,性能基準測驗將使用Caliper CLI運行,需要提供一個指向作業區的路徑,以及指向網路組態檔和基準組態檔的作業區相對路徑,這些資訊分別與標記--caliper workspace、--caliper-networkconfig和--caliper benchconfig一起提供,
由于智能合約已經安裝和實體化,Caliper只需要執行測驗階段,這是通過使用--caliper-flow-only-test標志來指定的,
由于目標網路已啟用發現功能,我們可以通過使用標志--capiler Fabric gateway enabled和--capiler Fabric gateway discovery來使用Hyperledger Fabric網關,
運行命令
確保您位于Caliper作業區目錄中,
在終端中,運行以下Caliper CLI命令:
npx caliper launch manager --caliper-workspace ./ --caliper-networkconfig networks/networkConfig.json --caliper-benchconfig benchmarks/myAssetBenchmark.yaml --caliper-flow-only-test --caliper-fabric-gateway-enabled --caliper-fabric-gateway-discovery
基準測驗結果
結果報告將詳細說明每輪基準測驗的以下專案:
- Name—基準組態檔中的圓形名稱
- Succ/Fail-成功/失敗的交易數
- Send Rate-Caliper發出交易的速率
- Latency(max/min/avg)-與發出交易和接收回應之間的時間(以秒為單位)有關的統計資訊
- Throughput—每秒處理的平均交易數
您已經成功地為智能合約運行基準性能測驗,您可以通過改變基準測驗引數來重復測驗,以及添加資源監視器,有關全套選項,請參閱Caliper檔案,
參考自官方檔案
如有侵權,請聯系作者洗掉,謝謝!
If there is infringement, please contact the author to delete, thank you!
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/163520.html
標籤:python
上一篇:一些基礎數論的知識和證明
