分片使用说明¶
2. 节点配置¶
ChainSQL分片版本对节点配置文件进行一些调整。
禁用了配置单元
[ips]
,[ips_fixed]
,[validators]
。新增了配置单元
[shard]
,[lookup_ips]
,[lookup_public_keys]
,[shard_ips]
,[shard_validators]
,[committee_ips]
,[committee_validators]
,[sync_ips]
,[lookup_relay_interval]
。修改了配置单元
[node_db]
。
下面一一对所有新增和修改的配置项进行说明。
[shard]¶
[shard]
role = shard
shard_count = 2
shard_index = 1
role :配置节点在分片网络中的充当的角色,可取值:lookup,sync,shard,committee,其中lookup与sync可以同时设置,用’,’分隔。
shard_count :配置分片网络规划的总片区数,不包括委员会片区。
shard_index :可选,节点角色为shard时,应配置,表示当前节点所属的分片标号,从1开始。
[lookup_ips]¶
[lookup_ips]
192.168.1.1:5016
192.168.1.2:5016
参考[ips]配置单元。
配置分片网络中所有或本节点要与其建立P2P关系的Lookup节点,每行配置一个。
[lookup_public_keys]¶
[lookup_public_keys]
n94feqNjDCNBUtUWYhnEUhyAhKB6zDa6RDTSosAuaz2TcQbyQydW
n9Mwy4qkUaYMKjAuwLxEjVHjfmSLRc4iNfRodxeohnM5BRAz7gjt
参考[validators]配置单元。
配置所有受信任的Lookup节点的公钥。
[shard_ips]¶
[shard_ips]
192.168.1.3:5016,192.168.1.4:5016
192.168.1.5:5016,192.168.1.6:5016
参考[ips]配置单元。
配置分片网络中所有角色为分片的节点。
每行可配置多个,用逗号分隔,每行列出一个片区的所有节点。
第一行配置片区1中的节点,第二行配置片区2中的节点,以此类推。
[shard_validators]¶
[shard_validators]
n9Kgr6tqprYF9scLnFBitpDFN2ztMYsQCHbRtRB8RZ6VuRVFvdWA,n9J5TxDkECMCfP4LCAkzsbsUa51MX1vHXMfzW2AAe5jgrvv6s8rd
n9Kk2bqFysmoV9jR37Mj6msk9eGEsWgcms7JEQEEVYM6QgduZFAS,n9JgeybK9GRBV4NJ46YS1y8MSEf49gbBaW6CFDxFHka24wVqvsGg
参考[validators]配置单元和[shard_ips]配置单元。
配置所有受信任的分片节点的公钥。
[committee_ips]¶
[committee_ips]
192.168.1.7:5016
192.168.1.8:5016
参考[ips]配置单元。
配置分片网络中所有或本节点要与其建立P2P关系的Committee节点,每行配置一个。
[committee_validators]¶
[committee_validators]
n9LuxesD97vZ7shE7euRnQ54TfybQRCJ1kHrBE2LWwrVp28Dq5DL
n94M2CfgMsqQ8yR7DJAG3cH6ycoFk3AkESu3ANQsyf7M4U6rjbPj
参考[validators]配置单元。
配置所有受信任的Committee节点的公钥。
[sync_ips]¶
[sync_ips]
192.168.1.9:5016
192.168.1.10:5016
可选配置,如果分片网络中存在独立的sync角色节点,则需进行配置。
参考[ips]配置单元。
配置分片网络中所有或本节点要与其建立P2P关系的Sync节点,每行配置一个。
[lookup_relay_interval]¶
[lookup_relay_interval]
500
可选配置,对Lookup节点生效,配置Lookup节点对交易进行分片、打包、并转发到分片节点的频率。
单位:毫秒,默认值:500。
3. UNL Server¶
利用UNL Server可对分片网络中的验证节点公钥列表进行初始配置,也可在区块链网络运行过程中对其进行热修改。
UNL Server每项信任列表项中增加分片相关的角色信息以及分片节点所属片区号。示例如下:
{
"sequence": 2,
"expiration": "2020-02-07 16:50:00",
"validators": [
{
"validation_public_key": "0306891C7BA2C276B4180AA4E8E5DECF88F06686B3A9AFB6709064393D51654325",
"shard_role": "lookup,sync"
},
{
"validation_public_key": "02028663F808393964CD4CE236056ECEF4CED217F9CE28F43537B0FDE14F62619E",
"shard_role": "shard ",
"shard_index": "1 "
},
{
"validation_public_key": "03A7E886143819F704238FBE0CE2431BC36D392E81036D39BBD21063FDCD558D3E",
"shard_role": "committee"
}
],
}
4. 客户端¶
ChainSQL分片版本对客户端提交交易做了以下修改:
客户端(SDK或RPC客户端)必须自己维护链上账户的Sequence。
对于分片中调用智能合约的交易,交易体中可增加
Priority
字段。当交易应用失败并返回tefCONTRACT_DIFF_SHARD
错误码时,使用此字段用来指定交易所属片区为委员会片区,避免交易应用失败。
目前支持分片的SDK有Java SDK。
下面分别对客户端在使用Sign-and-submit模式以及Java SDK的使用针对分片的修改做说明。
4.1 Sign-and-submit模式¶
提交交易时,交易的tx_json对象中必须包含发起交易账户的Sequence字段。否则交易提交不成功,返回
rpcINVALID_PARAMS
错误码。
下面是一个正确的tx_json示例:
{
"method": "submit",
"params": [
{
"offline": false,
"secret": "xnoPBzXtMeMyMHUVTgbuqAfg1SUTb",
"tx_json": {
"Account": "zHb9CJAWyB4zj91VRWn96DkukG4bwdtyTh",
"Sequence": 1,
"Amount": "1000000000000",
"Destination": "z9PyRF5WDzEpiBmFr9G4W5DiDcBXMV7kKq",
"TransactionType": "Payment"
},
"fee_mult_max": 1000
}
]
}
交易体中可设置
Priority
,指定交易所属片区为委员会片区。只对调用智能合约的交易类型生效。
当设置 Priority
值为1时,显示设置交易被划分到委员会分片。
{
"method": "submit",
"params": [
{
"offline": false,
"secret": "xnoPBzXtMeMyMHUVTgbuqAfg1SUTb",
"tx_json": {
"Account": "zHb9CJAWyB4zj91VRWn96DkukG4bwdtyTh",
"Sequence": 15,
"ContractAddress": "zx1eNuwaP8YGygi1VPNaZP6ZAJhq3m31Kf",
"ContractData": "2DEF54E00000000000000000000000000000000000000000000000000000000000003039",
"Gas": 30000000,
"Priority": 1,
"ContractOpType": 2,
"TransactionType": "Contract"
},
"fee_mult_max": 1000
}
]
}
4.2 Java SDK¶
支持分片的Java SDK源码和Realease版本均可从github开源仓库获取。
Java SDK已添加对链上账户Sequence的自动维护功能,不需要开发者自行维护与关心。
Java SDK增加了对合约交易设置
Priority
的接口。
setPriority¶
public void setPriority(boolean flag);
参数
flag
-boolean
:true
表示设置交易体中Priority
字段为1,false
表示表示清除(不设置)交易体中的Priority
字段。
示例
// 加载合约
Greeter contract = Greeter.load(c, "zKotgrRHyoc7dywd7vf6LgFBXnv3K66rEg", Contract.GAS_LIMIT);
// 设置合约交易Priority
contract.setPriority(true);
// 调用合约
JSONObject ret = contract.newGreeting("Well hello again3").submit(SyncCond.validate_success);
System.out.println(ret);
5. Load启动¶
ChainSQL分片中只有Lookup角色节点为对接外部客户端的节点。Lookup接收客户端交易,处理订阅,并发布区块和交易。同时,在账本持久化方面,只有Lookup节点和Sync节点对链上的原始交易详情和Meta Data进行了持久化。
因此,当运行中的分片网络由于运维或故障缘故需要重启整个链时,重启过程需遵循以下步骤,来保证分片网络的可用性和正确性。
先
--load
启动分片网络中已完成持久化,并且区块高度最高的Lookup节点,需事先在索引数据库SQLite中查明。再
--ledger <number>
启动一个包含最高区块的委员会节点。其中 number 为步骤1中Lookup节点的区块高度。最后,正常启动分片中其它所有节点,等待整个网络完成初始化,并达成共识。
6. 常见问题¶
7. 目前缺陷¶
目前ChainSQL分片设计及实现已基本能满足高并发、大规模节点部署的应用场景,但仍存在一些细节功能上的缺陷。在ChainSQL后续的开发计划中,将继续对分片方案及实现进行完善、优化。欢迎大家体验并反馈意见。
7.2 数据库功能缺陷¶
功能 |
缺陷 |
---|---|
行级控制 |
不支持 |
严格模式 |
不支持 |
数据库事务交易 |
必须设置NeedVerify为 |