狀態數據庫
LevelDB是默認的狀態數據庫.LevelDB是採用C++編寫的一種高性能嵌入式數據庫,沒有獨立的數據庫進程,佔用資源少,速度快。
CouchDB是一種文檔型數據庫,提供了RESTful的API操作文檔,CouchDB支持原生的JSON和字節數組的操作、富查詢,尤其是從Fabric1.3版本開始支持分頁。
啓用CouchDB
編寫節點配置文件及CouchDB配置文件docker-compose-couchdb.yaml
version: '2'
services:
couchdb0:
container_name: couchdb0
image: hyperledger/fabric-couchdb
# Populate the COUCHDB_USER and COUCHDB_PASSWORD to set an admin user and password
# for CouchDB. This will prevent CouchDB from operating in an "Admin Party" mode.
environment:
- COUCHDB_USER=
- COUCHDB_PASSWORD=
# Comment/Uncomment the port mapping if you want to hide/expose the CouchDB service,
# for example map it to utilize Fauxton User Interface in dev environments.
ports:
- "5984:5984"
以上爲最簡配置,僅包含用戶名、密碼、端口等信息,更多配置項可查閱相關的資料。啓動CouchDB容器:
docker-compose -f ../docker-compose-couchdb.yaml up -d
在peer節點的配置文件中增加以下配置項
- CORE_LEDGER_STATE_STATEDATABASE=CouchDB
- CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=couchdb0:5984
# The CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME and CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD
# provide the credentials for ledger to connect to CouchDB. The username and password must
# match the username and password set for the associated CouchDB.
- CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME
- CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD=
啓動相應容器,OK,基礎環境已經完成。
鏈碼常見API
常見shimAPI:Go,node.js, Java
LevelDB和CouchDB都支持基本的shim API:
GetState(key string) ([]byte, error)
PutState(key string, value []byte) error
GetStateByRange(startKey, endKey string) (StateQueryIteratorInterface, error)
GetStateByPartialCompositeKey(objectType string, keys []string) (StateQueryIteratorInterface, error)
對於CouchDB的富查詢,API提供了 GetQueryResult(query string) (StateQueryIteratorInterface, error) 接口,其中參數query string格式參考 CouchDB JSON 查詢語法
{
"selector": {
"year": {"$gt": 2010}
},
"fields": ["_id", "_rev", "year", "title"],
"sort": [{"year": "asc"}],
"limit": 2,
"skip": 0,
"execution_stats": true
}
CouchDB分頁
Fabric支持針對富查詢、基於範圍的查詢、分頁查詢。由於Fabric本身對於查詢結果的最大數目進行了限制,因此在CouchDB查詢中,不接受CouchDB limit關鍵字。
分頁查詢API提供以下三個常見的接口:
GetStateByRangeWithPagination(startKey, endKey string, pageSize int32, bookmark string) (StateQueryIteratorInterface, *pb.QueryResponseMetadata, error)
GetStateByPartialCompositeKeyWithPagination(objectType string, keys []string, pageSize int32, bookmark string) (StateQueryIteratorInterface, *pb.QueryResponseMetadata, error)
GetQueryResultWithPagination(query string, pageSize int32, bookmark string) (StateQueryIteratorInterface, *pb.QueryResponseMetadata, error)
指定查詢數量(pageSize )和書籤(bookmark ),接口返回數據和下次查詢的書籤(對於初次查詢,書籤傳入空字符串“”),分頁查詢是隻讀的,爲了避免查詢時間過長,所有的鏈碼查詢返回結果數據的最大條數都由core.yaml中的totalQueryLimit(默認值爲100000)限定。另外無論是否啓用分頁,peer都會根據core.yaml中的internalQueryLimit(默認值爲1000)分批查詢CouchDB,以保障性能。
CouchDB索引
索引使JSON查詢更高效,並且對應排序(sort)而言,創建索引是必須的。使用方法:在鏈碼文件所在目錄,創建META-INF / statedb / couchdb / indexes目錄,每個索引必須在擴展名爲.json的文本文件中定義,遵循CouchDB索引的基本語法. 例如:
{"index":{"fields":["docType","owner"]},"ddoc":"indexOwnerDoc", "name":"indexOwner","type":"json"}
當鏈碼實例化時,會自動創建到通道中的節點的狀態數據庫。索引建立後,鏈碼查詢將自動使用索引。 CouchDB可以根據查詢中使用的字段自動確定要使用的索引。 另外,在selector查詢中,可以使用use_index關鍵字指定索引。
鏈碼後續版本中可能存在相同的索引, 要更改索引,可使用相同的索引名稱,但要更改索引定義。 安裝/實例化後,索引定義將重新部署到peer節點的狀態數據庫。
通過CouchDB Fauxton interface
CouchDB Fauxton interface 是一個WEB UI,支持外部創建索引,更新索引,地址:http://localhost:5984/_utils
通過POST請求
應用程序可以通過POST請求,進行索引的創建和刪除,這裏爲了測試方便,我們通過curl進行接口交互.
索引創建(數據庫mychannel_marbles):
curl -i -X POST -H "Content-Type: application/json" -d
"{\"index\":{\"fields\":[\"docType\",\"owner\"]},
\"name\":\"indexOwner\",
\"ddoc\":\"indexOwnerDoc\",
\"type\":\"json\"}" http://hostname:port/mychannel_marbles/_index
一般情況數據庫命名爲通道名_鏈碼名,如上面例子,通道mychannel,鏈碼marbles
索引刪除(數據庫mychannel_marbles):
curl -X DELETE http://localhost:5984/mychannel_marbles/_index/indexOwnerDoc/json/indexOwner -H "accept: */*" -H "Host: localhost:5984"
命令格式
curl -X DELETE http://localhost:5984/{database_name}/_index/{design_doc}/json/{index_name} -H "accept: */*" -H "Host: localhost:5984"