分片
分片是一个成熟的概念,起源于数据库设计。它是指将一个逻辑数据集拆分并分布到多个数据库中,这些数据库不共享任何内容,并可跨多个服务器部署。 简单地说,分片允许横向扩展--将数据分割成可以并行处理的不同独立片段。这是世界从数据向大数据过渡的一个关键概念。 当数据集变得太大,无法用传统方法处理时,除了将其分解成更小的片段外,就没有其他扩展方法了。
分片是TON区块链中的一种机制,它允许处理大量交易。TON中分片的主要思想是,当账户A向账户B发送消息,同时账户C向账户D发送消息时,这两个操作都可以异步进行。
默认情况下,在基本链(workchain=0
)中只有一个分片,其分片号为 0x8000000000000000
(或二进制表示为 1000000000000000000000000000000000000000000000000000000000000000
)。主链(workchain=-1
)始终只有一个分片。
拆分
每个分片负责一些具有某些共同二进制前缀的账户子集。这个前缀出现在分片ID中,由一个64位整数表示,其结构为:<二进制前缀>100000...
。例如,ID为 1011100000...
的分片包含所有以前缀 1011
开头的账户。
当某个分片中的交易数量增长时,它会分裂成两个分片。新分片获得以下ID:<父前缀>01000...
和 <父前缀>11000...
,分别负责以 <父前缀>0
和 <父前缀>1
开头的账户。分片中的区块序列号从父区块的最后一个序列号加1开始连续。拆分后,分片独立进行,可能会有不同的序列号。
工作链
示例:
独特性
在设计 TON 区块链时,我们做出了两个关键决定,使其在其他使用分片技术的区块链中独树一帜。
当分片负载下降时,它们可以按如下方式合并回去:
TON 与众不同的第二个解决方案是分片数量不固定的原则。与以太坊 2.0 等支持固定分片数量(64 个分片)的系统不同,TON 允许根据网络需要添加越来越多的分片,每个工作链的理论上限为 260 个分片。 这个数字大到几乎是无限的,可以为地球上的每个人提供超过 1 亿个分片,而且还有剩余。这种方法是满足难以提前预测的动态扩展要求的唯一途径。
示例:
分割
在TON区块链中,单个账户的交易序列(例如 Tx1 -> Tx2 -> Tx3 -> ...
)被称为账户交易链或账户链(AccountChain)。这强调了它是与单个账户相关联的交易序列。
单个分区内的多个此类账户交易链组合在一起就形成了分区链。ShardChain(以下简称 "分片")负责存储和处理分块内的所有交易,其中每个交易链都由特定的账户组定义。
这些账户组由一个共同的二进制前缀表示,作为将它们聚类到同一分片的标准。
前缀出现在分片 id 中,分片 id 是一个 64 位整数,结构如下:<binary prefix>100000...
。例如,id 为 1011100000...
的分片包含所有以前缀 1011
开头的账户。
当某个分片的交易数量增加时,该分片就会分裂成两个分片。新分片获得以下 id:<parent prefix>01000...
和<parent prefix>11000...
,并负责相应的以<parent prefix>0
和<parent prefix>1
开头的账户。分片中区块的序列号从父代最后一个序列号加 1 开始连续变化。拆分后,分片独立运行,可能会有不同的序列号。
举个简单的例子:
主链区块的头部包含分片信息。分片区块出现在主链头部后,可视为已完成(不能回滚)。
一个真实的例子:
- 主链区块
seqno=34607821
有 2 个分片:(0,4000000000000000,40485798)
and(0,c000000000000000,40485843)
(https://toncenter.com/api/v2/shards?seqno=34607821). - 分片
shard=4000000000000000
被拆分成shard=2000000000000000
和shard=6000000000000000
,主链区块seqno=34607822
得到3个分 片:(0,c000000000000000,40485844)
,(0,2000000000000000,40485799)
and(0,6000000000000000,40485799)
.请注意,这两个新分片的序列号相同,但分片 ID 不同 (https://toncenter.com/api/v2/shards?seqno=34607822)。 - 新分片独立运行,100 个主链区块后(在主链区块
seqno=34607921
中),一个分片拥有最后一个区块(0,2000000000000000,40485901)
,另一个分片拥有(0,6000000000000000,40485897)
(https://toncenter.com/api/v2/shards?seqno=34607921)。
合并
如果分片的负载下降,它们就可以合并回来:
- 两个分片可以合并,如果它们有一个共同的父分片,因此,它们的分片id是
<parent prefix>010...
和<父前缀110...
。合并后的分片将拥有分片 ID<parent prefix>10...
(例如10010...
+10110...
=1010...
)。合并分片的第一个区块将具有seqno=max(seqno1, seqno2) + 1
。
举个简单的例子:
一个真实的例子:
- 在主链区块 "seqno=34626306 "中,最后一个区块"(0,a000000000000000,40492030) "和"(0,e000000000000000,40492216) "的五个分片中的两个合并为一个区块"(0,c000000000000000,40492217)"(https://toncenter.com/api/v2/shards?seqno=34626306 和 https://toncenter.com/api/v2/shards?seqno=34626307)。