Fabric 支持两种类型的节点数据库。LevelDB 是默认嵌入在 peer 节点的状态数据库。 LevelDB 用于将链码数据存储为简单的键-值对,仅支持键、键范围和复合键查询。 CouchDB 是一 个可选的状态数据库,支持以 JSON 格式在账本上建模数据并支持富查询,以便您查询实际数据 内容而不是键。 CouchDB 同样支持在链码中部署索引,以便高效查询和对大型数据集的支持。
为了发挥 CouchDB 的优势,也就是说基于内容的 JSON 查询,你的数据必须以 JSON 格式 建模。 你必须在设置你的网络之前确定使用 LevelDB 还是 CouchDB 。 由于数据兼容性的问 题,不支持节点从 LevelDB 切换为 CouchDB 。 网络中的所有节点必须使用相同的数据库类型。 如果你想 JSON 和二进制数据混合使用,你同样可以使用 CouchDB ,但是二进制数据只 能根据键、键范围和复合键查询。
2. CouchDB 是什么
Couch ( Cluster Of Unreliable Commodity Hardware ) , 它反映了 CouchDB 的目标具有高度可伸缩性,提供了高可用性和高可靠性,即使运行在容易出现故障的硬件上也是如此。
Apache CouchDB是一个开源数据库,专注于易用性和成为"完全拥抱web的数据库"。 它是一个使用JSON作为存储格式,JavaScript作为查询语言,MapReduce和HTTP作为API的面向文档的NoSQL数据库。 其中一个显著的功能就是多主复制。CouchDB的第一个版本发布在2005年,在2008年成为了Apache的项目。
不同于关系型数据库,CouchDB没有将数据和关系存储在表格里。替代的,每个数据库是一个独立的文档集合。 每一个文档维护其自己独立的数据和自包涵的schema。 一个应用程序可能会访问多个数据库,比如其中一个位于用户的手机上,另一个位于在远程的服务器上。 文档的元数据包含版本信息,让其能够合并可能因为数据库链接丢失导致的任何差异。
CouchDB实现了一个多版本并发控制(MVCC)形式,用来避免在数据库写 *** 作的时候对文件进行加锁。 冲突留给应用程序去解决。解决一个冲突的通用 *** 作的是首先合并数据到其中一个文档,然后删除旧的数据。
其他功能包括文档级别的ACID语义和最终一致性,MapReduce,复制(Replication)。 它还支持通过一个做Futon的内置web应用程序来进行数据库管理。
3. CouchDB 特点 3.1 文档存储CouchDB将数据存储为“文档”,其为用JSON表示的有一个或者多个字段/值的对。 字段的值可以是简单的东西比如字符串,数字,或者时间;但是数组和字典同样也可以使用。 CouchDB中的每一个文档有一个唯一的id但是没有必须的文档schema。
3.2 ACID 语义CouchDB提供了ACID语义,其通过多版本并发控制的形式来实现,意味着CouchDB能够处理大量的并发读写而不会产生冲突。
3.3 Map/Reduce 视图 和 索引存储的数据通过视图进行组装。在CouchDB中,每一个视图都是由作为map/reduce *** 作中的Map部分的Javascript函数构成。 该函数接受一个文档并且将其转换为一个单独的值来返回。 CouchDB能够对视图进行索引,同时在文档新增,修改,删除的时候对这些索引进行更新。
3.4 支持复制的分布式架构CouchDB的设计基于支持双向的复制(同步)和离线 *** 作。这意味着多个复制能够对同一数据有其自己的拷贝,可以进行修改,之后将这些变更进行同步。
3.5 REST API所有的数据都有一个唯一的通过HTTP暴露出来的URI。 REST使用HTTP方法 POST,GET,PUT和DELETE来 *** 作对应的四个基本 CRUD(Create,Read,Update,Delete) *** 作来 *** 作所有的资源。
3.5 最终一致性CouchDB保证最终一致性,使其能够同时提供可用性和分割容忍。
3.6 离线支持CoucbDB能够同步复制到可能会离线的终端设备(比如智能手机),同时当设置再次在线时处理数据同步。 CouchDB内置了一个的叫做Futon的通过web访问的管理接口。
#4.如何在 fabric 中使用 CouchDB
需要使用CouchDB的话需要在启动网络的时候加上-s CouchDB即可
需要先进入net-work目录下
./nework.sh up createChannel -s CouchDB
##安装链码
1.下载 hyperledger-fabric-contract-java-demo 合约源码到本地机器cd ~fabric-samples/chaincode/
git clone https://gitee.com/kernelHP/hyperledger-fabric-contract-java-demo.git
2. 返回到test-network所在目录
返回到test-network所在目录,以便可以将链码与其他网络部件打包在一起。
cd ../../test-network
3. 将bin目录中二进制文件添加到CLI路径
所需格式的链码包可以使用peer CLI创建,使用以下命令将这些二进制文件添加到你的CLI路径。
export PATH=${PWD}/../bin:$PATH
4. 设置FABRIC_CFG_PATH为指向fabric-samples中的core.yaml文件
export FABRIC_CFG_PATH=$PWD/../config/
5.创建链码包
peer lifecycle chaincode package hyperledger-fabric-contract-java-demo.tar.gz --path ../chaincode/hyperledger-fabric-contract-java-demo/ --lang java --label hyperledger-fabric-contract-java-demo_1
命令解释:此命令将在当前目录中创建一个名为 hyperledger-fabric-contract-java-demo.tar.gz的软件包。–lang标签用于指定链码语言,–path标签提供智能合约代码的位置,该路径必须是标准路径或相对于当前工作目录的路径,–label标签用于指定一个链码标签,该标签将在安装链码后对其进行标识。建议您的标签包含链码名称和版本。
6.查询包IDpeer lifecycle chaincode queryinstalled
包ID是链码标签和链码二进制文件的哈希值的组合。每个peer节点将生成相同的包ID。你应该看到类似于以下内容的输出:
通过链码时,我们将使用包ID,因此,将包ID保存为环境变量。将返回的包ID粘贴到下面的命令中。 注意:包ID对于所有用户而言都不相同,因此需要使用上一步中从命令窗口返回的包ID来完成此步骤(每个人运行完生成的链码不同,请根据自己的修改)
export CC_PACKAGE_ID=hyperledger-fabric-contract-java-demo_1:f61f9e5b97d2034aa864bccd148dac36d0583c13176dfd267af1c8f34e7c03ae
8.Org2通过链码
因为已经设置了环境变量为peer CLI作为Orig2管理员进行 *** 作,所以我们可以以Org2组织级别将 hyperledger-fabric-contract-java-demo 的链码定义通过。使用 peer lifecycle chaincode approveformyorg命令通过链码定义:
peer lifecycle chaincode approveformyorg -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --channelID mychannel --name hyperledger-fabric-contract-java-demo --version 1.0 --package-id $CC_PACKAGE_ID --sequence 1 --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
9.Org1通过链码
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export CORE_PEER_ADDRESS=localhost:7051
用 peer lifecycle chaincode approveformyorg命令通过链码定义
peer lifecycle chaincode approveformyorg -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --channelID mychannel --name hyperledger-fabric-contract-java-demo --version 1.0 --package-id $CC_PACKAGE_ID --sequence 1 --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
10.将链码定义提交给通道
使用peer lifecycle chaincode checkcommitreadiness命令来检查通道成员是否已批准相同的链码定义:
peer lifecycle chaincode checkcommitreadiness --channelID mychannel --name hyperledger-fabric-contract-java-demo --version 1.0 --sequence 1 --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --output json
该命令将生成一个JSON映射,该映射显示通道成员是否批准了checkcommitreadiness命令中指定的参数:
由于作为通道成员的两个组织都同意了相同的参数,因此链码定义已准备好提交给通道。你可以使用peer lifecycle chaincode commit命令将链码定义提交到通道。commit命令还需要由组织管理员提交。
peer lifecycle chaincode commit -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --channelID mychannel --name hyperledger-fabric-contract-java-demo --version 1.0 --sequence 1 --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --peerAddresses localhost:7051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses localhost:9051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
如果将链码成功提交给通道,该querycommitted命令将返回链码定义的顺序和版本:
链码已安装成功。
示例代码中只是添加了一条数据:
peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n hyperledger-fabric-contract-java-demo --peerAddresses localhost:7051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses localhost:9051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"function":"createCat","Args":["cat-0" , "tom" , "3" , "蓝色" , "大懒猫"]}'
2.使用富查询查看效果
示例代码中只查询了一次:
peer chaincode query -C mychannel -n hyperledger-fabric-contract-java-demo -c '{"Args":["queryCatByName" , "tom"]}'
3.使用分页查询查看效果
peer chaincode query -C mychannel -n hyperledger-fabric-contract-java-demo -c '{"Args":["queryCatPageByName" , "tom","此值为PageSize","此值为bookmark"]}'
注:bookmark的值是执行完分页查询后返回的值,如果不穿则默认第一页,穿了值,则查询出的是查询出的bookmark后面的一页。
示例代码新建了一个索引:
{
“index”:{
“fields”:[“docType”,“owner”] // Names of the fields to be queried
},
“name”:“indexOwner”,
“type”:“json”
}
将上一步的代码写为一个json文件,添加到链码的META-INF/statedb/couchdb/indexes路径下
通过进入客户端来创建索引
http://localhost:5984/_utils
密码和账号放在/test-network/docker/docker-compose-couch.yml里
找到合约名字
现在可以看到里面有三条数据和一个索引
点击索引即可进行编辑
注:如果用CouchDB进行查询时进行了排序则排序字段必须建索引,否则会报错!
6.编写合约时使用索引 6.1富查询 6.2分页查询个人学习心得,如有错误望指正!
参考文献:https://gitee.com/kernelHP/hyperledger-fabric-contract-java-demo
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)