该系统旨在以分布式方式高性能地分发资源。
系统以网络形式运行,网络中包含两种角色:Tracker 和用户节点(以下简称“节点”)。
节点是系统的主体,负责存储资源,并能够与网络中的其他节点交换资源。 一个网络中有且仅有一个 Tracker,负责追踪网络中各节点所持有的资源情况。
启动tracker
cd tracker
python -m tracker --host 0.0.0.0 --port 8000 --state tracker_state.json --ttl 90
启动node
cd node
cargo run -- --tracker http://127.0.0.1:8000 --host 127.0.0.1 --port 9001 --path ..\file --block-size 512
如果在同一台机器(同一IP)跑多个node,需要设置不同本地端口和不同本地资源文件夹。
网络中存在节点 1、2、3、A、B,以及一个 Tracker。 节点 1、2、3 已经持有文件 X。
A 想知道网络中有哪些文件。 A 从 Tracker 获取到文件 X 的信息。
A 想下载 X。 A 从 Tracker 获取到:节点 1、2、3 均持有 X。
随后,A 分别向 1、2、3 请求 X 的 1/3 数据块。 因此,A 可以以约 3 倍于中心化分发网络的效率下载 X。
B 上传了一个新文件 Y。 B 告知 Tracker:自己持有文件 Y。
A 想下载 Y。 A 从 Tracker 获取到:B 持有 Y。
A 向 B 请求完整的 Y,并完成下载。 随后,A 告知 Tracker:自己也持有文件 Y。
之后,节点 1 也想下载 Y。 1 从 Tracker 获取到:A 和 B 均持有 Y。
1 分别向 A、B 请求 Y 的 1/2 数据块。 因此,1 可以以约 2 倍于中心化分发网络的效率下载 Y。
使用 HTTP 与用户节点通信。
更新时机应为:
- 用户节点刚上线时
- 或固定时间间隔内定期更新
Tracker 监听用户主动发送的更新消息。 消息内容包括用户当前持有的资源索引信息:
- 文件哈希
- 文件名
- 块索引
Tracker 应记录这些信息。 Tracker 不需要对此请求进行响应。
(可选)将记录持久化到文件系统,以便断电后仍能恢复。
用户希望查看分发网络中存储了哪些文件,因此主动向 Tracker 发起请求。
Tracker 监听来自用户的查询请求。 请求内容为:获取所有文件的索引信息。
Tracker 需要查找记录,并返回网络中的文件列表,包括:
- 文件哈希
- 文件名
不需要返回块信息。
用户希望下载某个文件,因此主动向 Tracker 发起请求。
Tracker 监听来自用户的下载请求。 请求内容为某个文件的哈希值。
Tracker 需要查找记录,并返回与该文件相关的信息,包括:
- 所有持有该资源的节点 IP
- 每个节点持有的块索引
用户节点使用 HTTP 与 Tracker 通信,使用 TCP/HTTP 与其他用户节点传输大批量数据。
节点上线时,或每隔固定时间,向 Tracker 更新自己持有的所有资源索引,包括:
- 文件哈希
- 块索引
节点向 Tracker 请求网络中的文件列表。
节点应记录文件哈希与文件名之间的映射关系。 与用户交互时,应尽量仅展示文件名。
同时,应提供查看文件哈希的交互方式,因为网络中可能存在哈希不同但文件名相同的文件。
用户通过文件名(首选)或文件哈希(次要)向 Tracker 请求索引信息。
Tracker 返回结果后,系统应通过负载均衡算法动态计算下载方案,包括:
- 节点 IP
- 对应节点负责的块索引
随后,节点向对应用户节点请求数据。
如果部分节点离线或数据缺失,应在可能的情况下重新更新信息并重新执行负载均衡算法;若无法继续,则报错并终止下载。
(可选)实现进度条功能,实际上非常重要。
- 基本套接字收发
- Tracker 记录功能
- 负载均衡算法
- 文件分块方法
- HTTP Tracker 更新