Dragonfly 作为龙蜥社区的镜像加速标准解决方案,是一款基于 P2P 的智能镜像和文件分发工具。它旨在提高大规模文件传输的效率和速率,最大限度地利用网络带宽。在应用分发、缓存分发、日志分发和镜像分发等领域被大规模使用。
现阶段 Dragonfly 基于 Dragonfly1.x 演进而来,在保持 Dragonfly1.x 原有核心能力的基础上,Dragonfly 在系统架构设计、产品能力、使用场景等几大方向上进行了全面升级。
Dragonfly 架构主要分为三部分 Manager、Scheduler、Seed Peer 以及 Peer 各司其职组成 P2P 下载网络,Dfdaemon 可以作为 Seed Peer 和 Peer。详细内容可以参考架构文档(链接见文末),下面是各模块功能:
更多详细信息可以参考 Dragonfly 官网(链接见文末)。
虽然 Dragonfly 的定位是一个基于 P2P 的文件分发系统,但是分发的文件必须是能够从网络上下载的文件,无论是 rpm 包还是容器镜像内容,最终都是有一个地址源的,用户可以通过 dfget 命令向 dfdaemon 发起下载请求,然后 Dragonfly P2P 系统负责下载,如果数据不在其他 Peer 上,那么 Peer 或者 SeedPeer 自己会回源,直接从源下载数据,然后返回给用户。
但是有些场景我们需要分发的数据是某个节点上生成的,不存在一个远端的源地址,这个时候 Dragonfly 就无法分发这种数据了。所以我们希望 Dragonfly 能够增加对这种场景的支持,其实相当于把 Dragonfly 当作了一个分布式的基于 P2P 的缓存和任意数据分发系统。
所以我们设想中的 Dragonfly 缓存系统架构是这样的:
接口设计
dfdaemon 接口
原来的 daemon 接口:
pkg/rpc/dfdaemon/dfdaemon.proto
// Daemon Client RPC Service
service Daemon{
// Trigger client to download file
rpc Download(DownRequest) returns(stream DownResult);
// Get piece tasks from other peers
rpc GetPieceTasks(base.PieceTaskRequest)returns(base.PiecePacket);
// Check daemon health
rpc CheckHealth(google.protobuf.Empty)returns(google.protobuf.Empty);
}
新增 4 个接口:
service Daemon {
// Check if given task exists in P2P cache system
rpc StatTask(StatTaskRequest) returns(google.protobuf.Empty);
// Import the given file into P2P cache system
rpc ImportTask(ImportTaskRequest) returns(google.protobuf.Empty);
// Export or download file from P2P cache system
rpc ExportTask(ExportTaskRequest) returns(google.protobuf.Empty);
// Delete file from P2P cache system
rpc DeleteTask(DeleteTaskRequest) returns(google.protobuf.Empty);
}
scheduler 接口
原来的 scheduler 接口:
// Scheduler System RPC Service
service Scheduler{
// RegisterPeerTask registers a peer into one task.
rpc RegisterPeerTask(PeerTaskRequest)returns(RegisterResult);
// ReportPieceResult reports piece results and receives peer packets.
// when migrating to another scheduler,
// it will send the last piece result to the new scheduler.
rpc ReportPieceResult(stream PieceResult)returns(stream PeerPacket);
// ReportPeerResult reports downloading result for the peer task.
rpc ReportPeerResult(PeerResult)returns(google.protobuf.Empty);
// LeaveTask makes the peer leaving from scheduling overlay for the task.
rpc LeaveTask(PeerTarget)returns(google.protobuf.Empty);
}
新增 2 个接口,下载复用之前的 RegisterPeerTask()接口,删除复用之前的LeaveTask() 接口:
// Scheduler System RPC Service
service Scheduler{
// Checks if any peer has the given task
rpc StatTask(StatTaskRequest)returns(Task);
// A peer announces that it has the announced task to other peers
rpc AnnounceTask(AnnounceTaskRequest) returns(google.protobuf.Empty);
}
接口请求时序图
StatTask
ImportTask
ExportTask
DeleteTask
代码实现
目前代码已经合并,可以在 Dragonfly v2.0.3 版本中使用。
upstream PR:https://github.com/dragonflyoss/Dragonfly2/pull/1227
使用方法
除了增加新的接口之外,我们还增加了一个叫 dfcache 的命令,用于测试,使用方法如下:
- add a file into cache system
dfcache import --cid sha256:xxxxxx --tag testtag /path/to/file
- check if a file exists in cache system
dfcache stat --cid testid --local # only check local cache
dfcache stat --cid testid # check other peers as well
- export/download a file from cache system
dfcache export --cid testid -O /path/to/output
- delete a file from cache system, both local cache and P2P network
dfcache delete -i testid -t testtag
测试方法
通过新增的 dfcache 命令,在一个节点上向 P2P cache 系统中添加不同大小的文件,然后在另外一个节点上针对这个文件做查询、下载、删除等操作。例如:
# dd if=/dev/urandom of=testfile bs=1M count =1024
# dfcache stat -i testid # 检查一个不存在的文件
# dfcache import -i testid testfile
# on another node
# dfcache stat -i testid
# dfcache export -i testid testfile.export
测试效果
两台 ecs,网络走 vpc,带宽 3.45 Gbits/s (约 440MiB/s):
下载的 ecs 磁盘带宽 180MiB/s 左右:
相关阅读链接:
1.Dragonfly1.x 链接地址:https://github.com/dragonflyoss/Dragonfly
2.Dragonfly 架构文档:https://d7y.io/zh/docs/concepts/terminology/architecture/
3.Dragonfly 官网链接:https://d7y.io/
4.龙蜥云原生SIG地址链接:https://openanolis.cn/sig/cloud-native
原文链接
本文为阿里云原创内容,未经允许不得转载。