Optimización del protocolo de transmisión P2P en Dragonfly

imagen

Texto|Sun Hengke

Universidad Jiaotong de Shanghái

Este artículo tiene 1987 palabras y ha sido leído durante  10 minutos .

01 Optimizar el fondo

Anteriormente, la descarga P2P de Dragonfly adoptaba una estrategia de limitación de velocidad estática y los elementos de configuración relacionados estaban en el  dfget.yaml archivo de configuración:

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

El  límite superior de flujo se perPeerRateLimit establece para una sola tarea y el límite superior de flujo  totalRateLimit se establece para todas las tareas de un solo nodo.

La situación ideal de la política de limitación de corriente estática es:  perPeerRateLimit configurada en 20 M,  totalRateLimit configurada en 100 M y el nodo actualmente está ejecutando 5 o más tareas de descarga P2P, en este caso, puede garantizar que el ancho de banda total de todas las tareas no supere los 100 M , y el ancho de banda se utilizará de manera efectiva.

imagen

La desventaja de esta estrategia de limitación actual es: si perPeerRateLimit se establece en 20M y  totalRateLimit 100M, y el nodo actualmente solo ejecuta una tarea de descarga, entonces la velocidad máxima de descarga de esta tarea es 20M, que es un 80% desperdiciado en comparación con el ancho de banda máximo de Ancho de banda de 100M.

imagen

Por lo tanto, para maximizar el uso del ancho de banda, se requiere una limitación dinámica para garantizar que el ancho de banda total se pueda utilizar por completo cuando la cantidad de tareas sea pequeña y que el ancho de banda se pueda asignar de manera justa cuando la cantidad de tareas sea grande. Al final, diseñamos un conjunto de algoritmos para la limitación dinámica de corriente basados ​​en el contexto. El contexto se refiere al ancho de banda utilizado por cada tarea en el último segundo. Además, el algoritmo también tiene en cuenta factores como el número de tareas, el tamaño restante de las tareas y el ancho de banda garantizado de las tareas. En comparación con el algoritmo de limitación de corriente estática original, se ha mejorado significativamente.

02 Análisis de código relacionado

perPeerRateLimit El elemento de configuración finalmente se asigna a  peerTaskConductor , y el límite de velocidad se realiza  en la   función de by, pt.limiter y   se realiza el trabajo de límite de corriente real, y la capa inferior llama a la función de límite de corriente que viene con Go   .peerTaskConductorDownloadPiece()pt.waitLimit()WaitN()

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

imagen

根据以上分析,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
复制代码

imagen

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

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

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

Finalmente,  peerTaskManager cuando se detiene,  Stop se llama a la función para que deje de ejecutar Traffic Shaper.

05 Resultados de la optimización

Pruebe la mejora del rendimiento de Traffic Shaper en comparación con la estrategia original de limitación de tráfico estático en diversas situaciones, como una sola tarea, varias tareas simultáneas y varias tareas intercaladas. Los resultados de la prueba son los siguientes:

imagen Nota: a menos que se especifique lo contrario, el límite actual para una sola tarea es de 4 KB/s y el límite actual total es de 10 KB/s

Se puede ver que el rendimiento del formador de tráfico mejora significativamente entre un 24 % y un 59 % en comparación con la estrategia de limitación de tráfico estático en el caso de tareas únicas, multitareas inconexas y tareas únicas con poco ancho de banda. En el caso de múltiples tareas concurrentes y múltiples tareas intercaladas, el rendimiento es equivalente al de la estrategia de limitación de corriente estática. En resumen, el experimento demuestra que el modelador de tráfico de muestreo puede resolver la situación de que el ancho de banda total se desperdicia cuando el número de tareas es pequeño y, al mismo tiempo, todavía puede garantizar el mismo efecto que el algoritmo de limitación de corriente estática cuando el número de tareas es grande y otras situaciones complejas.

Enlace PR (fusionado): github.com/dragonflyos…

Lectura recomendada esta semana

Sistema de distribución de archivos e imágenes basado en Dragonfly P2P

HTTP/3(2) en profundidad | SSL no tan aburrido

Pasar la ciudad del código a la nube: práctica de KusionStack

Explicación detallada del canal inverso MOSN

Supongo que te gusta

Origin juejin.im/post/7166472256128811039
Recomendado
Clasificación