AMDB

分布式存储(Advanced Mass Database,AMDB)通过对表结构的设计,既可以对应到关系型数据库的表,又可以拆分使用KV数据库存储。通过实现对应于不同数据库的存储驱动,AMDB理论上可以支持所有关系型和KV的数据库。

  • CRUD数据、区块数据默认情况下都保存在AMDB,无需配置,合约局部变量存储可根据需要配置为MPTState或StorageState,无论配置哪种State,合约代码都不需要变动。
  • 当使用MPTState时,合约局部变量保存在MPT树中。当使用StorageState时,合约局部变量保存在AMDB表中。
  • 尽管MPTState和AMDB最终数据都会写向RocksDB,但二者使用不同的RocksDB实例,没有事务性,因此当配置成使用MPTState时,提交数据时异常可能导致两个RocksDB数据不一致。

名词解释

Table

存储表中的所有数据。Table中存储AMDB主key到对应Entries的映射,可以基于AMDB主key进行增删改查,支持条件筛选。

Entries

Entries中存放主Key相同的Entry,数组。AMDB的主Key与Mysql中的主key不同,AMDB主key用于标示Entry属于哪个key,相同key的Entry会存放在同一个Entries中。

Entry

对应于表中的一行,每行以列名作为key,对应的值作为value,构成KV结构。每个Entry拥有自己的AMDB主key,不同Entry允许拥有相同的AMDB主key。

Condition

Table中的删改查接口支持传入条件,这三种接口会返回根据条件筛选后的结果。如果条件为空,则不做任何筛选。

数据更新或者插入过程中,需要根据主Key获取数据并将对数据更新或者append操作,然后再写回存储系统。因此,在一个主Key对应的Entries中Entry个数很多的时候,执行效率会受到影响;同时,会加大内存的使用。所以,实际生产过程中主Key对应的Entries中Entry个数不宜过多。

举例

以某公司员工领用物资登记表为例,解释上述名词。

Name*item_iditem_name
Alice1001001laptop
Alice1001002screen
Bob1002001macbook
Chris1003001PC

解释如下:

  • 表中Name是AMDB主key。
  • 表中的每一行为一个Entry。一共有4个Entry,每个Entry以Map存储数据。4个Entry如下:
    • Entry1:{Name:Alice,item_id:1001001,item_name:laptop}
    • Entry2:{Name:Alice,item_id:1001002,item_name:screen}
    • Entry3:{Name:Bob,item_id:1002001,item_name:macbook}
    • Entry4:{Name:Chris,item_id:1003001,item_name:PC}
  • Table中以Name为主key,存有3个Entries对象。第1个Entries中存有Alice的2条记录,第2个Entries中存有Bob的1条记录,第3个Entries中存有Chris的一条记录。
  • 调用Table类的查询接口时,查接口需要指定AMDB主key和条件,设置查询的AMDB主key为Alice,条件为item_id = 1001001,会查询出Entry1。

AMDB表分类

表中的所有entry,都会有_status_,_num_,_hash_内置字段。

系统表

系统表默认存在,由存储驱动保证系统表的创建。

表名keyFieldvalueField存储数据说明AMDB主key
sys_tablestablenamekey_field,value_field存储所有表的结构,以表名为主键所有表的表名
_sys_consensusnametype,nodeid,enable_num存储共识节点和观察节点的列表node
_sys_table_accesstablenameaddress,enable_num存储每个表的具有写权限的外部账户地址表的表名
_sys_cnsnameversion,address,abi存储CNS映射关系合约名
sys_configkeyvalue,enablenum存储需要共识的群组配置项配置项
_sys_current_statekeyvalue存储最新的状态currentnumber/total_transaction_count
_sys_tx_hash_2_blockhashvalue,index存储交易hash到区块号的映射交易hash的16进制
sys_number_2_hashhashvalue存储区块号到区块头hash的16进制表示的映射区块高
sys_hash_2_blockkeyvalue存储hash到序列化的区块数据区块头hash的16进制
sys_block_2_noncesnumbervalue存储区块中交易的nonces区块高

用户表

用户调用CRUD接口所创建的表,从2.2版本开始以u_<TableName>为表名,底层自动添加u_前缀。

StorageState账户表

从2.2版本开始以c_+Address作为表名。表中存储外部账户相关信息。表结构如下

key*value
balance
nonce
code
codeHash
alive

StorageState

StorageState是一种使用AMDB实现的存储账户状态的方式。相比于MPTState主要有以下区别:

StorageStateMPTState
账户数据组织方式AMDB表MPT树
历史状态不支持,不维护历史状态支持

MPTState每个账户使用MPT树存储其数据,当历史数据逐渐增多时,会因为存储方式和磁盘IO导致性能问题。StorageState每个账户对应一个Table存储其相关数据,包括账户的nonce,code,balance等内容,而AMDB可以通过实现对应的存储驱动支持不同的数据库以提高性能,我们使用RocksDB测试发现,StorageState性能大约是MPTState的两倍。