感谢党,感谢政府,感谢国家!
已经进了Linux-Next,这意味着我们将在Linux-2.6.35中看到他的身影(不用再垂涎FreeBSD的netisr),到时候我们就能够将一个网卡收到的traffic按照5元组的hash值分流到多个CPU、Core或者是Thread上面,而不再发生包处理只pin在一个CPU上,导致不能充分利用多处理硬件的资源,或者是Round-Robin的NIC IRQ调度方式所带来的包乱序问题。
要启用RPS,你需要打开SMP和SYSFS的支持,并且RPS默认是关闭的,你需要在系统启动后将你用来处理包的CPU以bitmap的方式写入/sys/class/net/
/queues/rx-/rps_cpu。例如你用core 0和core 2处理单队列网卡eth0收到的数据包,那么命令是:
$ echo 5 > /sys/class/net/eth0/queues/rx-0/rps_cpu
|
RPS为了保持简单和效率,没有支持按照权重分发,也没有导出计算rxhash值或者是映射skb到CPU的hook,不过这丝毫不能影响我们这些把Linux作为开发平台,而不只是应用平台的人们,因为代码就在那里,改改就可以了。
对于UDP服务应用,比如说memcached,我们可以自己实现一个根据key值将skb映射到CPU的函数,然后就可以在memcached中去掉load distributing的代码,转而改成一个CPU bind一个memcached线程,监听一个独立的UDP端口,比如说CPU0上的线程监听8000,CPU1监听8001...,最后我们再改一下iptables的REDIRECT target,让他将流量重定向到当前CPUID+指定端口。这样也许能提高些性能吧?
对于TCP服务应用来说,因为每个新连接都是不确定的唤醒一个acceptor,所以很多服务器设计都采用了一个专门的acceptor进行连接的分发,如果这个acceptor能知道这个连接是从哪个CPU上来的的话,他的连接分发也就更有导向性,能避免些cache同步等的开销,也许我们能够就此设计一个socket option。偶然发现,UDP服务应用亦能如此炮制。 :)
对于本地是client的情形呢?我们可以设计个cache,记住每个连接发出第一个数据包时的cpuid,然后在skb到cpu的映射函数中从cache查询反向包发出的CPU,这样一个连接就能pin到一个CPU从而减少cache同步开销。
呵呵,我又浮想连篇了,时候不早,该洗洗睡了,有兴趣和需求的朋友自己捣鼓试试吧,我就不在这里纸上谈兵了,晚安!
共产党万岁,政府万岁,祖国万岁!
阅读(6577) | 评论(10) | 转发(0) |