使用multi zone的nf conntrack来缓存路由和socket构建高性能处理

前些日子完成了一个extension for nf_conntrack底层基础设施,后来写了一个测试代码,将:
1.一个数据流两个方向的路由结果;
2.如果数据流目的地是本机,则和该流关联的socket;

缓存在了conntrack的extension中。这意味着什么?
        这意味着可以将几乎所有的查找操作都压缩在conntrack的查找中:
1.路由可以保存在conntrack中;
2.socket可以保存在conntrack中;
3.IPSec流量的SA指针可以保存在conntrack中;
4.数据流的描述信息可以保存在conntrack中;
...

这就真的现实,虽然不使用这个技术也能实现如上的诸多种种,但是本文毕竟不是讨论软件工程,也不奢谈所谓的模块化/重用性诸如此类,本文涉及的仅仅是一种选择,多了一种选择,可能善良的人们会因此过得更好或者更不好,但起码比不固定不变更加单调。
        压力似乎落在了conntrack查找的头上。毕竟,我不是在手持了高速ASIC板卡的前提下才说:我实现了Linux的高速cache转发机制。conntrack毕竟是一个软件。但是,也正是由于它是软件,才更加好玩!在此,要提醒转发优化狂人们注意,Linux BOX或者任何中间的三层及3+层设备,一定是为了实现除转发之外的另一种或几种目的的,否则干脆用线缆直连岂不更好(当然,路由器要比硬连线更加灵活,可是不是还有三层交换机的么...单论效率,低层设备永远比高层的更优)?如果你觉得自己通过缓存了路由项而使得数据包可以在PREROUTING或者还没有进入netif_receive_skb的时候被forward,我只能说,不错,水平高,精通Linux协议栈...但是却不一定懂网络...Netfilter的其它钩子难道都是摆样子的吗?审计怎么做?入侵检测怎么采样?流控怎么做?包分类怎么做?...我可以直接把机器关掉让数据包bypass过去吗?
        在我度过了对协议栈本身的痴狂阶段后,我认为着手优化conntrack的查找是一条有点意思且还算正确的路,我并没有企图绕开它,因为很多check都基于它。说了这么多其实就是想说我已经这么做了,并且效果还不错...我的做法就是将一张conntrack分成了好几张,比如每一个L4协议一张,或者更加通用一点,在raw表中为skb分配conntrack表,为此,我修改了内核,在skb中增加了一个字段connmarkidx,然后内置16张conntrack表,由skb的connmarkidx来索引具体的conntrack表。
        然而,和很多次一样,我发现自己做了无用功,因为Linux内核已经支持zone了,这并不需要修改Linux内核为skb增加字段,只需要增加一个conntrack的extend就好了,我回顾了自己的思路,其实我想到了增加一个conntrack extend来保存一些东西,甚至在这样不满足我需求的时候,我想到了设计一个通用的extension of conntrack extend机制来保存任意数据,并且也做到了,但是我为何没有想到用extend机制来将conntrack表扩展成multi conntrack tables呢?我这是在内省自己,但恰恰是内省本身出了问题。真是太讽刺了,我已经知道了该做什么,但是却失败于怎么做,就是因为我对自己过度内省了,却不信任conntrack本身的内省机制:多张conntrack表是conntrack机制内在的,不能用conntrack的extend机制来扩展conntrack本身,它只适合保存一些和conntrack无关的东西...
        看,就是这样,太具讽刺意义。
        好了,现在使用multi zone conntrack机制,加上我的extension for nf_conntrack,我们就可以构建出一个快速转发机制了,该机制只是bypass了可以省去的查找操作而保留了协议栈的所有其它例行逻辑,比如校验码检查,TTL递减,NAT,入侵检测等,办法如下:
1.使用iptables的CT target在raw表中为符合一定matches的skb绑定一个conntrack zone ID;
2.加载我在《在Linux的连接跟踪(nf_conntrack)中缓存私有数据省去每次查找》中的最后给出的实例编译而成的module(可能需要完善);
3.如果panic请debug

        nf conntrack机制自从诞生之日就被很多人诟病,因为它的效率太低,因为它在分给它的连接数份额用尽后会drop掉数据包等...这些都不是问题,首先看它的效率问题,自第一代起,一直到最新的内核版本,conntrack的操作效率可以说一直在持续优化,比如单一spin lock改为了RCU lock,代码互斥区域的变化,lock粒度的变化,加上最为显著的硬件本身的变化。事实上,由于摩尔定律的存在,效率提升是一个无条件的结果,任何以效率为由pass掉某种机制的做法都不是明智的,关键还是要看它能给你带来什么。至于说它有连接数份额的限制,其实你可以从另一个角度来思考这个问题,这难道不是一种防DDos或者防SYN-Flood的方案吗?或者说一个副作用带来有益的效果。你不能单方面认为conntrack有个连接数份额就是对你的系统做了什么限制,要知道,这个连接数的默认值是根据你系统的内存情况精心计算出来的(虽然称作“精心”还真的有点名不副实,但是我相信它会做到!),连接数事实上是一个硬指标,不管你有没有限制它,总是存在的,就算你没有加载conntrack模块,难道你的系统就能处理无限的连接吗?当你的conntrack连接份额默认被计算成比如65535的时候,其实它是想告诉你这个硬限制的存在,即便没有限制,或者说你将它改成了6553500,当连接数大大超过65535的时候,强行进入协议栈的数据包也可能被其它逻辑由于处理不过来而丢弃。虽然这并不是说你试一下就会发生,但是记住,协议栈调优是一个极其复杂的工程化过程,并不是调整某个参数就可以做到完美的。

