劣币驱良币的 pacing 之殇
都说 pacing 好 burst 孬(参见:为啥 pacing),就像都知道金币好,掺铁金币孬一样。可现实中掺铁的金币流通性却更好,劣币驱良币。劣币流通性好在卖方希望收到别人的良币而储存,而自己作为买方只使用劣币。
burst 和 pacing 的关系也一样,都希望别人采用 pacing 策略,一旦有人 pacing,自己却 burst 加塞。在高速公路上,都希望别人 200 米车距,自己去加塞。仔细比较这些对弈双方,结论很有趣。
善者假设适用于自主系统,具有同类约定或共识,无罪则无罚,这是不稳定系统,因为一旦有投机者进入系统,假设无罪无罚的善者只能被毒打,而投机假设则适用于几乎所有自组织系统,只有贪婪自私和罪与罚,最后系统收敛到收益和代价之间,这是稳定系统,新来者进入这个系统,最终都会收敛。
我们的世界到处都是活泼开放的投机系统,善者系统反是非常态,死气沉沉。在一个活泼开放的系统中,到处都是投机,试探,收获,遇险,大概都是窦唯《高级动物》里的词,多是贬义,这是劣币之劣,但却是世界的本真。
本文侧重分析 burst 和 pacing 间劣币驱良币的过程。
reno/cubic 的 aimd 行为会被 pacing 改变。aimd + pacing 将形成一个闭环反馈:pacing_rate = cwnd / rtt,等号两边相生。
pacing_rate 达到瓶颈带宽后将稳定下来。增加 cwnd 将带来 queuing delay 等比例增加而维持 pacing_rate 不变,pacing_rate = link_rate 趋于排空 buffer,最终 inflight = pacing_rate * rtt,reno/cubic 等 aimd 流跳出 cwnd limited,cwnd 不再增加。
因此,reno/cubic + pacing 流不再填充 buffer,不再产生 buffer overflow 信号以驱动 aimd。
若有流量退出腾出共享带宽,由于 pacing_rate 和 inflight 相生,没有任何信号触发当前 aimd 流增加 inflight,也就无法 probe 空闲带宽,趋向死寂。
若有新流侵入却不至于丢包的 queuing 情形,本地维护的 cwnd 不变,pacing_rate = cwnd / rtt 由于 rtt 增加而减小意味着发得慢了,进而 inflight 减少,pacing_rate 继续减少。
这表明,根本轮不到 ai 激发 md,背景流作用下,这个闭环反馈自己懂松弛,自动退却。
全链路常规 aimd burst 流量的 buffer overflow 在整个时间序列呈类泊松分布,但无论哪种统计分布,采样次数越多,遭遇 buffer overflow 概率越大,而 pacing 将所有报文在时间序列均匀分布,遭遇 buffer overflow 概率最大,每次都会导致其 cwnd 比例降低,如前述,pacing_rate = cwnd / rtt 这个闭环稳定在 cwnd limited 外,cwnd 在丢包恢复后无法增加。
无论哪种情形,pacing_rate 只能单调递减,趋向跌 0。结论是,pacing 流无法与 aimd 行为相匹配,pacing_rate 与 inflight 相生,阻止 cwnd 的 ai,匡谈 md。
为解决这问题,Linux 引入 net.ipv4.tcp_pacing_ca_ratio 内核参数(即使非 Linux 实现,也必须有类似的措施):
pacing_rate = net.ipv4.tcp_pacing_ca_ratio * (cwnd / rtt)
tcp_pacing_ca_ratio 引入一种 probe 机制,可想而知,它不能比 1 小,甚至不能等于 1,否则 cwnd 将完全无用,但即使大于 1,测量和计算的精度问题以及抖动依然可能将其效果带到 1 以下,pacing_rate 将滑落。默认 1.2,带来非常保守的 probe 效果。
这个 probe 机制以驱动 aimd 运行。但并没解决遭遇 buffer overflow 概率影响 cwnd 增长的问题,增加的 pacing_rate 让 pacing 分布更加密集,遭遇 buffer overflow 概率更大。没有反制拥塞丢包影响的措施,却又完全伸展自己惨烈相迎,自己一直按照 pacing_rate 无 queuing 传输,tcp_pacing_ca_ratio 也只保守 probe,常规的 aimd 退却是对 ai 行为的积累退却,相当于零存整取,但遭遇与自身行为无关(并没有进行有效的 ai)的 buffer overflow 后仍然依照 aimd 原则退就只能一退再退。
谈完 probe 和丢包影响问题,接下来看看被加塞的影响。
pacing 流遭遇 burst 流是个劣币驱良币过程。设带宽为 T,pacing 流连续 2 个报文之间被加塞 n 个 burst 报文,将对 pacing 流引入 (n * 1500) / T 的延时,显然和 burst 量成正比,将引起 inflight 迅速降低而跳出 cwnd limited,这很可怕。换句话说,即使存在 tcp_pacing_ca_ratio probe 参数(即使存在 > 1 的 probe 增益),pacing 流依然很容易跳出 cwnd limited 而进入闭环稳态。
综上,pacing 严重影响 aimd 流的吞吐性能,并使之偏离 aimd 预期行为,不再零存整取而存零整取,取的是代价,更别谈公平收敛,pacing_rate = cwnd / rtt 闭环阻止了自身的 bufferbloat 贡献,pacing 流本身便不会主动(一种忏悔)执行 md(multiplicative-decrease) 收敛动作,被动的 md 纯被欺负。
那么 what about bbr with pacing ?
bbr 自身有状态机驱动 probe 行为,每 8 个 rounds 以 5 / 4 pacing_rate 增益做 probe。但只要是 pacing 流,被 burst 加塞的后果都一样引入 (n * 1500) / T 的延时进而引发 delivery rate 的下滑,被加塞将破坏 bbr 状态机的基本假设以及后续转换,因此 bbr 在一个 window 中不理会实际的测量值,反而坚持该 window 内的 max bandwidth,以此抵抗被动引入的延时,目前这个 window 是 10 rounds。
通过对 reno/cubic,bbr 的 pacing 动力学分析,结合假期最后一天的 高速公路堵车动力学,表明这是个典型的劣币驱良币的 case。无论 reno/cubic 还是 bbr 都需要主动 probe 避免死寂,同时需要某种坚持(persist)缓解被 burst 加塞的伤害,但没有一种良性机制对抗 burst。无奈 pacing 本身就是有价值的松弛策略,面对 burst 被驱逐也是情理之中。
当为传输使能 pacing 时,明明一个好东西,性能却劣化了,大概就是以上原因,网络终究是个劣币驱良币的投机系统。
所以呢,别在 sender host 侧 pacing,pacing 留给网络转发节点做。不 pacing,岂不加重 bufferbloat?但两害相权取其轻,对一厢情愿的 pacing,buffer 不会过分 bloat,我并不是说把 gain * delivery_rate * delivery_interval 全部一次性 burst 出去,可以分多次,定制你自己的 pacing。重要的是,你要知道你在做什么,并知晓后果。
至于数据中心网络,那是另一个故事。rtt 足够小,局域范围,很容易约定并形成大家都遵守的共识,别说 pacing,SDN 可以控制一切,但在广域网,SDN 就不好使,因为 rtt 太长了,反馈周期太久,响应太慢,就不得不接受广域网是一个投机者组成的自组织系统。
皮鞋没有蹬上,露着白袜子。
浙江温州皮鞋湿,下雨进水不会胖。
相关文章:
劣币驱良币的 pacing 之殇
都说 pacing 好 burst 孬(参见:为啥 pacing),就像都知道金币好,掺铁金币孬一样。可现实中掺铁的金币流通性却更好,劣币驱良币。劣币流通性好在卖方希望收到别人的良币而储存,而自己作为买方只使用劣币。 burst 和 pac…...
Gin 中的 Session(会话控制)
Session 介绍 session和cookie实现的底层目标是一致的,但是从根本而言实现的方法是不同的; session 是另一种记录客户状态的机制, 不同的是 Cookie 保存在客户端浏览器中,而 session保存 在服务器上 ; Session 的工作流程 当客户端浏览器第一次访问服务器并发送请求时,服…...
ChatGPT AIGC 实现数据分析可视化三维空间展示效果
使用三维空间图展示数据有以下一些好处: 1可视化复杂性:三维图可以展示三个或更多的变量,一眼就能看出数据各维度之间的关系,使复杂数据的理解和分析变得更为直观。 2检测模式和趋势:通过三维图,用户可以…...
Stable Diffusion 动画animatediff-cli-prompt-travel
基于 sd-webui-animatediff 生成动画或者动态图的基础功能,animatediff-cli-prompt-travel突破了部分限制,能让视频生成的时间更长,并且能加入controlnet和提示词信息控制每个片段,并不像之前 sd-webui-animatediff 的一套关键词控制全部画面。 动图太大传不上来,凑合看每…...
fatal error C1083: 无法打开包括文件: “ta_libc.h”: No such file or directory
用python做交易数据分析时,可以用talib库计算各类指标,这个库通过以下命令安装: pip install TA-Lib -i https://pypi.tuna.tsinghua.edu.cn/simple windows安装时可能出现本文标题所示的错误,可按如下步骤解决: 1、去…...
c 语言基础题目:L1-034 点赞
微博上有个“点赞”功能,你可以为你喜欢的博文点个赞表示支持。每篇博文都有一些刻画其特性的标签,而你点赞的博文的类型,也间接刻画了你的特性。本题就要求你写个程序,通过统计一个人点赞的纪录,分析这个人的特性。 …...
SaaS人力资源管理系统的Bug
SaaS人力资源管理系统的Bug Bug1【18】 这里我是直接把代码复制过来的,然后就有一个空白 这是因为它的代码有问题,原本的代码如下所示 <el-table-column fixed type"index" label"序号" width"50"></el-table…...
GPTQ 和 AWQ:LLM 量化方法的比较
大语言模型(LLM)在自然语言处理(NLP)任务中取得了显著的进展。然而,LLM 通常具有非常大的模型大小和计算复杂度,这限制了它们在实际应用中的部署。 量化是将浮点数权重转换为低精度整数的过程,…...
JVM:虚拟机类加载机制
JVM:虚拟机类加载机制 什么是JVM的类加载 众所周知,Java是面向对象编程的一门语言,每一个对象都是一个类的实例。所谓类加载,就是JVM虚拟机把描述类的数据从class文件加载到内存,并对数据进行校验,转换解析和初始化&a…...
PHP筆記
前言因緣際會下還是開始學習php了。經歷了風風雨雨終於在今年暑假要去加拿大留學了,php會是第二年的其中一門必修課程,加上最近前端也真的蠻心累,也許有一門精進的後端語言,日後轉職會有更寬廣的道路,對自己說加油&…...
IDEA启动报错Failed to create JVM. JVM path的解决办法
今天启动IDEA时IDEA报错,提示如下。 if you already hava a JDK installed, define a JAVA_HOME variable in Computer > Systen Properties > System Settings > Environment Variables.Failed to create JVM. JVM path:D:\ideaIU2023.2.3\IntelliJ IDE…...
源码解析FlinkKafkaConsumer支持周期性水位线发送
背景 当flink消费kafka的消息时,我们经常会用到FlinkKafkaConsumer进行水位线的发送,本文就从源码看下FlinkKafkaConsumer.assignTimestampsAndWatermarks指定周期性水位线发送的流程 FlinkKafkaConsumer水位线发送 1.首先从Fetcher类开始,…...
Nginx:动静分离(示意图+配置讲解)
示意图: 动静分离 动静分离是指将动态内容和静态内容分开处理的一种方式。通常,动态内容是指由服务器端处理的,例如动态生成的网页、数据库查询等。静态内容是指不需要经过服务器端处理的,例如图片、CSS、JavaScript文件等。通过…...
通讯网关软件024——利用CommGate X2Access实现Modbus TCP数据转储Access
本文介绍利用CommGate X2ACCESS实现从Modbus TCP设备读取数据并转储至ACCESS数据库。CommGate X2ACCESS是宁波科安网信开发的网关软件,软件可以登录到网信智汇(http://wangxinzhihui.com)下载。 【案例】如下图所示,实现从Modbus TCP设备读取数据并转储…...
vim工具的使用
目录 vi/vim键盘图 1、vim的基本概念 2、vim的基本使用 3、vim命令模式命令集 4、vim底行模式命令集 5、参考资料 vi/vim键盘图 1、vim的基本概念 vi和vim的区别:vi和vim的区别简单点来说,它们都是多模式编辑器,不同的是vim是vi…...
Docker学习_存储篇
当以默认的方式创建容器时,容器中的数据无法直接和其他容器或宿主机共享。为了解决这个问题需要学习一些Docker 存储卷的知识。 Docker提供了三种存储的方式。 bind mount共享宿主机文件目录volume共享docker存储卷tmpfs mount共享内存 volume* volume方式是容器…...
微信小程序获取当前日期时间
一、直接使用方式 在小程序中获取当前系统日期和时间,可直接拿来使用的常用的日期格式 //1. 当前日期 YYYY-MM-DDnew Date().toISOString().substring(0, 10)new Date().toJSON().substring(0, 10)//2. 当前日期 YYYY/MM/DDnew Date().toLocaleDateString()//3.…...
Unity关键词语音识别
一、背景 最近使用unity开发语音交互内容的时候,遇到了这样的需求,就是需要使用语音关键字来唤醒应用程序,然后再和程序做交互,有点像智能音箱的意思。具体的技术方案方面,也找了一些第三方的服务,比如百度…...
SpringBoot的配置文件——.yml和.properties
目录 1. Spring Boot 配置文件的使用场景 2. 配置文件的两种格式 2.0 特殊说明: 2.1 .properties 2.1.1 格式 2.2.2 缺陷 2.2.3 解决中文乱码的问题 2.2 .yml 2.2.3 格式 配置数据库连接 注意转义字符 编辑 编辑 配置null 配置对象 从.yml读取文件举例 Stud…...
Retrieve Anything To Augment Large Language Models
简介 论文主要介绍了一套通过对比学习和蒸馏学习的方法,来增强学习了embedding向量,然后能够在知识增强,长上下文建模,ICL和工具学习等方面来增强大模型能力。...
JavaSec-RCE
简介 RCE(Remote Code Execution),可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景:Groovy代码注入 Groovy是一种基于JVM的动态语言,语法简洁,支持闭包、动态类型和Java互操作性,…...
TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...
Java入门学习详细版(一)
大家好,Java 学习是一个系统学习的过程,核心原则就是“理论 实践 坚持”,并且需循序渐进,不可过于着急,本篇文章推出的这份详细入门学习资料将带大家从零基础开始,逐步掌握 Java 的核心概念和编程技能。 …...
JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案
JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停 1. 安全点(Safepoint)阻塞 现象:JVM暂停但无GC日志,日志显示No GCs detected。原因:JVM等待所有线程进入安全点(如…...
关键领域软件测试的突围之路:如何破解安全与效率的平衡难题
在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件,这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下,实现高效测试与快速迭代?这一命题正考验着…...
用机器学习破解新能源领域的“弃风”难题
音乐发烧友深有体会,玩音乐的本质就是玩电网。火电声音偏暖,水电偏冷,风电偏空旷。至于太阳能发的电,则略显朦胧和单薄。 不知你是否有感觉,近两年家里的音响声音越来越冷,听起来越来越单薄? —…...
Java求职者面试指南:计算机基础与源码原理深度解析
Java求职者面试指南:计算机基础与源码原理深度解析 第一轮提问:基础概念问题 1. 请解释什么是进程和线程的区别? 面试官:进程是程序的一次执行过程,是系统进行资源分配和调度的基本单位;而线程是进程中的…...
基于Springboot+Vue的办公管理系统
角色: 管理员、员工 技术: 后端: SpringBoot, Vue2, MySQL, Mybatis-Plus 前端: Vue2, Element-UI, Axios, Echarts, Vue-Router 核心功能: 该办公管理系统是一个综合性的企业内部管理平台,旨在提升企业运营效率和员工管理水…...
MySQL:分区的基本使用
目录 一、什么是分区二、有什么作用三、分类四、创建分区五、删除分区 一、什么是分区 MySQL 分区(Partitioning)是一种将单张表的数据逻辑上拆分成多个物理部分的技术。这些物理部分(分区)可以独立存储、管理和优化,…...
【LeetCode】算法详解#6 ---除自身以外数组的乘积
1.题目介绍 给定一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O…...
