Hyperledger Fabric CouchDB as the State Database
使用CouchDB作为状态数据库
状态数据库选项
状态数据库包括LevelDB和CouchDB。LevelDB是嵌入在peer进程中的默认键/值状态数据库,CouchDB是一个可选的外部状态数据库。与LevelDB键/值存储一样,CouchDB可以存储任何以chaincode建模的二进制数据(CouchDB附件函数在内部用于非json二进制数据)。但是,当chaincode值(例如,资产)被建模为JSON数据时,作为JSON文档存储,CouchDB支持对chaincode数据进行丰富的查询。
LevelDB和CouchDB都支持核心chaincode操作,例如获取和设置一个键(资产),并根据键进行查询。键可以通过范围查询,可以对组合键进行建模,以支持针对多个参数的等价查询。例如,作为所有者的组合键,资产id可以用于查询某个实体拥有的所有资产。这些基于key的查询可以用于针对账本的只读查询,以及更新总账的事务。
如果将资产建模为JSON并使用CouchDB,那么就可以使用chaincode中的CouchDB JSON查询语言对chaincode数据值执行复杂的富查询,这些类型的查询对于理解账本上的内容很有帮助。对于这些类型的查询,事务协议响应通常对客户端应用程序有用,但通常不会作为事务提交到排序服务。事实上,也无法保证结果集在chaincode执行与富查询提交时间之间的稳定性,因此使用富查询的结果去执行最终的事务更新操作是不合适的,除非可以保证结果集在chaincode执行时间与提交时间之间的稳定性,或者可以处理在后续交易中的潜在变化。例如,如果对Alice所拥有的所有资产执行一个富查询并将其传输给Bob,那么一个新的资产可能会被另一个事务分配给Alice,这是在chaincode执行时间和提交时间之间的另一个事务,可能此过程中会错过这个“虚值”。
CouchDB作为一个独立的数据库进程与peer一起运行,因此在设置、管理和操作方面有额外的考虑。我们可以考虑从默认的嵌入式LevelDB开始,如果需要额外的复杂的富查询,可以转移到CouchDB。将chaincode资产数据建模为JSON是一种很好的做法,这样我们就可以在将来执行需要的复杂的富查询。
使用Chaincode中的CouchDB
大多数chaincode的api都可以使用LevelDB或CouchDB状态数据库,例如GetState、PutState、GetStateByRange以及GetStateByPartialCompositeKey等。只有当使用CouchDB作为状态数据库和在chaincode中作为JSON的模型资产时,可以使用GetQueryResult API和传递一个CouchDB查询字符串来对状态数据库中的JSON执行富查询。查询字符串遵循CouchDB JSON查询语法。
fabric项目中的marbles02示例演示了使用来自chaincode的CouchDB查询。它包括一个getMarblesByOwner()函数,它通过将一个owner id传递给chaincode来演示参数化查询,然后查询与“marble”docType匹配的JSON文档的状态数据,以及owner id使用JSON查询语法:
{
"selector":{
"docType":"marble",
"owner":<OWNER_ID>
}
}
为了使JSON查询更高效,并且对于任何具有排序的JSON查询,都需要使用CouchDB中的索引。索引可以和chaincode一起打包 /META-INF/statedb/couchdb/indexes目录。每个索引必须在其自己的文本文件中通过扩展*.json被定义,其中索引定义为JSON格式并引用CouchDB索引JSON语法,例如,为了支持上面的marble查询,提供了一个关于docType和所有者字段的示例索引:
{
"index":{
"fields":[
"docType",
"owner"
]
},
"ddoc":"indexOwnerDoc",
"name":"indexOwner",
"type":"json"
}
这里可以找到示例索引。
注意:在1.1 alpha中,必须为索引定义中引用的每个字段指定“数据”封装器。在随后的版本中,指定“数据”封装器的需求可能会被取消。
在chaincode的META-INF/statedb/couchdb/indexes目录中的任何索引都将与chaincode一起被打包和安装在peer上。当chaincode即安装在peer上,且又在peer的channel上实例化时,该索引将自动部署到peer的channel状态数据库(如果已配置为使用CouchDB)。如果是先安装了chaincode,然后才在channel上实例化该chaincode,那么该索引将会在chaincode实例化的时候进行部署。如果chaincode已经在一个channel上实例化了,然后又在一个peer上安装了这个chaincode,该索引还是会在chaincode实例化的时候进行部署。
在部署时,索引将自动被chaincode查询利用。CouchDB可以根据查询中使用的字段自动确定要使用的索引。或者,在选择器查询中,可以使用use_index关键字指定索引。
在安装的chaincode的后续版本中可能存在相同的索引。要更改索引,使用相同的索引名称,但要更改索引定义。在安装/实例化,索引定义会重新部署到peer的状态数据库。
如果所在channle已经拥有大量的数据,并且随后安装了chaincode,那么索引的创建在实例化上可能需要一些时间。类似地,如果channel已经拥有大量的数据并且实例化了后续版本的chaincode,那么创建索引也可能需要一些时间。所以需要尽量避免在这些时间段内调用查询状态数据库的chaincode函数,因为当索引被初始化时,chaincode查询可能会超时。在事务处理期间,因为块被提交给账本总账,所以索引将自动刷新。
CouchDB配置
通过将状态数据库配置选项从goleveldb更改为CouchDB,可以将CouchDB作为状态数据库启用。此外,couchDBAddress需要配置为指向由peer使用的CouchDB。如果将CouchDB配置一个用户名和密码,那么用户名和密码属性应该包含管理员用户名和密码。在couchDBConfig中提供了更多的选项,并在适当的地方进行了记录。在重启peer之后,修改过的core.yaml将会立即生效。
当然还可以通过docker环境变量来覆盖core.yaml值,例如CORE_LEDGER_STATE_STATEDATABASE和CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS。
以下是来自core.yaml的状态数据库选项:
state:
# stateDatabase - options are "goleveldb", "CouchDB"
# goleveldb - default state database stored in goleveldb.
# CouchDB - store state database in CouchDB
stateDatabase: goleveldb
couchDBConfig:
# It is recommended to run CouchDB on the same server as the peer, and
# not map the CouchDB container port to a server port in docker-compose.
# Otherwise proper security must be provided on the connection between
# CouchDB client (on the peer) and server.
couchDBAddress: couchdb:5984
# This username must have read and write authority on CouchDB
username:
# The password is recommended to pass as an environment variable
# during start up (e.g. LEDGER_COUCHDBCONFIG_PASSWORD).
# If it is stored here, the file must be access control protected
# to prevent unintended users from discovering the password.
password:
# Number of retries for CouchDB errors
maxRetries: 3
# Number of retries for CouchDB errors during peer startup
maxRetriesOnStartup: 10
# CouchDB request timeout (unit: duration, e.g. 20s)
requestTimeout: 35s
# Limit on the number of records to return per query
queryLimit: 10000
CouchDB被托管在docker容器中,通过使用Docker Compose脚本来利用Hyperledger Fabric设置CouchDB的username和password的能力,通过已有的环境变量设置,即COUCHDB_USER和COUCHDB_PASSWORD环境变量。
对于在使用Fabric提供的docker映像之外的CouchDB安装,本地安装。必须编辑ini文件以设置admin用户名和密码。
Docker Compose脚本只在创建容器时设置用户名和密码。如果要在容器创建后更改用户名或密码,则必须对本地.ini文件进行编辑。
注意:在每个peer启动时都读取CouchDB的peer选项。
补充
在Hyperledger Fabric 1.0 从零开始(九)——Fabric多节点集群生产启动中已经设置了peer和cli的启动配置,其中没有加入couchdb,这里补充下一个新的peer编写方法,希望对各位有帮助。
后续在写到ca的时候也会将ca启动部分加入进来。
# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
# version: '2' services: couchdb:
container_name: couchdb
image: hyperledger/fabric-couchdb
# 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" peer0.xxx.example.com:
container_name: peer0.xxx.example.com
image: hyperledger/fabric-peer
environment:
- CORE_LEDGER_STATE_STATEDATABASE=CouchDB
- CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=couchdb:5984 - CORE_PEER_ID=peer0.xxx.example.com
- CORE_PEER_NETWORKID=anti
- CORE_PEER_ADDRESS=peer0.xxx.example.com:7051
- CORE_PEER_CHAINCODELISTENADDRESS=peer0.xxx.example.com:7052
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.xxx.example.com:7051
- CORE_PEER_LOCALMSPID=xxxMSP - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
# the following setting starts chaincode containers on the same
# bridge network as the peers
# https://docs.docker.com/compose/networking/
- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=anti_default
- CORE_LOGGING_LEVEL=ERROR
# - CORE_LOGGING_LEVEL=DEBUG
- CORE_PEER_GOSSIP_SKIPHANDSHAKE=true
- CORE_PEER_GOSSIP_USELEADERELECTION=true
- CORE_PEER_GOSSIP_ORGLEADER=false
- CORE_PEER_PROFILE_ENABLED=false
- CORE_PEER_TLS_ENABLED=false
- CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/fabric/tls/server.crt
- CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/fabric/tls/server.key
- CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/tls/ca.crt
volumes:
- /var/run/:/host/var/run/
- ./crypto-config/peerOrganizations/xxx.example.com/peers/peer0.xxx.example.com/msp:/etc/hyperledger/fabric/msp
- ./crypto-config/peerOrganizations/xxx.example.com/peers/peer0.xxx.example.com/tls:/etc/hyperledger/fabric/tls
working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
command: peer node start
ports:
- 7051:7051
- 7052:7052
- 7053:7053
depends_on:
- couchdb
networks:
default:
aliases:
- anti
extra_hosts:
- "orderer0.example.com:x.x.x.41"
- "orderer1.example.com:x.x.x.42"
- "orderer2.example.com:x.x.x.43" cli:
container_name: cli
image: hyperledger/fabric-tools
tty: true
environment:
- GOPATH=/opt/gopath
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
- CORE_LOGGING_LEVEL=ERROR
# - CORE_LOGGING_LEVEL=DEBUG
- CORE_PEER_ID=cli
- CORE_PEER_ADDRESS=peer0.xxx.example.com:7051
- CORE_PEER_LOCALMSPID=xxxMSP
- CORE_PEER_TLS_ENABLED=false
- CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/xxx.example.com/peers/peer0.xxx.example.com/tls/server.crt
- CORE_PEER_TLS_KEY_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/xxx.example.com/peers/peer0.xxx.example.com/tls/server.key
- CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/xxx.example.com/peers/peer0.xxx.example.com/tls/ca.crt
- CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/xxx.example.com/users/Admin@xxx.example.com/msp
working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
volumes:
- /var/run/:/host/var/run/
- ./chaincode/go/:/opt/gopath/src/github.com/hyperledger/fabric/antimoth/anti/chaincode/go
- ./crypto-config:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/
- ./scripts:/opt/gopath/src/github.com/hyperledger/fabric/peer/scripts/
- ./channel-artifacts:/opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts
depends_on:
- peer0.xxx.example.com
extra_hosts:
- "orderer0.example.com:x.x.x.41"
- "orderer1.example.com:x.x.x.42"
- "orderer2.example.com:x.x.x.43"
- "peer0.xxxx.example.com:x.x.xx.251"
Hyperledger Fabric CouchDB as the State Database的更多相关文章
- Hyperledger Fabric CouchDB as the State Database——使用CouchDB
使用CouchDB作为状态数据库 状态数据库选项 状态数据库包括LevelDB和CouchDB.LevelDB是嵌入在peer进程中的默认键/值状态数据库,CouchDB是一个可选的外部状态数据库.与 ...
- Hyperledger Fabric 1.0 从零开始(十二)——fabric-sdk-java应用
Hyperledger Fabric 1.0 从零开始(十)--智能合约 Hyperledger Fabric 1.0 从零开始(十一)--CouchDB 上述两章,最近网上各路大神文章云集,方案多多 ...
- Hyperledger Fabric Ledger——账本总账
Ledger Ledger(账本)即所有的state transitions(状态切换),是有序且不可篡改的.state transitions(状态切换)是由参与方提交的chaincode(智能合约 ...
- Hyperledger Fabric 1.0 从零开始(一)
在HyperLedger/Fabric发布0.6的时候,公司就已经安排了一个团队研究这一块,后来也请IBM的专家组过来培训了一批人,不幸的是,这批人后来全走了,然后1.0就发布了.自从2017年7月H ...
- Centos7 HyperLedger Fabric 1.4 生产环境部署
Kafka生产环境部署案例采用三个排序(orderer)服务.四个kafka.三个zookeeper和四个节点(peer)组成,共准备八台服务器,每台服务器对应的服务如下所示: kafka案例网络拓扑 ...
- 在HyperLedger Fabric中启用CouchDB作为State Database
回顾一下我之前的一篇博客,在Fabric 1.0中,我们存在3种类型的数据存储,一种是基于文件系统的区块链数据,这个跟比特币很像,比特币也是文件形式存储的.Fabric1.0中的区块链存储了Trans ...
- Hyperledger Fabric 替换couchDB
fabric中默认数据存储的方式是levelDB,一个key/value存储的单机数据库.除此之外还提供了另外一种存储方式:couchDB.同样也是一个K/V 数据库,对fabric而言,相比于前者, ...
- Hyperledger Fabric 本地运行的简单示例
环境: Ubuntu 16.04 go 1.7.4 版本: Fabric v1.0.0-alpha 本文主要目的就是让大家体验以下Fabric网络环境搭建的具体过程,不基于集成化脚本手动搭建. 一.编 ...
- HyperLedger Fabric ChainCode开发——shim.ChaincodeStubInterface用法
深蓝前几篇博客讲了Fabric的环境搭建,在环境搭建好后,我们就可以进行Fabric的开发工作了.Fabric的开发主要分成2部分,ChainCode链上代码开发和基于SDK的Application开 ...
随机推荐
- Python之旅本地环境搭建
刚开始学习Python, 之后将会把Python相关的一些学习在此记录下来 . 毋庸置疑 ,我们需要先搭建本地开发环境, 为之后的Python开发做准备 ,这篇文章 ,将环境的搭建记录下来 第一步: ...
- JQuery.lazyload 图片延迟加载
1.引入 jquery.lazyload.js 2. 延时加载的方式 <script type="text/javascript"> $(function() { ...
- Javascript一句代码实现JS字符串去除重复字符
需求: 原字符串:abcdabecd 去重后字符串:abcde JS字符串去重,一个简单需求,网上找案例发现都是一大堆代码,对于强迫症的我 实再无法忍受,于是自己手动写出一段代码,完美解决该问题. 代 ...
- ZZ_INEERNAL每个栏位的含义
ZZ_INEERNAL包含10列,每列之间用,隔开 第一列:exception class,有KE/NE/JE/EE等 第二列:pid 第三列:tid 第四列:固定是99 第五列:固定是/data/c ...
- Maven02——回顾、整合ssh框架、分模块开发、私服
1 回顾 1.1 Maven的好处 节省空间 对jar包做了统一管理 依赖管理 一键构建 可跨平台 应用在大型项目可提高开发效率 1.2 Maven安装部署配置 1.3 Maven的仓库 本地仓库 远 ...
- 用Windbg来分析.Net程序的dump
介绍 1. 什么是Windbg WinDbg是微软发布的一款相当优秀的源码级(source-level)调试工具,可以用于Kernel模式调试和用户模式调试,还可以调试Dump文件. WinDbg是微 ...
- Android基础_多媒体
一.MediaPlayer Android的MediaPlayer包含了Audio和video的播放功能,在Android的界面上,Music和Video两个应用程序都是调用MediaPlayer实现 ...
- ajax中url赋json格式的值时发生中文乱码的相关问题
具体流程:转入到jsp界面时会加载ajax,ajax转到url时传带hide在jsp界面的值titleString,其来源见下面的代码. String title=new String("\ ...
- hdu 6191--Query on A Tree(持久化字典树)
题目链接 Problem Description Monkey A lives on a tree, he always plays on this tree. One day, monkey A l ...
- CSS3让长单词与URL地址自动换行——word-wrap属性
div{ word-wrap:break-word; } word-wrap属性可以使用的属性值为normal与break-word两个.使用normal属性值时浏览器默认处理,只在半角空格或者连字符 ...