非常有意思的Flowlet

周五了解到一个叫做Flowlet的东西,比较有意思。大体上说来,它是由一个问题而引出的一个解决方案,由于理解还不够深入,所以也暂时只能这么说。

  我先从问题说起。

ISP的动态负载均衡

由于公共骨干网上流量的不确定性,每一条链路的负载不尽相同,为了保证总带宽的最佳利用率,ISP往往会做一些动态负载均衡的策略。如下图所示:

  • 时刻1:
    这里写图片描述

  • 时刻2:
    这里写图片描述

packet负载均衡和flow负载均衡

到底是按照packet做负载均衡呢还是按照一个五元组flow来做负载均衡呢?这是一个问题,很多人在做负载均衡的时候都会面临这个选择问题。

  具体来讲,如果一条flow是强序的,那么基于packet的负载均衡将会导致乱序,这是设备在做负载均衡时要避免的,比如TCP就不能基于packet来做负载均衡,而对于UDP这种协议便可以。

  目前从主机到中间设备,几乎所有的从板卡,网卡队列,到CPU中断,到hash算法,均有机制保证TCP的强序性。

TCP的问题

正是由于TCP是强序的,所以TCP便无法基于packet做负载均衡,也就意味着,只要一条TCP流已经发起了,它就几乎不能再改变底层链路了,至少是最好不要改变底层链路,因为一旦底层链路改变,TCP将增加面临乱序的概率。

幸亏TCP是burst发送

前面我的描述其实隐含了一个假设,即TCP flow的packet是平滑发送的:

这里写图片描述

然而实际上,不管是实际抓包(你可以观测抓包的tcptrace图)还是从具体实现(你可以看30年内任何TCP实现的源码,比如cubic,vegas…)上看,你会发现TCP packet的发送其实是burst的:

这里写图片描述

哈哈,可乘之机!看到两批次burst之间的时间间隙没有,在这种间隙足够大的时候切换下层链路是一个好的时机。这意味着旧链路上的packet均已经离开了链路或者至少将要离开链路,这个时候切换链路将不会造成乱序,不会破坏TCP的强序要求。

  嗯,这就是Flowlet。


Flowlet

一般而言,英文中的“-let”后缀代表“微小”的意思,比如booklet,houselet,以及Java applet…一个Flowlet代表的就是一条小流。如下图所示:

这里写图片描述

在宏观的观感上,可以把一条flow看成是多个flowlet组成的,负载均衡现在就是基于flowlet来进行了,好吧,又引入了一个中间层,它既不是packet,也不是flow,而是大于packet小于flow的flowlet,哈哈,很有意思!

  那么到底如何定量的去切分flowlet呢?这里给出一个公式:

D1,D2αα 已 知 两 条 链 路 的 延 迟 分 别 为 D 1 , D 2 , 设 一 个 数 α , 当 α 满 足 下 面 的 条 件 :
α>|D1D2| α > | D 1 − D 2 |
flow便αflowlet 一 条 f l o w 便 可 以 通 过 α 来 切 割 为 不 同 的 f l o w l e t

α α 建议 50ms 50 m s 应该不错了。

BBR之后一切将不再

我个人觉得flowlet的理念非常Q,perfect,通过一个新的层次解决了强序flow的负载均衡问题。然而它借用了一个TCP实现上的问题或者说是bug,即burst机制。所谓借着坏事干好事。

  在TCP的AIMD模型下,pacing发送几乎是不可能的,因为pacing的计算会破坏AIMD的盲决策,最终的控制模型将会畸变。然而近期Google的研究证明简单的AIMD用于TCP传输其实是错误的,而引入了一中新的BBR pacing传输模型,这个BBR一下子把TCP拥塞控制算法引入了2.0时代!

  我想表达什么?

  在BBR pacing模型下,我们假设BBR已经完美升级到了它应该成为的样子,解决了一系列的失速,误判等问题,届时TCP packet的发送将会是下面的样子:
