Dragonfly での P2P 伝送プロトコルの最適化

写真

本文|孫恒科

上海交通大学

この記事には 1987ワードがあり、  10分間読まれています

01 背景を最適化する

以前、Dragonfly の P2P ダウンロードは静的レート制限戦略を採用しており、関連する構成項目は dfget.yaml 構成ファイルにありました。

# 下载服务选项。
download:  
# 总下载限速。  
totalRateLimit: 1024Mi  
# 单个任务下载限速。  perPeerRateLimit: 512Mi
复制代码

フローの 上限はperPeerRateLimit 単一のタスクに対して設定され、フローの上限 totalRateLimit は単一ノードのすべてのタスクに対して設定されます。

静的電流制限ポリシーの理想的な状況は次のとおりです perPeerRateLimit 。20M に totalRateLimit 設定し、100M に設定し、ノードは現在 5 つ以上の P2P ダウンロード タスクを実行しています。この場合、すべてのタスクの合計帯域幅が 100M を超えないようにすることができます。 、帯域幅が有効に使用されます。

写真

この現在の制限戦略の欠点は、perPeerRateLimit 20M と totalRateLimit 100M に設定され、ノードが現在 1 つのダウンロード タスクのみを実行している場合、このタスクの最大ダウンロード速度は 20M であり、最大帯域幅と比較して 80% 無駄になります。 100M 帯域幅。

写真

したがって、帯域幅の使用を最大化するには、動的スロットリングを使用して、タスク数が少ないときに帯域幅全体を完全に利用できるようにし、タスク数が多いときに帯域幅を公平に割り当てる必要があります。最後に, コンテキストに基づいた動的電流制限の一連のアルゴリズムを設計しました. コンテキストとは, 各タスクが過去 1 秒間に使用した帯域幅を指します. さらに, アルゴリズムはタスク数などの要素も考慮に入れます.タスクの残りのサイズ、およびタスクの保証された帯域幅. 元の静的電流制限アルゴリズムと比較して、大幅に改善されています.

02 関連コード分析

perPeerRateLimit 設定項目は最終的に に割り当てられ peerTaskConductor 、速度制限は by の  関数で実行さpt.limiter れ  、実際の電流制限作業が実行され、最下層は Go に付属する電流制限関数を呼び出します  。peerTaskConductorDownloadPiece()pt.waitLimit()WaitN()

TotalRateLimit 配置项则在创建 Daemon 时被赋值给 pieceManager 的pm.limiter ,在 pieceManager 的 DownloadPiece() 和 processPieceFromSource() 函数中用到的 pm.limiter ,而这两个函数都会由 peerTaskConductor 调用,也就是说 P2P 下载会先进行总限速,之后再进行每个任务单独限速。

写真

根据以上分析,Dragonfly 进行任务限速的逻辑为,每个peer task(peerTaskConductor)会有单独的限速 perPeerRateLimit ,同时 pieceManager 会有 TotalRateLimit 的总限速,以此达到单任务单独限流,同时限制所有任务总带宽的效果。

03 优化方案

为了解决此前静态限流算法总带宽利用率不佳的缺点,需要将其改进为动态限流算法,即总带宽限速仍恒定,但每个任务的单独带宽限速需要根据上下文适度、定期调整,已达到最大化利用总带宽、同时相对公平分配带宽的目的。

在经过数个改版后,最终我们确定了根据上下文进行限流的 sampling traffic shaper 动态限流算法。具体方案为,每个任务的单任务限流交由 TrafficShaper 组建进行统一管理, TrafficShaper 维护当前正在运行的所有任务,并且定期(每秒)更新这些任务的带宽。

具体来说,上下文指每个任务在上一秒使用的带宽、每个任务的剩余大小、任务数量、任务保底带宽(不能低于 pieceSize )等因素, TrafficShaper 会根据这些上下文公平地、效率最大化地为每个任务分配其下一秒的带宽(具体分配方案详见下一小节),实现动态限流的效果。

04 优化实现

定义 TrafficShaper 接口如下:

