所有的代码逻辑基于openvswitch-2.11.1。

流表管理线程

OVS启动的时候会通过udpif_start_threads创建n_revalidators个线程udpif_revalidator来删除流表,创建n_handlers个线程udpif_upcall_handler来下发流表。

n_revalidator和n_handlers可以通过OVS进行配置,分别是n-revalidator-threads和n-handler-threads。

n_revalidator未配置,n_handlers已配置:n_revalidator = cpu_num(cpu个数) - n_handlers。

n_revalidator已配置,n_handlers未配置:n_handlers = cpu_num - n_revalidator。

均为未配置:n_revalidator = cpu_num / 4 + 1; n_handlers = cpu_num - n_revalidator。

流表删除

流表分为手动删除和自动删除,这里只看自动删除。

请输入图片描述

udpif_revalidator删除流表时,有两种类型的线程:leader和normal线程,以下是两种线程的操作流程:

以上是整体流程,这其中有几个指标需要注意一下:

  1. 合理的流表数(flow_limit)如何判定,默认值是20w,当然也是支持配置的,并且配置方式比较灵活,此处不介绍。
    flow_limit的值是一直动态调整的过程,取决于上面记录的整个流程的总时间(dump_duration毫秒),即所有线程完成dump流表以及流表操作的时间。其计算方式如下:
    if (dump_duration > 2000) flow_limit /= dump_duration / 1000; 此时ovs也会日志报警。
    elif (dump_duration > 1300) flow_limit = flow_limit * 3 / 4;
    elif (dump_duration < 1000 && flow_limit < n_flows * 1000 / duration) flow_limit += 1000; n_flows表示leader dump出来的流表数量
    其中flow_limit是有区间的,1000-200000条之间波动。
  2. 流表是否需要删除是怎么判定的,这里主要关注max-revalidator和max-idle两个配置项指标。

    1. dump_duration > max-revalidator / 2,则删除流表,所以这个参数直接了当的影响到流表的删除。
    2. ovs中有两个超时时间(idle和hard),idle timeout是指该流表没有报文命中之后多长时间超时,hard timeout是指该流表创建之后多长时间超时,目前这里只讨论idle timeout。
      超时时间(duration)和上面提到的flow_limit有关系,计算方式如下:

      1. dump流表数>flow_limit * 2,则所有的流表都要删除。
      2. dump流表数>flow_limit,则所有的流表超时时间都是100ms。
      3. dump流表数<flow_limit,则所有流表的超时时间都是基于配置的max-idle,默认值10s。

      由此可以看出,其实max-idle对流表的删除有一定的影响,但是影响不大,只有最后一种情况有影响。另外删除流表时也要判断流表对应的报文pps,如果pps比较高则也不会删除。取决于min-revalidate-pps,默认值是5.

以下就是删除流表时的操作,这里面每个线程删除流表时,满50个流表则批量删除一次,不满50等到遍历完所有流表后统一删除。

udpif_start_threads-->udpif_revalidator-->revalidator_sweep-->revalidator_sweep__-->push_ukey_ops-->push_dp_ops-->dpif_operate-->dpif_netlink_operate-->try_send_to_netdev-->netdev_ports_flow_del-->netdev_flow_del-->netdev_tc_flow_del-->del_filter_and_ufid_mapping-->tc_del_filter

流表添加

比较复杂,还没看。

调优选项

线程数配置

默认值 n-revalidator-threads + n-handler-threads = cpu_num,其中 n-revalidator-threads 占比 1 / 4,n-handler-threads 占比 3 / 4。

流表的添加删除操作工作量并没有那么大,所以线程数这么多的必要性感觉不大,可以考虑减少一些,比如各配置 4 个,这个配置多少并没有数据支撑。

流表删除调优

流表删除时机对网络的稳定性影响很大,举个简单的例子,一个正常转发的连接突然流表被删除了,这时候该连接瞬间会有大量的报文匹配不到流表,上送到用户态,对ovs的压力很大,造成网络抖动。

max-idle 对流表的删除影响比较小,并且是一定时间内没有报文转发时才会删除,默认值是 10s,所以做不做更改都可以。

max-revalidator 对流表的删除影响比较大,如果流表 dump_duration > max-revalidator / 2,则直接删除流表,而 max-revalidator 默认值是 500ms,很容易触发,所以建议改大到 10s。触发例子比如 dump_duration 会使用 rtnl 锁,如果系统有其他操作和该锁竞争,那么 dump_duration 会耗时比较长,根据现有判断会删除正在使用的流表。

最后修改:2022 年 08 月 08 日
如果觉得我的文章对你有用,请随意赞赏