理想
ipfs宣称自己是一个基于内容寻址的去中心化存储网络,每个节点只需要存储部分数据,整个存储网络就可以运行起来。其中,内容寻址通过DHT实现,数据交换通过bitswap实现。
现实
简述
1,每个block都需要DHT provide出去
2,当文件很大时,会切割成很多个block
3,DHT网络很慢,无法及时将所有block provide出去
4,其它节点永远无法找到部分block
详述
1,在ipfs中,1个block最大为256KB,当文件超过256KB时,通过IPLD进行切割,构造出1颗Merkel DAG树,以此用来描述这个文件。为了达到去重的效果,默认每个block都会通过DHT provide出去,告诉其它节点本节点提供这个block。
2,provider记录保存在DHT网络中,默认有效期是24h,超过24h就会自动清理,因此需要不断被刷新。
3,DHT是一个慢速网络,按照我们实测数据以及预估,上传一个100G文件,会产生至少40万个block,需要耗时45天。
4,即使你有足够耐心等45天,但是provider记录的默认有效期是24h,也就是说,没等你传完,前面很多block的provider记录已经过期。
5,ipfs默认每隔12h会进行reprovide,刷新DHT网络中的provider记录,但是速度比provide更慢,因此无法及时刷新所有block在DHT网络中的provider记录。
6,ipfs网络中许多block是无法找到的。
解决方案
1,放开block大小的限制,1个文件1个block
这样子确实大大减少provider记录的数量,但ipfs通过bitswap协议传输block,bitswap不支持传输过大的block。
2,只provide root block,不provide content block
这样做也可以大大减少provider记录的数量,实际上, ipfs提供了这个配置选项。但仍然存在一些问题,比如A节点向B节点获取1个大文件,A节点由于某种原因下线了,重启后无法直接连接到B节点,在这种情况下,A节点继续获取那个文件,可能永远也无法完成。
分析:
这个问题的根源在于bitswap只负责执行blockservice的命令,不知道block的具体类型,所有block的解析由IPLD完成。1个block可能是root block,也可能是content block。如果是root block,需要通过IPLD解析后,才能获取到下层的block cid。
因此,如果bitswap能够解析block的类型,这个问题也就迎刃而解了,这样做也可以简化bitswap的实现。