背景

在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源码阅读--流表查询原理的更多相关文章

  1. Mybatis源码分析--关联表查询及延迟加载原理(二)

    在上一篇博客Mybatis源码分析--关联表查询及延迟加载(一)中我们简单介绍了Mybatis的延迟加载的编程,接下来我们通过分析源码来分析一下Mybatis延迟加载的实现原理. 其实简单来说Myba ...

  2. 淘宝数据库OceanBase SQL编译器部分 源码阅读--生成物理查询计划

    淘宝数据库OceanBase SQL编译器部分 源码阅读--生成物理查询计划 SQL编译解析三部曲分为:构建语法树,制定逻辑计划,生成物理执行计划.前两个步骤请参见我的博客<<淘宝数据库O ...

  3. redis 5.0.7 源码阅读——跳跃表skiplist

    redis中并没有专门给跳跃表两个文件.在5.0.7的版本中,结构体的声明与定义.接口的声明在server.h中,接口的定义在t_zset.c中,所有开头为zsl的函数. 一.数据结构 单个节点: t ...

  4. Mybatis源码分析--关联表查询及延迟加载(一)

    Mybatis提供了关联查询映射的功能. 一.一对一关联

  5. ovs源码阅读--元组空间搜索算法

    关于TTS(元组空间搜索算法)的详细介绍可以参考OVS+DPDK Datapath 包分类技术这篇文章,本文只对该篇博客进行简单的介绍,案例和部分图片来自于OVS+DPDK Datapath 包分类技 ...

  6. ovs源码阅读--netlink使用

    netlink netlink socket是一种用于用户态进程和内核态进程之间的通信机制.它通过为内核模块提供一组特殊的API,并为用户程序提供了一组标准的socket接口的方式,实现了全双工的通讯 ...

  7. Yii2.0源码阅读-behavior的实现原理

    Yii2.0中的一个思想就是组件化的思想,所以.大多数的类都直接或间接的继承自yii\base\Component,而组件的三大功能:属性.事件.行为. 行为的目的是为了方便的扩展一个类的功能,而不需 ...

  8. 14 BasicHashTable基本哈希表类(一)——Live555源码阅读(一)基本组件类

    这是Live555源码阅读的第一部分,包括了时间类,延时队列类,处理程序描述类,哈希表类这四个大类. 本文由乌合之众 lym瞎编,欢迎转载 http://www.cnblogs.com/oloroso ...

  9. angular源码阅读,依赖注入的原理:injector,provider,module之间的关系。

    最开始使用angular的时候,总是觉得它的依赖注入方式非常神奇. 如果你跳槽的时候对新公司说,我曾经使用过angular,那他们肯定会问你angular的依赖注入原理是什么? 这篇博客其实是angu ...

随机推荐

  1. C#中Array类

    Array类是C#中所有数组的基类,它是在System命名空间中定义的,Array类提供了各种用于数组的属性和方法

  2. 在CentOS上安装node.js的时候报错:No acceptable C compiler found!解决办法

    在CentOS上安装node.js的时候报错:No acceptable C compiler found! 原因:没有c编译器. 解决办法:安装GCC 命令如下: #yum install gcc ...

  3. LL(1)文法--递归下降程序

    递归下降程序 递归下降程序一般是针对某一个文法的.而递归下降的预测分析是为每一个非终结符号写一个分析过程,由于文法本身是递归的,所以这些过程也是递归的. 以上是前提. Sample 假如给的是正规式子 ...

  4. (解释文)My SQL中主键为0和主键自排约束的关系

    上一篇我们说了关于自排如果主键是0的问题,在这里我搞清楚了原因,导致这种情况是因为在SQL中对自排设置了初始值: 从这里可以看到这两个变量一个是自增的初始值,一个是增量,这里都是1,所以在设置自增的时 ...

  5. 【Mac】解决「无法将 chromedriver 移动到 /usr/bin 目录下」问题

    问题描述 在搭建 Selenium 库 + ChromeDriver 爬虫环境时,遇到了无法将 chromedriver 移动到 /usr/bin 目录下的问题,如下图: 一查原来是因为系统有一个 S ...

  6. MLT的学习理解

    MLT的学习理解 MLT是一个开源的多媒体库,我们的音视频编辑工具,是使用它作为底层支持,某司的'快剪辑'pc版和安卓版,也是用的它. MLT简介 它的GitHub地址,这个库比较老了,现在只有一个作 ...

  7. 第一节 如何用Go实现单链表

    一.概念介绍 下面这副图是我们单链表运煤车队. 每节运煤车就是单链表里的元素,每节车厢里的煤炭就是元素中保存的数据.前后车通过锁链相连,作为单链表运煤车,从1号车厢开始,每节车厢都知道后面拉着哪一节车 ...

  8. Mac配置MySql

    MySql在Mac下的情况如下: 首先,我们进入MySql的官网下载MySql(直接点击即可),打开之后便是这样. 我们点击红色方框标记的内容,之后我等待下载完成. 下载完成之后,我们需要点点,注意一 ...

  9. 20155211 《Java程序设计》实验四 Android程序设计

    20155211 <Java程序设计>实验四 Android程序设计 一.实验内容及步骤 1.Android Stuidio的安装测试: 安装 Android Stuidio 完成Hell ...

  10. 20155306 实验四 Android程序设计

    20155306 实验四 Android程序设计 实验内容 1.基于Android Studio开发简单的Android应用并部署测试; 2.了解Android.组件.布局管理器的使用: 3.掌握An ...