Hyperledger Fabric CouchDB as the State Database——使用CouchDB

使用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":[      "data.docType",      "data.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/[email protected]/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"

原文地址:https://www.cnblogs.com/aberic/p/8384999.html

时间: 2024-07-31 07:09:37

Hyperledger Fabric CouchDB as the State Database——使用CouchDB的相关文章

Hyperledger Fabric 1.0 从零开始(十二)——fabric-sdk-java应用

Hyperledger Fabric 1.0 从零开始(十)--智能合约 Hyperledger Fabric 1.0 从零开始(十一)--CouchDB 上述两章,最近网上各路大神文章云集,方案多多,因为最近工作太忙太忙,我暂时就先不赘述了,后续会提供我参考过的大神文章链接出来. 这章先捡大家都比较在意的java sdk应用方案贴出来,很多朋友都找我要过,我主要是把注释都写进去了,用法简单了说了下,一般情况下会java开发的都能看懂. 年前实在太忙. JAVA-SDK 9.1.基本介绍 官方在

在HyperLedger Fabric中启用CouchDB作为State Database

回顾一下我之前的一篇博客,在Fabric 1.0中,我们存在3种类型的数据存储,一种是基于文件系统的区块链数据,这个跟比特币很像,比特币也是文件形式存储的.Fabric1.0中的区块链存储了Transaction订单读写集.而读写集到底是读什么?写什么?其实就是我们的State Database,也叫做World State,里面以键值对的方式存储了我们在ChainCode中操作的业务数据.另外还有就是对历史数据和区块链索引的数据库. 区块链是文件系统,这个目前不支持更改,历史数据和区块链的索引

Hyperledger Fabric启用CouchDB为状态数据库

Hyperledger Fabric 启用CouchDB作为状态数据库 一.概述 数据请求流 超级账本采用背书/共识模型,模拟执行和区块验证是在不同角色的节点中分开执行的.模拟执行是并发的,这样可以提高扩展性和吞吐量: 背书节点:模拟执行链码 Peer节点:验证交易并提交 2.超级账本存储元素 超级账本包含以下元素: 账本编号:快速查询存在哪些账本 账本数据: 实际的区块数据存储 区块索引: 快速查询区块/交易 状态数据: 最新的世界状态数据 历史数据: 跟踪键的历史 每个Peer节点会维护四个

HyperLedger Fabric 1.0的Transaction处理流程

如果把区块链比作一个只能读写,不能删改的分布式数据库的话,那么事务和查询就是对这个数据库进行的最重要的操作.以比特币来说,我们通过钱包或者Blockchain.info进行区块链的查询操作,而转账行为就是Transaction的处理.而HyperLedger Fabric在1.0对系统架构进行了升级,使得事务的处理更加复杂. 一.架构 让我们来看看Fabric 0.6到1.0的架构图: 这个图来自IBM微课堂第三讲,我们可以看到原来单一的peer节点在1.0中进行了拆分,分为peer(背书节点和

HyperLedger Fabric关键技术(6.4)

本节介绍从最底层的账本开始,逐一讲解账本的结构和存储.智能合约的编写和部署.通道的操作.节点的背书和提交.排序的共识和客户端SDK的接口调用,与交易流程顺序相反,由里及表的说明Fabric最关键的技术,通过学习了这六种关键技术知识,能初步掌握Fabric的核心,了解Fabric运作原理. 6.3.1 帐本(Ledger) Fabric帐本(Ledger)是一系列有序和防篡改的状态转换的记录,结构由一个区块链构成,并将不可变的.有序的记录存放在区块中:同时包含一个状态数据库来记录当前的状态,账本的

Hyperledger Fabric 建立一个简单网络

p { margin-bottom: 0.25cm; line-height: 120% } Building you first network 网络结构: 2个Orgnizations(每个Org包含2个peer节点)+1个solo ordering service 打开fabric-sample下的示例first-network p { margin-bottom: 0.25cm; line-height: 120% } 其中byfn.sh为启动这个网络的启动脚本,启动脚本中除建立一个包含

Hyperledger Fabric CA的命令行用法

介绍Hyperledger Fabric CA的命令行方式简单用法 Hyperledger Fabric CA由server和client两部分组成. 设置两个环境变量 export FABRIC_CA_SERVER_HOME=/path_to/fabric-ca/server export FABRIC_CA_CLIENT_HOME=/path_to/fabric-ca/client server的操作主要有两个: 1. 初始化Server服务 在server启动之前,需要至少有一个自我认证的

Hyperledger Fabric on SAP Cloud Platform

今天的文章来自Wen Aviva, 坐Jerry面对面的程序媛. Jerry在之前的公众号文章<在SAP UI中使用纯JavaScript显示产品主数据的3D模型视图>已经介绍过Aviva了,SAP成都C4C开发团队中其他同事评价她为:"美腻与智慧的化身","云时代女王","是大家前沿技术的引路人".因为Jerry和Aviva就在一个组,所以我的看法是,这些评价都实至名归. 比如Jerry了解到的Javascript 3D渲染,增强现

Hyperledger fabric 1.3版本的安装部署(原创多机多Orderer部署

首先,我们在安装前,要考虑一个问题 Hyperledger Fabric,通过指定的节点进行背书授权,才能完成交易的存储 延伸开来,就是为了实现容错.高并发.易扩展,需要zookeeper来选择排序引擎处理记账的唯一性 我们这里选择kafka排序引擎并通过Kafka集群和zookeeper集群保证数据的一致性,实现排序功能 同时,为了排序服务器的稳定,采取多Orderer集群实现容错空间, 为此,我们采用了最基础的配置方案:两个组织,四个节点 两个CA服务器,三个Zookeeper服务器,四个K