Files
solana/docs/i18n/zh/docusaurus-plugin-content-docs/current/cluster/turbine-block-propagation.md
Justin Starry a1df57a4ea Add chinese translations to docs (#17125)
* import zh translations

* Fix broken links

* fix whitespace
2021-05-09 00:46:24 +08:00

89 lines
5.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: 涡轮Turbine区块传播
---
Solana 集群使用一个叫做 _Turbine_ 的多层区块传播机制来广播所有节点的交易,该过程只产生少量的重复信息。 群集将自身分成小的节点集合,叫做 _neighborhoods邻居_。 每个节点负责与其附近的其他节点分享它收到的任何数据,同时将数据传播到其他邻居的小节点。 这样,每个节点只需要与少数节点通信。
在其插槽中,领导人节点会在第一个邻居的验证节点\(层 0\) 之间分配碎片。 每个验证节点在其邻居之间共享各自的数据,但也在下一层\(层 1\) 中将碎片转化为某个邻居的一个节点。 每个 1 层节点与邻居节点共享数据, 并在下一层重新传输到节点,以此类推,直到集群中的所有节点都收到了所有碎片。
## 邻居分配 - 权重选择
为了使数据扩散发挥作用,整个集群必须就如何将划分邻居达成一致。 为了实现这一点,所有公认的验证节点 \(TVU 节点\) 都按质押权重排列并存储在一个列表中。 然后以不同的方式索引这该列表,来查明邻居边界并相互重新传送。 例如,领导者只需选择第一个节点来构建层 0。 最高权重的质押持有者会让得票最多的节点优先成为领导者。 0 层和下层节点使用相同的逻辑来找到他们的邻居和下一个层节点。
为了减少攻击向量的可能性,每个碎片都向邻居发送一个随机树。 每个节点使用代表集群的同一批节点。 随机树是通过碎片集生成的它使用领导者ID、插槽和碎片索引来生成种子。
## 层和邻居结构
当前领导者将其初始广播到最多 `DATA_PLANE_FANOUT` 的节点。 如果该层 0 小于集群中的节点数,则数据平面扫描机制在下面添加图层。 随后的图层遵循这些约束来决定图层容量:每个邻居包含的 `DATA_PLANE_FANOUT` 节点。 0 层从带有扩散节点的 1 个邻居开始计算。 每个附加层中的节点数量增加了一个扩散因素。
如上文所述, 图层中的每个节点只能向邻居广播它的碎片,并且在某些下层邻居中只能播放一个节点, 不适用于集群中的每个 TVU 节点。 有一个理解该问题的好方法0 层从带有扩散节点的 1 个邻居开始计算1 层增加扩散邻居, 每个带有扩散节点和 2 层的节点都会有 `扩散 * 在 1 层的节点数量`,以此类推。
这样,每个节点进行通信最大只能达到 `2 * DATA_PLANE_FANOUT - 1` 个节点。
下面的图表显示了领导人如何在 0 层向 0 令居发送两个扩散的碎片,以及 0 邻居的节点如何彼此分享他们的数据。
![领导者向 0 层中的 0 号邻居发送碎片](/img/data-plane-seeding.svg)
下面的图表显示了 Neighborhood 0 如何向 Neighborhood 1和2 进行扩散。
![Neighborhood 0 向Neighborhood 1 和 2 号散播](/img/data-plane-fanout.svg)
最后,下图显示两个层集群都有 2 个扩散。
![具有两个扩散的两层集群](/img/data-plane.svg)
### 设置值
`DATA_PLANE_FANOUT` - 确定层 0 的大小。 后续的层由 `DATA_PLANE_FANOUT` 系数生成。 邻居的节点数量等于扩散值。 某个邻居要在添加新邻居之前被填满即如果某个邻居没有满它_必须_是最后一个。
目前,集群启动的时候就进行了配置。 未来这些参数可能会托管在链上,从而能够随着群组大小的变化而自行调整。
## 计算所需的 FEC 比率
Turbine 依赖于验证器之间数据包的再传输。 由于重新传输,任何网络宽包丢失都会加重, 同时每次访问的数据包未能到达目的地的概率也会增加。 FEC 比率需要考虑网络宽数据包丢失和传播深度。
碎片组是可以使用重建彼此的数据和编码数据集。 每个碎片组都有失败的可能性,其概率大致相当于数据包错误率超过 FEC。 如果验证节点无法重建碎片组,那就无法构建区块,它就必须先修复区块。
碎片组失败的概率可以通过二项分布计算。 如果 FEC 率是 `16:4`, 那么群组大小则为 20而且至少要有 4 个碎片失败才会导致整个组失败。 这等于 20 个碎片中的四条或更多个体失败的概率之和。
涡轮区块成功的概率为:
- 数据包失败的概率为: `P = 1 - (1 - network_packet_loss_rate)^2`
- FEC 率: `K:M`
- 尝试次数: `N = K + M`
- 碎片组失败率: `S = SUM of i=0 -> M for binomial(prob_failure = P, trials = N, failures = i)`
- 每个区块的碎片: `G`
- 区块成功率: `B = (1 - S) ^(G / N)`
- `i` 的精确结果的双向分布被定义为 `(N choose i) * P^i * (1 - P)^(N-i)`
例如:
- 网络丢包率为 15%。
- 50k Tps 的网络每秒产生 6400个碎片。
- FEC 率增加了每个块按 FEC 笔录的总碎片数。
其中 FEC 率为: `16:4`
- `G = 8000`
- `P=1 - 0.85 * 0.85 = 1 - 0.7225 = 0.2775`
- `S = i 的总和 =0 -> 4 为二项分布(prob_fail= 0.2775, trials = 20, fails = i) = 0.689414`
- `B = (1 - 0.689) ^(8000 / 20) = 10^-203`
其中 FEC 率为: `16:16`
- `G = 12800`
- `S = i 的总和 =0 -> 32 为二项分布(prob_fail= 0.2775, trials = 64, fails = i) = 0.002132`
- `B = (1 - 0.002132) ^(12800 / 32) = 0.42583`
其中 FEC 率为: `32:32`
- `G = 12800`
- `S = i 的总和 =0 -> 32 为二项分布(prob_fail= 0.2775, trials = 64, fails = i) = 0.000048`
- `B = (1 - 0.000048) ^(12800 / 64) = 0.99045`
## 邻居Neighborhoods
以下图表显示不同层中两个邻居之间的相互作用。 若要使邻居瘫痪,就需要从上面的邻居建立足够的节点\(擦除代码+1\)。 由于每个邻居都会从上层一个邻居的多个节点收到碎片, 因此上层网络出现大规模故障,才会产生不完整的数据。
![邻居的内部工作](/img/data-plane-neighborhood.svg)