这里写图片描述
你可能再也捕捉不到那个flowlet中的 α α ,因为pacing rate的精确计算机制不会允许 α α 那么久的空窗期存在!

  但BBR最终至多只是终结了flowlet在TCP上的具体实现,它无法终结flowlet的理念。拥塞控制和负载均衡是两个不同的领域,虽然有所关联但却井水不犯河水,拥塞控制说的是,当发现拥塞,要怎么做,负载均衡说的是,它可以帮忙分担拥塞。

Linux RFS中的影子

上周写的那篇:
合并N个有序链表与FQ公平调度https://blog.csdn.net/dog250/article/details/80234049
我找到了一道面试题或者说作业题在Linux中的影子,在我第一次听闻flowlet的昨天,我想Linux RPS/RFS也有该理念的实现,具体看下面这段代码:

/*
 * If the desired CPU (where last recvmsg was done) is
 * different from current CPU (one in the rx-queue flow
 * table entry), switch if one of the following holds:
 * ...
 *   - The current CPU's queue tail has advanced beyond the
 *     last packet that was enqueued using this table entry.
 *     This guarantees that all previous packets for the flow
 *     have been dequeued, thus preserving in order delivery.
 */
if (unlikely(tcpu != next_cpu) &&
    (...
     ((int)(per_cpu(softnet_data, tcpu).input_queue_head -
      rflow->last_qtail)) >= 0)) {
    tcpu = next_cpu;
    rflow = set_rps_cpu(dev, skb, rflow, next_cpu);
}

后记

非常感激总是有人帮助我让我重新思考技术的本质!今天周六一觉睡到8点半,所以这篇文章到了10点多才分享出来,迟来了,但总比没有好。

  对flowlet理解不深,不到一日而已,如果有需要讨论的,或者说发现我的说法有错误的,希望能及时指出,我会及时回复。

  上午积累了很多的家务事,申请了延后执行,这快到中午了,估计也干不完了,疯子大人和小小马上也就回来了,等待接受批评,但能总结出这篇文章,也算欣慰了。

  • 13
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
好的,以下是一些使用Python实现的有趣的功能示例: 1. 生成彩色文字 使用Python的art库可以生成非常漂亮的彩色文字。例如,下面的代码可以生成彩色的“Hello World”文字: ```python from art import text2art print(text2art("Hello World", font='block')) ``` 2. 生成二维码 使用Python的qrcode库可以生成二维码。例如,下面的代码可以生成包含文字信息的二维码,并保存为图片文件: ```python import qrcode img = qrcode.make("Hello World") img.save("qrcode.png") ``` 3. 人脸识别 使用Python的face_recognition库可以进行人脸识别。例如,下面的代码可以识别图片中的人脸,并在人脸上标注出人名: ```python import face_recognition import cv2 # 加载已知人脸的图片 known_image = face_recognition.load_image_file("known.jpg") known_face_encoding = face_recognition.face_encodings(known_image)[0] # 加载待识别的图片 unknown_image = face_recognition.load_image_file("unknown.jpg") face_locations = face_recognition.face_locations(unknown_image) face_encodings = face_recognition.face_encodings(unknown_image, face_locations) # 在人脸上标注出人名 for (top, right, bottom, left), face_encoding in zip(face_locations, face_encodings): matches = face_recognition.compare_faces([known_face_encoding], face_encoding) name = "Unknown" if matches[0]: name = "Known" cv2.rectangle(unknown_image, (left, top), (right, bottom), (0, 0, 255), 2) cv2.putText(unknown_image, name, (left + 6, bottom - 6), cv2.FONT_HERSHEY_SIMPLEX, 1.0, (0, 0, 255), 1) # 显示结果 cv2.imshow("Result", unknown_image) cv2.waitKey(0) cv2.destroyAllWindows() ``` 4. 生成词云 使用Python的wordcloud库可以生成非常漂亮的词云。例如,下面的代码可以生成包含指定文字的词云,并保存为图片文件: ```python from wordcloud import WordCloud import matplotlib.pyplot as plt text = "Hello World, this is a test of word cloud generation using Python" wordcloud = WordCloud(width=800, height=400).generate(text) plt.imshow(wordcloud, interpolation='bilinear') plt.axis("off") plt.savefig("wordcloud.png") ``` 以上是一些使用Python实现的有趣的功能示例,希望对你有帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值