时间: 2024-11-04 19:32:47

使用multi zone的nf conntrack来缓存路由和socket构建高性能处理的相关文章

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

是查路由表快呢?还是查socket哈希表快?这不是问题的根本.问题的根本是怎么有效利用这两者,让两者成为合作者而不是竞争者.这是怎么回事?       我们知道,如果一个数据包要到达本地,那么它要经过两次查找过程(暂时不考虑conntrack):IP层查找路由和传输层查找socket.怎么合并这两者.       Linux内核协议栈采用了一种办法:在socket中增加一个dst字段作为缓存路由的手段,skb在查找路由之前首先查找socket,找到的话,就将缓存的dst设置到skb,接下来在查找

构建高性能数据库缓存之redis主从复制

一.什么是redis主从复制? 主从复制,当用户往Master端写入数据时,通过Redis Sync机制将数据文件发送至Slave,Slave也会执行相同的操作确保数据一致:且实现Redis的主从复制非常简单. 二.redis主从复制特点 1.同一个Master可以拥有多个Slaves. 2.Master下的Slave还可以接受同一架构中其它slave的链接与同步请求,实现数据的级联复制,即Master->Slave->Slave模式: 3.Master以非阻塞的方式同步数据至slave,这将

(尚042) vue_缓存路由组件

现在About切换后效果: 值不在了,说明About是个新的,要想值存在,About必须是个老的,旧的,被切换时死亡,在切换时重新创建; 要想不死亡,需要将它缓存起来,怎样缓存呢? <keep-alive> <router-view></router-view> </keep-alive> ============================================================= 缓存路由组件对象 1. 理解 1) 默认情况下

Eureka实战-2【构建Multi Zone Eureka Server】

工程pom中公共依赖 <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <spring-clo

《构建高性能web站点》随笔 无处不在的性能问题

前言– 追寻大牛的足迹,无处不在的“性能”问题. 最近在读郭欣大牛的<构建高性能Web站点>,读完收益颇多.作者从HTTP.多级缓存.服务器并发策略.数据库.负载均衡.分布式文件系统多个方面娓娓道来,洋洋洒洒,甚是精彩,想来让人心旷神怡.     但“纸上得来终觉浅,绝知此事要躬行”,要消化本书的内容,绝不是一件简单的事情,更重要的还是实践.在实践和学习的过程中,我会把自己的经验和感悟分享出来,一方面权当做笔记,另一方面,对于后来的童鞋,希望能提供一丝一毫的帮助,不胜欣慰.     由于是读书

在Linux的连接跟踪(nf_conntrack)中缓存私有数据省去每次查找

前面说过很多次,conntrack作为一中连接跟踪机制,如果它本身是可扩展的,那么将会是多么令人激动的一件事,当你看了N多文档代码之后,你发现它确实是可以扩展的,但是却没有感到激动,因为你可能发现:1.它可以注册一个account扩展,但是计数机制却很原始:2.我希望增加一个新型的扩展,却不得不重新编译内核:怎 么办?我曾经很生气地默默指责过当初实现这个的人,想当然的认为将扩展本身也做成可扩展的,而不是写死几个特定的扩展将是一个多么容易的事,我一直憋着没 有去做这个实现,就是因为觉得它太简单,在

Nginx - 代理、缓存

Nginx 标签 : nginx 代理 代理服务可简单的分为正向代理和反向代理: 正向代理: 用于代理内部网络对Internet的连接请求(如VPN/NAT),客户端指定代理服务器,并将本来要直接发送给目标Web服务器的HTTP请求先发送到代理服务器上, 然后由代理服务器去访问Web服务器, 并将Web服务器的Response回传给客户端: 反向代理: 与正向代理相反,如果局域网向Internet提供资源,并让Internet上的其他用户可以访问局域网内资源, 也可以设置一个代理服务器, 它提供

缓存学习笔记-1

    缓存是存储使用频繁数据的临时地方,从而加快系统响应速度.缓存在构建高性能web系统有着很重要的作用.如果要对一个系统进行优化,那么使用缓存是最快最有效的手段. 缓存术语     命中(Cache hit):当客户端发起一个请求(比如说一个产品的信息)时,我们会检测这个产品是否在缓存中,如果没有的话加入到缓存中,反之我们称之为命中了.     漏掉(Cache miss):很简单,虽然在缓存中存在,但是没有客户端请求.这里需要注意亮点     1.如果还有缓存空间,那么,没有命中的对象会被

Openstack安全组与conntrack简介

Openstack中的安全组实现相互信任的虚拟机之间的通信,绑定同一个安全组的虚拟机使用相同的安全策略.安全组作用范围是在虚拟机上,更具体来说是作用在虚拟机的端口而不是网络上.Openstack中安全组基于Iptables实现,由于当前OpenvSwitch(ovs)不能使用iptables rule,所以虚拟机先连接linux bridge,再连接到ovs网桥.参考链接[1]. 使用Iptables时,报文的状态可以归类为四种:NEW ESTABLISEDRELATED INVAILD. Ne