zoukankan      html  css  js  c++  java
  • Hyperledger Fabric 替换couchDB

    fabric中默认数据存储的方式是levelDB,一个key/value存储的单机数据库。除此之外还提供了另外一种存储方式:couchDB。同样也是一个K/V 数据库,对fabric而言,相比于前者,后者提供更加丰富的查询功能。

    而默认的levelDB切换到couchDb也很简单。即所谓的快速拔插。

    区块链是文件系统,这个目前不支持更改,历史数据和区块链的索引是LevelDB,这个也不能更改。而对于State Database,由于和业务相关,所以提供了替换数据库,目前支持默认的LevelDB和用户可选择的CouchDB。这里要说到2点,一个是在0.6的时候其实用的RockDB,但是由于License的考虑,所以在1.0改成了LevelDB。另外就是CouchDB也不一定是最优的,很多人还考虑到MongoDB或者MySQL等,但是由于现在Fabric那边开发资源有限,所以在1.0还不会做,以后可能会实现。

    1.安装couchDB

    正常来讲,我们会为每一个peer节点提供一个couchDB作为数据存储。

    执行: docker pull klaemo/couchdb 下载镜像
    创建完成后 创建一个文件夹: mkdir couchDb 这个文件夹是用来存储数据的,因为couchDB每次启动时候都需要指定数据存储位置。

    实例化一个couchDB实例:  docker run -p 5984:5984 -d --name my-couchdb -e COUCHDB_USER=admin -e COUCHDB_PASSWORD=password -v ~/couchdb:/opt/couchdb/data klaemo/couchdb
    这是启动一个名字为
    my-couchdb,账号为admin,密码为 password的 couchDb实例  本地的5984端口映射到容器的5984端口。

    接下来访问界面化操作页面:
    http://IP:5984/_utils

    显示如下界面:

    
    

     先不用管里面的数据,因为我这个是后面操作的数据。正常到这一步应该是没有数据。

    因为我们正常的fabric网络是默认启动4个peer节点,所以需要启动四个couchDb实例。

    创建用来对应剩下的三个peer节点的数据库存储文件夹。

    mkdir couchdb2 
    mkdir couchdb3 
    mkdir couchdb4

    docker run -p 6984:5984 -d --name my-couchdb2 -e COUCHDB_USER=admin -e COUCHDB_PASSWORD=password -v ~/couchdb1:/opt/couchdb/data klaemo/couchdb 
    docker run -p 7984:5984 -d --name my-couchdb3 -e COUCHDB_USER=admin -e COUCHDB_PASSWORD=password -v ~/couchdb2:/opt/couchdb/data klaemo/couchdb
    docker run -p 8984:5984 -d --name my-couchdb4 -e COUCHDB_USER=admin -e COUCHDB_PASSWORD=password -v ~/couchdb3:/opt/couchdb/data klaemo/couchdb

    2.关联 peer节点和couchDb

    到这一步fabric的网络是还没有启动的,上一篇文章启动的e2e-cli的网络。peer节点的相关配置在/root/go/src/github.com/hyperledger/fabric/examples/e2e_cli/下的docker-compose-cli.yaml

    vi docker-compose-cli.yaml

    编辑四个节点,红色部分为新增:

    peer0.org1.example.com:
    container_name: peer0.org1.example.com
    environment:
    - CORE_LEDGER_STATE_STATEDATABASE=CouchDB
    - CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=121.199.63.157:5984
    - CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME=admin
    - CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD=password
    extends:
    file: base/docker-compose-base.yaml
    service: peer0.org1.example.com

    peer1.org1.example.com:
    container_name: peer1.org1.example.com
    environment:
    - CORE_LEDGER_STATE_STATEDATABASE=CouchDB
    - CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=121.199.63.157:6984
    - CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME=admin
    - CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD=password
    extends:
    file: base/docker-compose-base.yaml
    service: peer1.org1.example.com

    peer0.org2.example.com:
    container_name: peer0.org2.example.com
    environment:
    - CORE_LEDGER_STATE_STATEDATABASE=CouchDB
    - CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=121.199.63.157:7984
    - CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME=admin
    - CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD=password
    extends:
    file: base/docker-compose-base.yaml
    service: peer0.org2.example.com

    peer1.org2.example.com:
    container_name: peer1.org2.example.com
    environment:
    - CORE_LEDGER_STATE_STATEDATABASE=CouchDB
    - CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=121.199.63.157:8984
    - CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME=admin
    - CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD=password
    extends:
    file: base/docker-compose-base.yaml
    service: peer1.org2.example.com

    保存以后启动fabric网络  ./network_setup.sh up

    这个时候再查看就会发现多出来的数据。

    http://IP:5984/_utils

    可以看到以Channel名字创建的Database,另外还有几个是系统数据库。点进去可以查看存储在当前节点的区块数据。


    -------------------以下内容转自深蓝大神的博文-----------------------------
    https://www.cnblogs.com/studyzy/p/7101136.html

    CouchDB的直接查询

    接下来我们使用Linux的curl来查询CouchDB数据库。
    比如我们要看看mychannel数据库下有哪些数据:
    curl http://192.168.100.129:5984/mychannel/_all_docs
    可以看到我运行了一些ChainCode后的State DATABASE结果:

    {"total_rows":7,"offset":0,"rows":[ 
    {"id":"devinccu0000a","key":"devinccu0000a","value":{"rev":"2-a979bf6c2716ecae6d106999f833a59c"}}, 
    {"id":"devinccu0000b","key":"devinccu0000b","value":{"rev":"2-ad1c549305fd277097180405f96bdcd8"}}, 
    {"id":"lsccu0000devincc","key":"lsccu0000devincc","value":{"rev":"1-05d2cd0b344c4dd8a8d1a3ffd7332544"}}, 
    {"id":"lsccu0000mycc","key":"lsccu0000mycc","value":{"rev":"1-2cba0344b1610b9d9254bbafbda5e9b1"}}, 
    {"id":"myccu0000a","key":"myccu0000a","value":{"rev":"2-588a45b289359afa9dc6e5e7866eaf97"}}, 
    {"id":"myccu0000b","key":"myccu0000b","value":{"rev":"2-54e6639a858b0f91298c9a354484513a"}}, 
    {"id":"statedb_savepoint","key":"statedb_savepoint","value":{"rev":"10-6ccde2a55c71d7d6a70d9333d119fc8e"}} 
    ]}

    如果我们要查询其中的一条数据,只需要用/ChannelId/id来查询,比如查询:statedb_savepoint

    curl http://192.168.100.129:5984/mychannel/statedb_savepoint

    返回的结果: 
    {"_id":"statedb_savepoint","_rev":"10-6ccde2a55c71d7d6a70d9333d119fc8e","BlockNum":4,"TxNum":0,"UpdateSeq":"19-g1AAAAEzeJzLYWBg4MhgTmHgzcvPy09JdcjLz8gvLskBCjMlMiTJ____PyuRAYeCJAUgmWQPVsOCS40DSE08WA0jLjUJIDX1eO3KYwGSDA1ACqhsPiF1CyDq9mclsuJVdwCi7j4h8x5A1AHdx5kFAI6sYwk"}

    麻烦的是业务数据是“ChainCodeNameu0000数据”这样的格式的ID,而如果我们要通过这个ID查询,那么就根本找不到啊!

    curl http://192.168.100.129:5984/mychannel/myccu0000a 
    {"error":"not_found","reason":"missing"}

    正确的做法是把u0000替换为%00,也就是说我们的查询应该是:

    curl http://192.168.100.129:5984/mychannel/mycc%00a

    正确返回结果: 
    {"_id":"myccu0000a","_rev":"2-588a45b289359afa9dc6e5e7866eaf97","chaincodeid":"mycc","version":"4:0","_attachments":{"valueBytes":{"content_type":"application/octet-stream","revpos":2,"digest":"md5-hhOYXsSeuPdXrmQ56Hm7Kg==","length":2,"stub":true}}}

    Fabric可能会遇到的问题

    虽然区块链是一个只能插入和查询的数据库,但是我们的业务数据是存放在State Database中的,如果我们直接修改了CouchDB的数据,那么接下来的查询和事务是直接基于修改后的CouchDB的,并不会去检查区块链中的记录,所以理论上是可以通过直接改CouchDB来实现业务数据的修改。
    我们以官方的Marble为例,看看修改CouchDB会怎么样?
    具体操作步骤如下:
    1.Install,instantiate和初始化数据:
    复制代码
    peer chaincode install -n marbles02 -v 1.0 -p github.com/hyperledger/fabric/examples/chaincode/go/marbles02
    
    peer chaincode instantiate -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/cacerts/ca.example.com-cert.pem -C mychannel -n marbles02 -v 1.0 -p github.com/hyperledger/fabric/examples/chaincode/go/marbles02 -c '{"Args":["init"]}' -P "OR ('Org1MSP.member','Org2MSP.member')"
    
    peer chaincode invoke -o orderer.example.com:7050  --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/cacerts/ca.example.com-cert.pem  -C mychannel -n marbles02 -c '{"Args":["initMarble","marble2","red","50","tom"]}'
    
    peer chaincode query -C mychannel -n marbles02 -c '{"Args":["readMarble","marble2"]}'
    复制代码

    我们可以看到通过curl直接查询CouchDB中的数据:

    curl http://192.168.100.129:5984/mychannel/marbles02%00marble2

    {"_id":"marbles02u0000marble2","_rev":"1-a1844f47b9ed94294b430c9a9a6f543b","chaincodeid":"marbles02","data":{"docType":"marble","name":"marble2","color":"red","size":50,"owner":"tom"},"version":"6:0"}

    如果我们要修改其中的数据,把颜色改成green,大小改成10,那么我们可以运行:

    curl -X PUT http://192.168.100.129:5984/mychannel/marbles02%00marble2 -d '{"_id":"marbles02u0000marble2","_rev":"1-a1844f47b9ed94294b430c9a9a6f543b","chaincodeid":"marbles02","data":{"docType":"marble","name":"marble2","color":"green","size":10,"owner":"tom"},"version":"6:0"}'

    系统返回结果: 
    {"ok":true,"id":"marbles02u0000marble2","rev":"2-6ffc6652cfc707f8352a5f06c3ce1ce6"}

    我们在4个CouchDB中都运行这个命令,把4个数据库的数据都改了。
    接下来我们通过ChainCode来查询,看看会怎么样。
    peer chaincode query -C mychannel -n marbles02 -c '{"Args":["readMarble","marble2"]}'
    返回结果:
    Query Result: {"color":"green","docType":"marble","name":"marble2","owner":"tom","size":10}
    可以看到数据已经变成新的值,那么接下来运行其他的Transaction会怎么样?我们试一试转账操作:
    peer chaincode invoke -o orderer.example.com:7050  --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/cacerts/ca.example.com-cert.pem  -C mychannel -n marbles02 -c '{"Args":["transferMarble","marble2","jerry"]}'
    系统返回成功,我们再查一下呢
    peer chaincode query -C mychannel -n marbles02 -c '{"Args":["readMarble","marble2"]}'
    Query Result: {"color":"green","docType":"marble","name":"marble2","owner":"jerry","size":10}
    所以我们对CouchDB数据库的更改都是有效的,在Fabric看来似乎并不知道我们改了CouchDB的内容。
     







  • 相关阅读:
    Jquery 添加插件
    后台添加前台标签
    jQuery.validate 中文API
    jquery validate 详解二
    jquery validate 详解一
    System.Collections里的一些接口
    C#中 Reference Equals, == , Equals的区别
    关于iOS原生条形码扫描,你需要注意的两三事
    layoutSubviews何时调用的问题(转)
    layoutSubviews总结
  • 原文地址:https://www.cnblogs.com/gzhlt/p/9486071.html
Copyright © 2011-2022 走看看