ovs源码阅读--流表查询原理
背景
在ovs交换机中,报文的处理流程可以划分为一下三个步骤:协议解析,表项查找和动作执行,其中最耗时的步骤在于表项查找,往往一个流表中有数目巨大的表项,如何根据数据报文的信息快速的查找到对应的流表项是ovs交换机的一个重要的功能。
在openflow协议中,支持多级流表的形式,可以类比于将一个复杂的功能进行打散,分解成过个小的功能,实现一个流水线的功能,具体见下图:
上图中可以看到,一个数据报文进入后,会经过多个流表,每个流表负责特定的功能,比如上图中table 1中的流表项只会与数据报文中L2层的信息进行匹配,多个流表的处理使得整个数据报文的查询形成一种流水线的处理方式。
ovs流cache设计
首先需要明确的是,ovs中的多级流表存放在用户空间,内核态存放的是流表的缓存,数据报文进入ovs的时候,首先会查询内核态的缓存信息,如果命中则直接执行相应的动作,否则通过netlink的方式发送到用户空间,用户空间查找多级流表,如果用户态命中则将对应的信息丢给内核态进行缓存,否则查询不到,用户态还要继续将报文的信息丢给控制器,由控制器下发对应的规则,有关ovs和控制器之间的关系可以参见我的上一个博客。
ovs中关于流表的查询经历了三个过程:
microflow cache
microflow cache的思想十分简单,具体见下图:
多级流表的查询过程中,会将报文与每个流表的每个流表项进行匹配,这个过程中耗费的时间是很大的,microflow cache的想法就是将多级流表查询之后的结果按照一定的表项格式直接缓存到内核态中,然后下次同样的数据报文到达时,直接通过hash的方法在内核态中命中,第二次的时间复杂度为$O(1)$,
microflow cache的缺点也很明显:
- 实际存在很多short-lived类型的流量,导致命中率低
- 由于Mircroflow Cache 基于Hash的精确匹配查表,数据头中微小的改动都会导致无法命中cache(如TTL)
Megaflow Cache
虽然基于microflow cache的流表查询方式,能让数据报文第二次命中的时间复杂度达到$O(1)$,但是其真正的性能瓶颈在于用户空间的查询,如何减少数据报文进入用户态,是一个很重要的问题。
为了解决精确匹配的问题,减少数据报文进入用户态,ovs采用了megaflow cache代替了microflow cache的匹配方式,megaflow cache是一种基于TTS(元组空间搜索算法)的实现方式,采用了模糊匹配取代microflow cache的精确匹配,通过增加在内核态中查询的时间(从1次hash查找到k次,仍然是常数时间内,跟TTS算法中表的数量有关),减少数据报文进入用户态的次数,具体会在TTS算法中解释。
一种朴素的megaflow cache实现方式就是,将所有多级流表的级联结果存放在内核态中,如下图:
内核态中存放着一张所有流表级联之后的大表,显而易见,这种做法简单粗暴,但是内存的开销也是巨大的。
一种好的做法是,采用’Lazy‘的方式,如下图所示,数据报文首先通过模糊匹配的方式检索内核中的表,如果所有的表都无法命中,则查询用户态,然后将用户态的查询出的所有表项合并成一条表项,再插入到内核态的表中。
需要注意的是,上图中megaflow cache是一张表,在实际的ovs实现中,因为采用了TTS,所以megaflow cache是多张表形成的链表。
microflow cache+Megaflow Cache
目前版本的ovs采用的是第三种查询方式,也就是结合microflow cache和Megaflow Cache,其中microflow cache作为一级cache,Megaflow Cache作为二级cache,此时microflow cache中存放的不再是多级流表返回的结果,而是上一次在Megaflow Cache中命中的索引。
数据报文到达时,首先通过对报文信息hash,查询microflow cache中是否存放着对应的hash值,如果存在则查询对应hash值所指向的索引,这个索引用来定位对应的Megaflow链表中的某一个元素表,然后再在这个元素表中进行查找。
整体的解释起来可能有点拗口,本人也是第一次写博客,对ovs了解的也不够深入,其中涉及到很多细节也不是很清楚,希望通过分享的形式同大家交流。
参考资料
Pfaff B, Pettit J, Koponen T, et al. The Design and Implementation of Open vSwitch[C]//NSDI. 2015, 15: 117-130.
Open vSwitch流表查找分析
The Design and Implementation of Open vSwitch 作者演讲ppt
作者:yearsj
转载请注明出处:https://www.cnblogs.com/yearsj/p/9519827.html
segmentfault对应博文:https://segmentfault.com/a/1190000016112493
ovs源码阅读--流表查询原理的更多相关文章
- Mybatis源码分析--关联表查询及延迟加载原理(二)
在上一篇博客Mybatis源码分析--关联表查询及延迟加载(一)中我们简单介绍了Mybatis的延迟加载的编程,接下来我们通过分析源码来分析一下Mybatis延迟加载的实现原理. 其实简单来说Myba ...
- 淘宝数据库OceanBase SQL编译器部分 源码阅读--生成物理查询计划
淘宝数据库OceanBase SQL编译器部分 源码阅读--生成物理查询计划 SQL编译解析三部曲分为:构建语法树,制定逻辑计划,生成物理执行计划.前两个步骤请参见我的博客<<淘宝数据库O ...
- redis 5.0.7 源码阅读——跳跃表skiplist
redis中并没有专门给跳跃表两个文件.在5.0.7的版本中,结构体的声明与定义.接口的声明在server.h中,接口的定义在t_zset.c中,所有开头为zsl的函数. 一.数据结构 单个节点: t ...
- Mybatis源码分析--关联表查询及延迟加载(一)
Mybatis提供了关联查询映射的功能. 一.一对一关联
- ovs源码阅读--元组空间搜索算法
关于TTS(元组空间搜索算法)的详细介绍可以参考OVS+DPDK Datapath 包分类技术这篇文章,本文只对该篇博客进行简单的介绍,案例和部分图片来自于OVS+DPDK Datapath 包分类技 ...
- ovs源码阅读--netlink使用
netlink netlink socket是一种用于用户态进程和内核态进程之间的通信机制.它通过为内核模块提供一组特殊的API,并为用户程序提供了一组标准的socket接口的方式,实现了全双工的通讯 ...
- Yii2.0源码阅读-behavior的实现原理
Yii2.0中的一个思想就是组件化的思想,所以.大多数的类都直接或间接的继承自yii\base\Component,而组件的三大功能:属性.事件.行为. 行为的目的是为了方便的扩展一个类的功能,而不需 ...
- 14 BasicHashTable基本哈希表类(一)——Live555源码阅读(一)基本组件类
这是Live555源码阅读的第一部分,包括了时间类,延时队列类,处理程序描述类,哈希表类这四个大类. 本文由乌合之众 lym瞎编,欢迎转载 http://www.cnblogs.com/oloroso ...
- angular源码阅读,依赖注入的原理:injector,provider,module之间的关系。
最开始使用angular的时候,总是觉得它的依赖注入方式非常神奇. 如果你跳槽的时候对新公司说,我曾经使用过angular,那他们肯定会问你angular的依赖注入原理是什么? 这篇博客其实是angu ...
随机推荐
- vlc-android native调试配置
1, 按照官网给出的链接,git clone代码,配置好android sdk,ndk...后运行compile.sh; 2, 出现一个protobuf相关的问题(貌似要求protobuf3),自己去 ...
- 软工之词频统计器及基于sketch在大数据下的词频统计设计
目录 摘要 算法关键 红黑树 稳定排序 代码框架 .h文件: .cpp文件 频率统计器的实现 接口设计与实现 接口设计 核心功能词频统计器流程 效果 单元测试 性能分析 性能分析图 问题发现 解决方案 ...
- LeetCode40.组合总和|| JavaScript
给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合. candidates 中的每个数字在每个组合中只能使用一次. ...
- rman基础知识理解(一)
rman用于对数据库的备份和恢复. 他的命令主要分成两大类:独立命令和批处理命令: 独立命令只能在rman的提示符下执行,主要的命令有: CONNECT CONFIGURE CREATE CATALO ...
- SqlParameter 2
SqlParameter string strSql = "Insert into News(TypeId,NewsCaption,NewsContent) values(@TypeId,@ ...
- react 配置开发环境
一:先自行下载安装node和npm 二:cnpm install create-react-app -g 三:create-react-app my-project 四:cd my-project ...
- swiper在vue中正确的使用方法
1.安装swiper,执行npm install vue-awesome-swiper --save命令 2.在main.js中添加下面三行 import 'swiper/dist/css/swipe ...
- html5手机浏览器启动微信客户端支付实例
html5手机浏览器启动微信客户端支付实例,外部浏览器html5微信支付技术,如何在手机浏览器微信支付,在微信客户端外的移动端网页使用微信支付 首先在微信支付官网https://pay.weixin. ...
- gi的安装和使用
Git的安装 git是什么? git是一种版本控制器,更直白的说,团队开发的时候,管理代码使用的软件 Linux下的安装 yum install git Git的配置 在使用git之前,需要先进行配置 ...
- HxUtils: 批量转换换行符,print2to3
在 windows 和 linux 系统,换行符有时需要转换,其代码文件 HxUntils.py 如下: ''' HxUtils.py 2018 by x01 ''' import os, sys d ...