概述
Storj是来自美国Storj Labs公司旗下的项目,是在2014年首次被提出的,总共做了两次募资,第一次众筹了约50万美元,在上线测试版之后也就是2017年又进行了一次1CO,这次共筹得了约3000万美元。目前发的ERC20 token,币价近一年翻了30倍 (截止2021/3/30 价格是¥19)。项目的定位是抗审查,不会停机的去中心化的云存储平台。
Storj将运行网络上的所有卫星(访问Tardigrade.io体验,目前有六个卫星),每个卫星的账户、计费等体系都是独立的,一个卫星相当一个存储运营商。但由于创建的软件是开源的,且网络是去中心化的,任何人任何人都可以运行自己的卫星,也可以在可信第三方的卫星上建账户。
角色
-
Client
从网络上传或下载数据的用户或应用程序。 -
Peer类别
网络服务集合。代表我们网络服务的三种peer类别:storage nodes, Satellites, Uplinks. -
Storage node
矿工,参与节点发现,存储数据,根据存储的数据和提供的带宽获取报酬 -
Uplink
这类peer表示实现libuplink的任何应用程序或服务,
它能存储或检索数据。这个peer不会像Storage node 和Satellite一样一直保持在线,它相对轻量。主要执行加密、纠删码编码操作,并代表client与其他peer进行协调。主要实现有libuplink、Gateway、Uplink CLI -
Satellite
作为用户/客户端和存储节点之间的一个中介,它可以促进存储交互,并决定哪个存储节点将存储哪些文件。该类peer参与节点发现系统、缓存节点地址信息、存储每个对象的元数据、维护存储节点信誉、聚合计费数据、支付存储节点费用、执行审核和修复以及管理授权和用户帐户。用户在特定卫星上拥有帐户并信任它们。任何用户都可以运行自己的卫星,但我们希望许多用户选择避免操作的复杂性,并在另一个卫星上创建一个由受信任的第三方(如Storj Labs、朋友、组或工作场所)托管的帐户。
数据
-
bucket
bucket是由路径标识的文件的无边界但命名的集合。每个文件在一个bucket中都有一个唯一的路径。 -
path path是bucket中文件的唯一标识符。path是任意字节字符串。path在访问控制边界处包含正斜杠。正斜杠(称为路径分隔符)分隔path组件。例如videos/carlsagan/gloriousdawn.mp4,其中path组件是videos、carlsagan和gloriousdawn.mp4. 除非另有要求,否则我们会在路径离开客户应用程序的计算机之前对其进行加密。
-
file or object
文件(或对象)是我们系统中的主要数据类型。文件由path引用,包含任意数量的字节,并且没有最小或最大大小。文件由一个或多个Segments的有序集合表示。Segments具有固定的最大大小。文件还支持数量有限的key/value用户定义字段,称为扩展属性。与路径一样,文件中包含的数据在离开客户机之前就被加密。 -
Extended attribute
扩展属性是与文件关联的用户定义的key/value字段。与其他文件元数据一样,扩展属性也是加密存储的。 -
segment
segment表示单个字节数组,介于0和用户可配置的最大segment大小之间 (默认maxSegmentSize=64MiB) -
Remote Segment
Remote Segment是将被纠删码编码并分布在网络上的Segment。Remote Segment大于跟踪其簿记所需的元数据,其中包括诸如存储数据的节点的id之类的信息。(4k以上) -
Inline Segment
内联段是一段足够小的数据,
它比远程段跟踪哪些节点拥有数据所需的相应数据占用更少的空间。(4k下) -
stripe
stripe是segment的进一步细分。stripe是用作加密和纠删码编码边界大小的固定字节数。纠删码编码单独在stripe上进行,而加密可能一次在一小部分stripe上进行。所有segments都加密,但只有 remote segments纠删码编码stripes。stripes是执行审核的单元 -
Erasure Share
当一个stripe进行纠删码编码时,它会生成多个称为Erasure Share的pieces。恢复原始stripe只需要Erasure Share的一个子集。每个Erasure Share都有一个索引,标识它是哪个Erasure Share(例如,第一个、第二个等)。 -
pieces
当Remote Segment的stripe被纠删码编码为Erasure Share时,具有相同索引的该远程段的Erasure Share被串联在一起,并且该串联的Erasure Share组被称为一个piece。如果纠删码编码stripe后有n个Erasure Share,则处理 Remote Segment后有n个piece。第i个piece是该Segment的 stripe中所有第i个Erasure Share的串联 -
Pointer
Pointer是一种数据结构,它要么包含Inline Segment数据,要么跟踪Remote Segment的pieces存储在哪个存储节点上,以及其他每文件元数据。
上传流程
-
当用户想要上传文件时,用户首先开始向uplink实例传输数据。
- uplink为第一个segment选择一个加密密钥和开始随机数,并在流经网络时开始使用经过身份验证的加密方式对传入的数据进行加密。
- uplink链路缓冲区会一直缓存数据,以了解传入的segment,判断它是内联段还是远程段。内联段足够小,可以存储在Satellite本身上。
- uplink向Satellite发送请求,为第一个segment的存储做准备。请求对象包含API凭据(如macaroons、身份证书)。
其余部分将采用远程段,因为远程段涉及完整的技术堆栈。
-
收到请求后,Satellite将:
- 确认上行链路有适当的授权和资金用于请求。uplink必须已经有这个特定Satellite的帐户。
- 选择具有足够资源的存储节点,这些节点符合bucket配置的持久性、性能、地理位置和信誉要求。
- 返回存储节点列表,以及它们的联系信息和不受限制的带宽分配,以及所选的root piece ID。
-
接下来,uplink将获取该信息,并在测量带宽的同时开始与所有选定存储节点并行连接
- uplink将开始将segment分成stripe,然后对每条stripe进行纠删码编码。
- 生成的Erasure Share将在并行传输到每个存储节点时连接成多个pieces。
- 纠删码将配置为对更多的piece进行编码,这将消除长尾效应,并允许uplink取消最慢的上传,从而显著提高可见性能。
- 数据将继续传输,直到达到最大segment大小或stream结束(以较早者为准)。
- 每segment的所有hash将被写入每segment流的末尾。
-
之后,存储节点将存储:最大的受限带宽分配;segment的TTL(如果存在);以及数据本身。数据将通过特定于存储节点的piece ID和委派的Satellite ID进行标识。
如果由于某种原因中止了上传,则存储节点将保留它代表Satellite从客户端uplink接收到的最大受限带宽分配,但会丢弃所有其他相关请求数据。
假设成功:- uplink使用确定性的分层密钥对它为此文件选择的随机加密密钥进行加密。
- uplink会将指针对象上传回Satellite,其中包含以下信息:
- 哪些存储节点最终成功
- 为此segment选择了哪种加密路径–使用了哪种纠删码算法
- 所选piece id
- 加密的加密密钥和其他元数据
- piece hashes的hash
- 签名
-
最后,uplink将继续进行下一个segment,继续处理segment,直到整个流都已完成。每个segment都有一个新的加密密钥,但是该segment的开始随机数比前一个segment 大1。
流中存储的最后一个segment将包含其他元数据:- 流包含多少segment
- segment的大小(以字节为单位)
- 第一个segment的开始随机数
- 扩展属性和其他元数据
存储节点以后会定期将它们作为上载的一部分收到的最大受限带宽分配发送到相应的Satellite进行支付。
如果通过Amazon S3的multipart-upload接口进行了上传,则每个部分都作为segment分别上传。
下载流程
当用户想要下载文件时,首先用户向uplink发送数据请求。然后,uplink通过推测性地请求除了最后一个segment的指针之外的前几个segment的指针,来尝试减少去往Satellite的往返次数。uplink需要最后一个segment指针来了解object(file)的大小,segment的大小和数量以及如何解密数据。在将来的版本中,uplink可能只会告诉Satellite需要哪个字节范围,并且Satellite可以使用适当的segment指针进行响应。
对于请求的每个segment指针,Satellite将:
- 确认uplink有权下载segment指针,并且有足够的资金来支付下载费用。
- 为组成该segment的每个piece生成不受限制的带宽分配。
- 查找指针中列出的存储节点的联系信息。
- 返回请求的segment指针,带宽分配和每个piece的节点联系信息。
uplink将决定对于接收到的数据请求是否需要更多的segment,并在需要时请求其余的segment指针。
- 一旦返回了所有必需的segment指针,如果请求的segment不是内联的,则uplink将启动并行请求,为每个存储的piece对应的erasure share测量存储节点带宽
- 由于并非所有erasure share都是恢复所必需的,因此,通过允许uplink取消最慢的下载,可以消除长尾,并且可以显着提高性能。
- uplink会将检索到的erasure share合并为stripe并解密数据。
如果由于某种原因中止下载,则每个存储节点将保留收到的最大限制带宽分配,但会丢弃所有其他相关请求数据。无论哪种方式,存储节点都将在以后将它们作为下载的一部分收到的最大受限带宽分配发送到适当的Satellite,以供以后付款。
关键设计
- satellite 中心化设计,如何信任satellite
https://www.storj.io/blog/2019/08/so-youre-a-storage-node-operator.-which-satellites-do-you-trust/ - 专注文件存储,没有链,satellite支付系统集成coinpayments,支持信用卡、eth和storj币
- gateway 兼容Amazon S3 ,应用可以无缝切换到storj存储
- 可以选择通过zkSync接收付款,可以极大的降低gas费用(zkSync是基于ZK rollup 技术的L2层以太坊扩展解决方案)
- 移除了Kademlia
https://github.com/storj/storj/blob/86d98f6d0992a75d256caaa21116008a67b51895/docs/design/kademlia-removal.md
https://github.com/storj/storj/pull/2974