// TrafficShaper allocates bandwidth for running tasks dynamically
type TrafficShaper interface {
   // Start starts the TrafficShaper
   Start()   
   // Stop stops the TrafficShaper
   Stop()   
   // AddTask starts managing the new task
   AddTask(taskID string, ptc *peerTaskConductor)
   // RemoveTask removes completed task
   RemoveTask(taskID string)   
   // Record records task's used bandwidth
   Record(taskID string, n int)
   // GetBandwidth gets the total download bandwidth in the past second
   GetBandwidth() int64
}
复制代码

该接口有两种实现,第一种是 samplingTrafficShaper 即基于上下文的 traffic shaper ,第二种是 plainTrafficShaper 只记录带宽使用情况,除此之外不做任何动态限流工作,用于和 samplingTrafficShaper 对比性能提升。

同时,将相关配置项修改为如下内容:

# 下载服务选项。
download:  
# 总下载限速。
totalRateLimit: 1024Mi
# 单个任务下载限速。
perPeerRateLimit: 512Mi
# traffic shaper类型,有sampling和plain两种可选  trafficShaperType: sampling
复制代码

写真

Traffic shaper 的具体运行逻辑为,由peerTaskManager维护trafficShaper,在创建peerTaskManager时,根据配置初始化trafficShaper,并且调用Start()函数,启动trafficShaper,具体来说,新建time.NewTicker,跨度为 1 秒,也即每秒trafficShaper都会调用updateLimit()函数以动态更新所有任务的带宽限流。

updateLimit() 函数会遍历所有运行中的任务,得出每个任务上一秒消耗的带宽以及所有任务消耗的总带宽,随后根据任务上一秒使用的带宽、任务剩余大小等因素,按比例分配带宽,具体来说首先根据上一秒该任务使用带宽以及该任务剩余大小的最大值确定下一秒该任务带宽,接着所有任务带宽根据总带宽按比例缩放,得到下一秒的真实带宽;同时需要确保每个任务的带宽不低于该任务的 pieceSize ,以免出现持续饥饿状态。

在 peerTaskManager 的 getOrCreatePeerTaskConductor() 函数中,若新建任务,需要带宽,那么调用 AddTask() 更新所有任务的带宽,即按照已有任务的平均任务分配带宽,然后再根据总带宽上限将所有任务的带宽等比例进行缩放;根据平均带宽分配新任务带宽的优势为,避免了已经有一个任务占满了所有带宽,有新任务进来时,带宽会被压缩到很小 **的情况;同时,不是平均分配带宽,而是按需等比例分配,可以确保带宽需求量大的任务仍然带宽最多。在 peerTaskManager 的 PeerTaskDone() 函数中,任务完成,不再占用带宽,调用 RemoveTask() 按比例扩大所有任务的带宽。

最後に peerTaskManager 、停止時に Stop 関数が呼び出され、トラフィック シェーパーの実行が停止されます。

05 最適化結果

単一タスク、複数同時タスク、複数タスク インターリービングなどのさまざまな状況で、元の静的トラフィ​​ック制限戦略と比較して、トラフィック シェーパーのパフォーマンスの向上をテストします。テスト結果は次のとおりです。

写真 注: 特に指定のない限り、1 つのタスクの現在の制限は 4KB/秒、合計の現在の制限は 10KB/秒です。

シングル タスク、マルチ タスク分離、低帯域幅のシングル タスクの場合、トラフィック シェーパーのパフォーマンスが静的トラフィ​​ック制限戦略と比較して 24% から 59% 大幅に改善されていることがわかります。複数の同時タスクと複数のタスクのインターリーブの場合、パフォーマンスは静的電流制限戦略のパフォーマンスと同等です。要約すると、この実験は、タスク数が少ない場合に総帯域幅が浪費される状況をサンプリング トラフィック シェーパーがうまく解決できることを証明しています。タスクの数が多く、その他の複雑な状況。

PR リンク (統合): github.com/dragonflyos…

今週のおすすめ読書

Dragonfly P2P ベースのファイルおよび画像配信システム

詳細な HTTP/3(2) | それほど退屈ではない SSL

コードシティをクラウドに移行 - KusionStack の実践

MOSNリバースチャネルの詳細説明

おすすめ

転載: juejin.im/post/7166472256128811039