网络 buffer 与内存 swap
Posted dog250
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了网络 buffer 与内存 swap相关的知识,希望对你有一定的参考价值。
到底要不要开 swap,几乎一致说不,但仍有人为之辩护:In defence of swap: common misconceptions 。
这文章没站稳立场,承认不要将 swap 作为 emergency memory,承认卡顿,却没找准根因并解决,只寻求 “公平卡顿”,将坏事分摊到所有进程,并引入没完没了地调参。
Swap is primarily a mechanism for equality of reclamation, not for emergency “extra memory”. Swap is not what makes your application slow – entering overall memory contention is what makes your application slow.
文中显示,内存争抢是变慢的原因。case by case 看,文章没错,就像用排队代替争抢一样。但问题是,避免内存争抢才是根本,为什么不提一下应用程序的贪婪呢?
作者接受每个应用程序申请并读写 50GB 内存,并希望利用 swap 让结果不太糟糕,但作者没意识到,问题的根源恰恰在于申请内存太多,而不是满足这么多内存需求的方式不够好。
时代早就变了,“古时候”,由于内存不足导致程序执行失败进而重新载入程序的成本非常高,可现在,如果内存配置就是低,一次少运行几个程序没什么大不了,而再低的内存配置也几乎能满足一个程序的需求。
swap 相关的内存颠簸抖动和网络传输延时抖动相比,无论从原因还是结果看,如出一辙。
网络传输有端到端反馈以提醒 sender 做拥塞控制,而不是承认 sender 的贪婪后想办法最小化其贪婪的恶果。
举个例子。
根治延时抖动之术,大 buffer 加一个好的队列算法,还是小 buffer 加一个好的拥塞控制算法,显然是后者。延时抖动的根源是 buffer,延时的最大方差取决于 buffer 大小,大方差是否引起抖动取决于报文如何到达,好的队列算法只能尽量保证延时公平。
足够久,河里一定会有鱼,这是进化论,也是统计律,足够久,buffer 一定有填满的时刻,也是统计律,因此 buffer 越大,延时一定会增加。所以要有好的拥塞控制算法。
swap 和 buffer 一样,只提供假象,该假象和 buffer 一样具象。buffer 足够大,端可以一直发送而不丢包,但只有带宽才真实。swap 足够大,可满足进程对足够多内存的需求,但只有物理内存才真实。
和好的拥塞控制以效率和公平为目标一致,高尚的做法是高效紧凑使用内存,好的调度算法公平使用内存。
与 buffer 满了丢包不同,内存满了除 OOM 外无法丢弃匿名页,但这并非开 swap 的理由。开篇引用的文章提出的转嫁 I/O 我并不认同,理由很简单,拥有后备存储的 page cache,代码页(简称后备页)等内存是特殊的,与匿名页并不平等。
后备页并非真正的内存页,而作为 cache 临时占用物理内存,剩下的匿名页是才算真正的内存,30GB 的内存装不下 40GB 字节,这是基础事实,正确的做法是将内存扩到 40GB 以上,而不是用 swap 提供假象。因为回收和调入 page cache 造成颠簸无碍,将此事看作 cache 回写和刷新更合适,应该评估这种 cache 在整体上的收益,而不是拉低匿名页效率以求公平性。
开启 swap 在整体上并不能平衡后备页 I/O 造成的颠簸,若不是 page cache,这些页本来是要每次 I/O 的。
10Mbps 带宽铁定无法满足 100Mbps 码率,这个都理解,正确的做法要么购买更大带宽,要么忍受更低品质,而不是增加 buffer。换到内存场景,30GB 的内存就是满足不了 40GB 字节的需求。
为挽救没有后备的匿名内存,应对内存的统计突发申请,要么以足够低的物理内存使用率安排应用程序,要么应用程序自行对匿名内存做后备存储。比如始终保留若干足够大的空闲内存作为 buffer 应对统计突发,越下界则新内存分配失败,越上界则 OOM。
内存抖动的根源在于内存不够大却还要贪婪使用,要么约束应用程序,要么买更大内存。但文章显然不是这个意思。
应对统计突发的时空转换是等价的。
带宽属于时间延展资源,数据会随时间流逝,因此额外空间暂存突发,就是网络节点的 buffer。与之相对,内存属于空间延展资源,数据不会随时间流逝,因此需要额外时间,等内存释放或挪动数据腾出空间,同时要求应用程序尽快释放不使用的匿名页,因此保持一个足够高又不太高的内存使用率可供吸收突发。
为什么 swap 不能像 buffer 吸收网络突发那样吸收内存突发?
网络在汇聚,大收敛,多对一扇入面临的突发内存并不存在,以网络拥塞为例,任何信息均无法第一时间反馈到 sender 而抑制它,若丢包替代排队,sender 无法获取反馈以实施拥塞控制,重传数据更容易淹没网络,小 buffer 配合 AQM 是避免拥塞崩溃的重要一环。内存场景与之不同,内存可第一时间反馈失败,若启用 swap,只是增加颠簸后延迟了失败,远不如快速失败。
借着内存 swap 的反面评述一个人们在本质上相同的两件事上矛盾的做法。很有意思。
“内存抖动的根源在于内存不够大却还要贪婪使用,要么约束应用程序,要么买更大的内存“ 上面这句话换到网络传输场景再说一遍就是 “延时抖动的根源在于带宽不够大却还要贪婪使用,要么约束发送,要么买更大带宽”,前者,人们普遍知道 swap 不好,要关掉,可对后者,人们却依然倾向于部署大 buffer 而不想约束发送。
在我看来,计算机里的进程更具有全局观,统筹全局的就是计算机用户或管理员,而分布式端主机则处于博弈状态。
但无论如何,与网络传输相似,应用程序对内存的使用也存在并需要端到端控制,若每个应用程序拼命申请读写匿名页,OOM 会保证进程级公平性。另一方面,若每个应用程序都企图用更多内存做磁盘的后备 cache,频繁页面回收和调入势必造成所有应用的内存颠簸,一损俱损也公平。但把很多场景糅合在一起,似乎很难保证公平,正如网络传输多个拥塞控制算法混部并存很难保证公平性一样。
大致就是以上的意思,在我看来,文初引用的那篇文章观点不正确,请关掉 swap。
周一下午讨论了一个问题,说是为什么关闭 swap。注意,问题是 “为什么关闭 swap”,而不是 “要不要关闭 swap”,有人不但答非所问,反而贴了一个文章链接而支持打开 swap,此人道不明,似乎是为了反驳而反驳,读了链接的文章,亦不敢苟同。关于 swap 不 swap,一句简单的话,你安装有多大物理内存,就申请多少用量,有多少硬件资源干多大事。打开 swap 只是没事找事。写篇作文记之。
浙江温州皮鞋湿,下雨进水不会胖。
以上是关于网络 buffer 与内存 swap的主要内容,如果未能解决你的问题,请参考以下文章
Linux内存机制以及手动释放swap和buffer和cache
Linux mem/swap/buffers/cached 区别
Linux中buffer/cache,swap,虚拟内存和page ++