• 长安链数据存储介绍及Mysql存储环境搭建


    概述

    存储模块负责持久化存储链上的区块、交易、状态、历史读写集等账本数据,并对外提供上述数据的查询功能。区块链以区块为单位进行批量的数据提交,一次区块提交会涉及到多项账本数据的提交,比如:交易提交,状态数据修改等,所以存储模块需要维护账本数据的原子性。长安链支持常用的数据库来存储账本数据,如LevelDB、BadgerDB、TikvDB、MySQL等数据库,业务可选择其中任意一种数据库来部署区块链。

    账本数据主要分为5类:

    1、区块数据,记录区块元信息和交易数据:

    • 区块元数据包括:区块头、区块DAG、区块中交易的txid列表,additionalData等;
    • 交易数据,即序列化后的交易体,为了提供对单笔交易数据的查询,所以对交易数据进行了单独存储。

    2、状态数据,记录智能合约中读写的链上状态数据,即世界状态。

    3、历史数据,长安链对每笔交易在执行过程中的状态变化历史、合约调用历史、账户发起交易历史都可以进行记录,可用于后续追溯交易、状态数据的变迁过程。

    4、合约执行结果读写集数据,长安链对每笔交易在执行过程中的所读写的状态数据集进行了单独保存,方便其他节点进行快速的数据同步。

    5、事件数据,合约执行过程中产生的事件日志。

    存储模块运行逻辑

    针对上述5类账本数据,长安链分别实现了5个DB类,分别是:Block DB、State DB、History DB、Result DB和Contract Event DB。采用多个数据库之后,就需要维护数据库之间的数据一致性,避免仅有部分数据库提交后,发生程序中断而导致不同数据库间的数据不一致,因此,长安链引入了Block binary log组件来持久化存储区块的原始内容,用于重启过程中的数据恢复,类似于数据库中的预写式日志(wal)的功能。 需要注意的是,历史数据、结果数据并不是每个节点必须保存的,节点可以根据自己的业务需要在配置文件中启用或者关闭历史数据库和结果数据库。

    1.存储模块未开启区块文件存储时运行逻辑

     区块提交流程

    1. 首先将序列化后的区块、读写集数据、以及最新的区块高度写入Block binary log,用于异常中断后的数据恢复。为了提高性能,加入一层cache,新区块提交请求在更新完Block binary log之后,再将区块数据写入cache,在更新完log和cache后,提交即可返回,由后台线程异步更新Block DB、State DB、ContractEvent DB、History DB和Result DB。

    2. 在Block DB中记录区块元信息与交易信息,其中交易信息以TxID作为主键存储,区块信息以BlockHeight作为主键存储,区块元信息中只记录交易ID列表,同时索引BlockHash到BlockHeight的映射关系。Block DB中额外记录了当前最新的区块高度(LastBlockHeight)作为checkpoint,用以重启后的数据恢复。

    3. 在State DB中保存state数据,key为合约名与对象主键的组合:<contractName, ObjectKey>,同时记录最新的区块高度(LastBlockHeight)作为checkpoint。

    4. 在History DB中记录交易产生的三种类型的索引:

      1. 状态变更历史,以<contractName, ObjectKey,TxId>为索引

      2. 合约调用历史,以<contractName, TxId>为索引

      3. 账户交易历史,以<accountId,TxId>为索引

    5. 在Result DB中记录交易的读写集,读写集以TxID作为key,同时记录最新的区块高度(LastBlockHeight)作为checkpoint。

    6. 在ContractEventDB中记录下交易结果的EventLog,并记录最新区块高度作为checkpoint。

    数据库

    概述

    存储模块中的Block DB、State DB、History DB等都是封装后的DB对象,其具体实现要基于特定的数据库引擎,比如LevelDB、BadgerDB、TikvDB、MySQL等数据库引擎。为了实现可插拔的数据库引擎,长安链在数据库引擎之上封装了一层接口,并将LevelDB、BadgerDB、TikvDB、MySQL等数据库封装成DB provider。用户可以根据业务需求选择合适的数据库引擎作为长安链的底层存储组件。

    源码

    chainmaker / store · ChainMaker长安链2.0版本存储基础模块项目https://git.chainmaker.org.cn/chainmaker/store

    支持的数据库类型

    长安链目前支持4种数据库引擎可供选择,分别是LevelDB、BadgerDB、TikvDB、MySQL。

    • LevelDB,默认采用的数据库引擎,LevelDB作为一款嵌入式KV数据库,默认集成在长安链节点中,无需部署,性能也相对关系型数据要更好。

    • BadgerDB,作为另一种形式的KV单机数据库的实现,也是嵌入式KV数据库,性能在写入value比较大时比LevelDB更高,但是读性能可能差于LevelDB

    • TikvDB,作为KVDB的横向扩容版本,需要单独启动tikv服务,底层使用rocksdb,性能更高。tikv部署流程

    • MySQL,关系型数据库,支持schema和富查询,性能较KV数据库低,目前关系型数据库与区块链的状态数据并不能很好的结合,导致很少有区块链采用关系型数据库作为状态数据库。原因主要有两点:1.区块链需要对智能合约所读写的状态数据做严格的控制和校验,而SQL语句相对区块链来说过于灵活,难以控制;2.需要提前创建库表和索引,需要针对不同的智能合约创建不同的数据库表结构,不够灵活。目前长安链支持MySQL存储引擎,在系统数据如Block DB上支持区块元信息、交易信息的关系型语义,状态数据库支持kv的方式和智能合约编写SQL语句方式读写状态数据(world state)。

    数据库配置说明

    配置文件在节点本地配置文件chainmaker.yml中

    1. storage:
    2. store_path: ../data/ledgerData #账本的存储路径, 包括LevelDB、BadgerDB的数据目录,Block binary log的数据目录
    3. write_buffer_size: 4 #LevelDB的write_buffer_size, 单位为MB,默认为4M
    4. bloom_filter_bits: 10 #LevelDB的布隆过滤器参数,为每个key分配的额外bit空间,默认为10,如果少于或等于0,则不开启布隆过滤。
    5. disable_historydb: false #是否禁用历史读写集的存储功能, 默认为false,也就是保存历史读写集。
    6. disable_block_file_db: false #是否禁用区块文件存储功能, 默认为true,也就是未启用,新节点建议此处设置为false。
    7. logdb_segment_async: false #区块文件异步落盘与否, 默认为false,也就是默认同步落盘,异步落盘时存在断电后数据损坏风险。
    8. logdb_segment_size: 128 #区块文件大小,单位MB,默认20MB。
    9. blockdb_config: #BlockDB 数据库配置
    10. provider: leveldb #数据库类型,支持LevelDB,BadgerDB,TikvDB,Mysql,这里示例为LevelDB
    11. leveldb_config: #LevelDB的详细配置
    12. store_path: ../data/org1/blocks
    13. write_buffer_size: 4 #LevelDB的write_buffer_size, 单位为MB,默认为4M
    14. bloom_filter_bits: 10 #LevelDB的布隆过滤器参数,为每个key分配的额外bit空间,默认为10,如果少于或等于0,则不开启布隆过滤。
    15. block_write_buffer_size:
    16. statedb_config: #StateDB 数据库配置
    17. provider: sql #数据库类型,支持LevelDB,BadgerDB,TikvDB,Mysql,这里示例为Mysql
    18. sqldb_config: #SQL数据库的详细配置
    19. sqldb_type: mysql #具体的RDBMS为mysql,也可以是sqlite、mssql等
    20. dsn: root:password@tcp(127.0.0.1:3306)/ #MySQL的数据库连接字符串
    21. max_idle_conns: 10 #连接池中维持的最大的空闲连接数,默认为10
    22. max_open_conns: 10 #最大的可用连接数,默认为10
    23. conn_max_lifetime: 60 #连接维持的最长时间,单位秒,默认为60
    24. historydb_config: #HistoryDB数据库配置
    25. provider: badgerdb #数据库类型,支持LevelDB,BadgerDB,TikvDB,Mysql,这里示例为BadgerDB
    26. badgerdb_config:
    27. store_path: ../data/org1/history
    28. compression: 0 # value为0 不压缩,1 Snappy压缩,2 ZSTD压缩,默认为0
    29. value_threshold: 10240 # 单位为bytes,默认为10240 bytes
    30. resultdb_config: #ResultDB数据库配置
    31. provider: tikvdb # 支持LevelDB,BadgerDB,TikvDB,Mysql
    32. tikvdb_config:
    33. endpoints: "127.0.0.1:2379" # tikv pd server url,支持多个url, 如: "192.168.1.2:2379,192.168.1.3:2379"
    34. max_batch_count: 128 # 每次kv batch最大大小 默认128
    35. grpc_connection_count: 4 # chainmaker连接tikv的连接数, 默认4
    36. grpc_keep_alive_time: 10 # 保持连接的连接数, 默认10
    37. grpc_keep_alive_timeout: 3 # 保持连接的超时时间 默认3
    38. write_batch_size: 128 # 每次提交tikv批次最大大小,默认128
    39. disable_contract_eventdb: true #是否禁止合约事件存储功能,默认为true,如果设置为false,需要配置mysql
    40. contract_eventdb_config:
    41. provider: sql #如果开启contract event db 功能,需要指定provider为sql
    42. sqldb_config:
    43. sqldb_type: mysql #contract event db 只支持mysql
    44. dsn: root:password@tcp(127.0.0.1:3306)/ #mysql的连接信息,包括用户名、密码、ip、port等,示例:root:admin@tcp(127.0.0.1:3306)/

    mysql数据库配置

    1. storage:
    2. # Default store path
    3. store_path: ../data/ljh-org1.qianjinlian.com/ledgerData1 # [*]
    4. # Prefix for mysql db name
    5. # db_prefix: org1_
    6. # Minimum block height not allowed to be archived
    7. unarchive_block_height: 300000
    8. # Symmetric encryption algorithm for writing data to disk. can be sm4 or aes
    9. # encryptor: sm4 # [*]
    10. # Disable block file db, default: false
    11. disable_block_file_db: false
    12. # async write block in file block db to disk, default: false, so default is sync write disk
    13. logdb_segment_async: false
    14. # file size of .fdb, MB, default: 20
    15. logdb_segment_size: 128
    16. # bigfilter config
    17. enable_bigfilter: false #default false
    18. bigfilter_config:
    19. redis_hosts_port: "127.0.0.1:6300,127.0.0.1:6301" #redis host:port
    20. redis_password: abcpass #redis password
    21. tx_capacity: 1000000000 #support max transaction capacity
    22. fp_rate: 0.000000001 #false postive rate
    23. # RWC config
    24. enable_rwc: true #default false
    25. # suggest
    26. # if block_tx_capacity < 10000,
    27. # set rolling_window_cache_capacity greater than block_tx_capacity*1.1 and less than block_tx_capacity*2
    28. # if block_tx_capacity > 10000, set rolling_window_cache_capacity 20000
    29. rolling_window_cache_capacity: 200
    30. # Symmetric encryption key:16 bytes key
    31. # If pkcs11 is enabled, it is the keyID
    32. # encrypt_key: "1234567890123456"
    33. write_block_type: 0 # 0 common write,1 quick write
    34. disable_state_cache: false # default false
    35. state_cache_config:
    36. life_window: 3000000000000 #key/value ttl time, ns
    37. clean_window: 1000000000
    38. max_entry_size: 500
    39. hard_max_cache_size: 10240 #cache size MB
    40. # Block db config
    41. blockdb_config:
    42. # Event db only support sql
    43. provider: sql
    44. # Sql db config
    45. sqldb_config:
    46. # Event db only support mysql
    47. sqldb_type: mysql
    48. # Mysql connection info, such as: root:admin@tcp(127.0.0.1:3306)/
    49. dsn: root:root@tcp(192.168.0.201:3306)/
    50. # Example for sql provider
    51. # Databases type support leveldb, sql, badgerdb, tikvdb
    52. # provider: sql # [*]
    53. # If provider is sql, sqldb_config should not be null.
    54. # sqldb_config:
    55. # Sql db type, can be mysql, sqlite. sqlite only for test
    56. # sqldb_type: mysql # # [*]
    57. # Mysql connection info, the database name is not required. such as: root:admin@tcp(127.0.0.1:3306)/
    58. # dsn: root:password@tcp(127.0.0.1:3306)/
    59. # Example for badgerdb provider
    60. # Databases type support leveldb, sql, badgerdb, tikvdb
    61. # provider: badgerdb
    62. # If provider is badgerdb, badgerdb_config should not be null.
    63. # badgerdb_config:
    64. # BadgerDb store path
    65. # store_path: ../data/wx-org1.chainmaker.org/history
    66. # Whether compression is enabled for stored data, default is 0: disabled
    67. # compression: 0
    68. # Key and value are stored separately when value is greater than this byte, default is 1024 * 10
    69. # value_threshold: 256
    70. # Number of key value pairs written in batch. default is 128
    71. # write_batch_size: 1024
    72. # Example for tikv provider
    73. # provider: tikvdb
    74. # If provider is tikvdb, tikvdb_config should not be null.
    75. # tikvdb_config:
    76. # db_prefix: "node1_" #default is ""
    77. # endpoints: "127.0.0.1:2379" # tikv pd server url,support multi url, example :"192.168.1.2:2379,192.168.1.3:2379"
    78. # max_batch_count: 128 # max tikv commit batch size, default: 128
    79. # grpc_connection_count: 16 # chainmaker and tikv connect count, default: 4
    80. # grpc_keep_alive_time: 10 # keep connnet alive count, default: 10
    81. # grpc_keep_alive_timeout: 3 # keep connnect alive time, default: 3
    82. # write_batch_size: 128 # commit tikv bacth size each time, default: 128
    83. # State db config
    84. statedb_config:
    85. # Event db only support sql
    86. provider: sql
    87. # Sql db config
    88. sqldb_config:
    89. # Event db only support mysql
    90. sqldb_type: mysql
    91. # Mysql connection info, such as: root:admin@tcp(127.0.0.1:3306)/
    92. dsn: root:root@tcp(192.168.0.202:3306)/
    93. # History db config
    94. historydb_config:
    95. provider: sql
    96. disable_key_history: false
    97. disable_contract_history: true
    98. disable_account_history: true
    99. # Sql db config
    100. sqldb_config:
    101. # Event db only support mysql
    102. sqldb_type: mysql
    103. # Mysql connection info, such as: root:admin@tcp(127.0.0.1:3306)/
    104. dsn: root:root@tcp(192.168.0.203:3306)/
    105. # Result db config
    106. resultdb_config:
    107. # Event db only support sql
    108. provider: sql
    109. # Sql db config
    110. sqldb_config:
    111. # Event db only support mysql
    112. sqldb_type: mysql
    113. # Mysql connection info, such as: root:admin@tcp(127.0.0.1:3306)/
    114. dsn: root:root@tcp(192.168.0.204:3306)/
    115. # Disable contract event database or not. If it is false, contract_eventdb_config must be mysql
    116. disable_contract_eventdb: true
    117. # Contract event db config
    118. contract_eventdb_config:
    119. # Event db only support sql
    120. provider: sql
    121. # Sql db config
    122. sqldb_config:
    123. # Event db only support mysql
    124. sqldb_type: mysql
    125. # Mysql connection info, such as: root:admin@tcp(127.0.0.1:3306)/
    126. dsn: root:root@tcp(192.168.0.205:3306)/

    注意事项

    1. mysql数据库需要提前部署且每个节点都必须部署一套mysql环境,不可多个节点共用同一个mysql数据库。
    2. 每个节点都需要修改chainmaker.yml配置文件中的storage部分。
    3. 旧链或者已经有数据的链最好不要改数据存储方式,否则会导致链不可用。
    4. 示例中的dsn: root:root@tcp(192.168.0.205:3306)/,roo为数据库账号和密码,192.168.0.205:3306为数据库IP和端口,请根据自己的实际环境修改替换。
    5. mysql数据库部署方式参考:
    docker run -p 3306:3306 --name mysql  -v /mydata/mysql/log:/var/log/mysql -v /mydata/mysql/data:/var/lib/mysql -v /mydata/mysql/conf:/etc/mysql -e MYSQL_ROOT_PASSWORD=root -d mysql:5.7

  • 相关阅读:
    【USRP】通信总的分支有哪些
    Nacos的注册和使用
    通达信和同花顺能否实现程序化自动交易股票,量化交易如何实现?
    web前-JAVA后端 数据API接口交互协议
    Mac下adb性能测试实战
    微服务(SpringCloud)之配置管理及链路追踪
    股票买卖Ⅴ
    杭电oj--计算两点间的距离
    WorkPlus移动数字化平台高定制化服务,贴身满足企业的个性化需求
    使用Java构建RESTful API:实现灵活、可扩展的Web服务
  • 原文地址:https://blog.csdn.net/h363659487/article/details/125445686