当前位置: 首页 > news >正文

Linux内核协议栈的socket查找缓存路由机制

是查路由表快呢?还是查socket哈希表快?这不是问题的根本。问题的根本是怎么有效利用这两者,让两者成为合作者而不是竞争者。这是怎么回事?
       我们知道,如果一个数据包要到达本地,那么它要经过两次查找过程(暂时不考虑conntrack):IP层查找路由和传输层查找socket。怎么合并这两者。
       Linux内核协议栈采用了一种办法:在socket中增加一个dst字段作为缓存路由的手段,skb在查找路由之前首先查找socket,找到的话,就将缓存的dst设置到skb,接下来在查找路由的时候,发现已经有了dst,就省去了路由查找的过程。
       问题是,socket的dst字段什么时候设置的呢?当然是“和该socket相关的第一个skb”到来的时候设置上的,无疑即便这第一个skb找到了 socket,此时的socket上的dst也是NULL,那么它会去老老实实查找路由表,如果找到,则将找到的路由项设置到socket的dst字段。
       这个特性在Linux的实现中叫做ip_early_demux,在内核文档中,描述如下:
ip_early_demux - BOOLEAN Optimize input packet processing down to one demux for
    certain kinds of local sockets.  Currently we only do this
    for established TCP sockets.
    It may add an additional cost for pure routing workloads that
    reduces overall throughput, in such case you should disable it.
    Default: 1
对于forward转发,这个特性必然要降低性能,但是我并不是想说这个显而易见的问题,我想说的有两点:
1.层次cache逻辑
我 们知道,路由查找是一个“尽力而为”的多对一匹配过程,skb和路由entry并不是精确的一一对应关系,因此不能在路由entry中缓存socket, 但是却可以在socket中缓存路由entry,因为socket和skb是一个一一对应的关系(我说的不是TCP listen socket..),同样,我也能在路由cache中缓存socket,因为路由cache和skb也是一一对应的关系。
       然而linux内核还是去掉了路由cache的支持,不过这没关系,只要知道一点就够了:一一对应的精确匹配项可以缓存更加松散的非一一对应的匹配项。如 果将目光移到conntrack,就知道该怎么做了,我曾经将路由entry缓存到了conntrack里面,按照这个逻辑,是合理的,同样 的,socket也可以被缓存到conntrack里面,这一点已经有了iptables相关的match和target。
2.自动还是手动
既 然Linux有了ip_early_demux配置参数,问题就是什么时候开启它而什么时候关闭它。特别是,在你事先不知道有多少包是到达本地,有多少包 是forward的情况下,这个问题显得更加不易回答。此时,是相信管理员的非0即1的配置呢,还是让系统去动态自适应?

       如何统计包显得尤为重要,典型情况下,如果有超过60%的包是到达本地的,那么就开启它,反之则关闭它。ip_early_demux配置参数作为一个全 局的参数并没有什么不好,因为如果不是这样,那么就会出现另一个问题,即如何判断一个包是否要进行early_demux...对于边界非七层设备,一般 而言,流量是分类的,分为管理面流量和数据面流量,对于前者而言,流量的终点就是本地,而对于后者,本机仅仅做forward,如果能事先高效地将包进行 平面分类,那么两个ip_early_demux配置会显得更好,对于带外管理而言,Linux的nsnamespace可以很好地完成这个任务。


 本文转自 dog250 51CTO博客,原文链接:http://blog.51cto.com/dog250/1601786


相关文章:

  • 如何在mes中更新dll文件
  • .NET 设计模式初探
  • DatabaseMetaData的用法(转)
  • bash组织成树型数据结构
  • CentOS 5.4 通过yum升级php到5.3版本的两种方
  • Nginx之不能解析下载站顶部和底部的inc文件
  • 【转】 iphone开发常用代码
  • 学习笔记 124: 预备知识总结
  • Js参数值中含有单引号或双引号解决办法
  • 学习笔记 十五: mariadb
  • mysql 优化几个注意点(非完全统计)
  • Python中的tuple
  • MySQL都有哪些日志?分别都代表什么?
  • Centos 7.4 安装ipython和mysql-python遇到的问题
  • Windows XP SP3 升级故障汇总
  • 【mysql】环境安装、服务启动、密码设置
  • Angular6错误 Service: No provider for Renderer2
  • avalon2.2的VM生成过程
  • Hibernate最全面试题
  • linux学习笔记
  • React Native移动开发实战-3-实现页面间的数据传递
  • UEditor初始化失败(实例已存在,但视图未渲染出来,单页化)
  • ⭐ Unity 开发bug —— 打包后shader失效或者bug (我这里用Shader做两张图片的合并发现了问题)
  • 案例分享〡三拾众筹持续交付开发流程支撑创新业务
  • 道格拉斯-普克 抽稀算法 附javascript实现
  • 使用iElevator.js模拟segmentfault的文章标题导航
  • 源码安装memcached和php memcache扩展
  • kubernetes资源对象--ingress
  • 阿里云ACE认证学习知识点梳理
  • ​​​​​​​ubuntu16.04 fastreid训练过程
  • #{}和${}的区别?
  • #HarmonyOS:基础语法
  • #Linux(权限管理)
  • (2)MFC+openGL单文档框架glFrame
  • (PHP)设置修改 Apache 文件根目录 (Document Root)(转帖)
  • (三维重建学习)已有位姿放入colmap和3D Gaussian Splatting训练
  • (一)kafka实战——kafka源码编译启动
  • (译)2019年前端性能优化清单 — 下篇
  • (转)Linq学习笔记
  • (最简单,详细,直接上手)uniapp/vue中英文多语言切换
  • *Django中的Ajax 纯js的书写样式1
  • .NET 3.0 Framework已经被添加到WindowUpdate
  • .net CHARTING图表控件下载地址
  • .NET Core 版本不支持的问题
  • .net core 实现redis分片_基于 Redis 的分布式任务调度框架 earth-frost
  • .NET 中的轻量级线程安全
  • .net 桌面开发 运行一阵子就自动关闭_聊城旋转门家用价格大约是多少,全自动旋转门,期待合作...
  • .NET6 开发一个检查某些状态持续多长时间的类
  • .net中生成excel后调整宽度
  • @Mapper作用
  • [ C++ ] STL---string类的使用指南
  • []利用定点式具实现:文件读取,完成不同进制之间的
  • [EWS]查找 文件夹
  • [hdu 3065] 病毒侵袭持续中 [AC自动机] [病毒特征码匹配]
  • [JS]数据类型