本项目利用java多线程完整仿真了Pbft共识算法,并实现了请求执行时间、网络吞吐量的数据获取与图表绘制!
项目最初来源:
方维维,王子岳,宋慧丽,王云鹏,丁毅. 一种面向区块链的优化PBFT共识算法[J]. 北京交通大学学报, 2019, 43(5): 58-. FANG Weiwei, WANG Ziyue, SONG Huili, WANG Yunpeng, DING Yi. An optimized PBFT consensus algorithm for blockchain. Beijing Jiaotong University, 2019, 43(5): 58-.
https://github.com/fangvv/SPBFT
本项目借用了以上项目的源码,但经过一周的钻研,此SPBFT算法在java多线程仿真环境下,Linux系统上,不可能达到文章中降低请求执行时延的效果;在真实网络处理环境下,时延的降低效果也微乎其微。
分析如下:
论文提出的SPBFT算法通过主节点向网络共识节点发验证消息,收集共识节点返回的验证消息,达到验证条件主节点便向所有节点发确认消息,网络共识节点收到消息便向发出请求的节点回复记录成功消息。与PBFT算法相比,SPBFT算法通过主节点负责主要的验证过程,降低了网络消息处理量,由此得出请求处理时间会因此降低的结论。
-
多线程执行逻辑属于并发,非并行,我们可以借用多线程技术在宏观上模拟多节点并行执行网络验证消息,但在实际仿真中,同一时刻,只有一个节点在处理消息。
-
Linux系统上java线程切换的时间片推断是5ms左右,原项目的网络节点延迟在10~60ms,相对而言,高速切换的线程近似模拟了并行处理,在这点上,确实一定程度上对PBFT进行了有效仿真。
-
SPBFT与PBFT在java多线程仿真下,所有节点的消息处理都受制于上一阶段,若上一阶段消息未满足条件,那此消息便不会进行下一阶段。
-
Request阶段,两者时延明显一致;
-
Preprepare阶段,都是主节点向其他节点publish消息,时延同样一致;
-
SPBFT在Prepare阶段出现“掉队”
时间片大小明显小于单次节点任务执行时间,所以消息的一个阶段需要花费多轮时间片轮回才可完成。也就是这点,由于SPBFT的第三阶段要求收到所有节点的确认消息比PBFT多了1/3,回复时延较低的2/3节点花费更少的时间片轮回便满足了PBFT下一阶段的执行条件,PBFT进入下一阶段,SPBFT继续在此阶段轮回,SPBFT便在此阶段出现“掉队” 。
- 最后两个阶段Commit和Reply阶段,SPBFT的时延减少对Prepare阶段的“掉队”进行了有效“回填”:
SPBFT在Commit阶段仅是主节点发布消息,之后其他节点收到后直接回复Request节点,两阶段间不存在“排队”情况,两个阶段可以同时进行; 而PBFT在Reply阶段需要受制于Commit阶段,需要在Commit阶段N节点向N节点publish消息,以获取满足条件从而进入下一阶段。 所以,SPBFT执行到使Reply阶段能够返回 f+1 条Reply消息时,此请求便宣告结束;而PBFT则需要执行到使Reply阶段每个节点收到2/3的投票通过消息,才可进入Reply阶段,之后Reply阶段执行到能够返回 f+1 条Reply消息,才能结束此次请求。
虽说PBFT需要N节点向N节点publish消息,执行任务明显多。但多线程时间片切换的工作方式:PBFT需要多轮时间片不断切换以达到N节点publish消息,但SPBFT同样是多轮时间片不断切换,一个时间片内无法处理完主节点的publish任务,然后切换到其他节点,无法及时完成publish任务。这就导致最后两个阶段,SPBFT并没有以过于明显的优势减少太多的时延。
- 由以上分析可见,SPBFT出现“掉队”与“回填”,都是由于多线程执行机理是时间片轮回的并发,真正的并行执行,不会出现以上两种情况! 如果在真实网络环境下,消息处理任务对节点的处理能力来说是轻便的,任务量减少并不会大幅降低消息的处理时长。所以,如果在真实应用中,时延问题并不会得到明显优化。
综上所述,可以得出结论:多线程并发技术无法对PBFT进行完全有效的仿真,仿真结果甚至会得出违背现实的结论!
所以,移除了原项目中SPBFT的部分,保留成熟的PBFT算法,希望以后能有机会优化PBFT算法