基于 OS 内核的数据传输有什么弊端
UNIX 的设计初衷其实为电话网络的控制系统而设计的,而不是一般的服务器操作系统,所以,它仅仅是一个数据负责数据传送的系统,没有所谓的控制层面和数据层面的说法,不适合处理大规模的网络数据包。最后 Errata Security 公司的 CEO Robert Graham得出的结论是:
OS 的内核不是解决 C10M 问题的办法,恰恰相反 OS 的内核正式导致 C10M 问题的关键所在。
当网络中大量数据包到来时,会产生频繁的硬件中断请求。
解决方案
- 控制层留给Linux做,其它数据层全部由应用程序来处理。
- 减少系统调度、系统调用、系统中断,上下文切换等
- 摒弃Linux内核协议栈,将数据包传输到用户空间定制协议栈
- 使用多核编程技术替代多线程,将OS绑在指定核上运行
- 针对SMP系统,使CPU尽量使用所在NUMA系统节点的内存,减少内存刷写
- 使用大页面,减少访问
- 采用无锁技术解竞争
而DPDK恰好为我们提供了解决问题的脚手架。
DPDK 官网:http://dpdk.org
DPDK是因特尔推出的数据平面开发组件,主要是提供了一个高效的用户态网卡驱动,改以往网卡驱动采用的中断方式,为绑定线程轮询网卡的高效模式,可以大幅提高吞吐率。
Dpdk是X86平台报文快速处理的库和驱动的集合,不是网络协议栈,不提供二层,三层转发功能,不具备防火墙ACL功能,但通过DPDK可以轻松的开发出上述功能。优势在于通过Dpdk,可以将用户态的数据,不经过内核直接转发到网卡,实现加速目的。
dpdk优势:
- 减少了中断次数。
- 减少了内存拷贝次数。
- 绕过了linux的协议栈,进入用户协议栈,用户获得了协议栈的控制权,能够定制化协议栈降低复杂度
dpdk劣势
DPDK详细介绍分析:https://www.cnblogs.com/bakari/p/8404650.html
Jupiter是一个基于DPDK实现的高性能4层网络负载均衡服务,支持在fullnat工作模式下对TCP和UDP报文转发。jupiter支持的负载均衡算法包括一致性哈希算法,轮询算法,加权轮询算法。
LVS由于基于内核实现,大量并发访问时,频繁系统中断、上下文切换。相同环境下,测试LVS最大70w qps,而jupiter可达200w qps。
tiglabs/jupiter GitHub地址:https://github.com/tiglabs/jupiter
支持的OS发行版本: Centos-7.2或者Centos-7.4。
个人测试,在VMware Workstation上测试,网卡驱动原因是安装不上的。主机上不能划分vlan信息。
yum install numactl-devel kernel-devel libpcap-devel rpm-build
不装kernel-devel会报错:
make: *** /lib/modules/3.10.0-327.el7.x86_64/build: 没有那个文件或目录。
系统没有安装内核开发包,可以看下/usr/src/kernels/,
如果这个目录是空的,就说明没有安装 内核开发包,
如果这个目录非空,你就需要重新做一下连接
# 参考地址 :http://blog.sina.com.cn/s/blog_6f24670f0102wv7p.html
tar -xf jupiter.tar.gz
cd jupiter
make rpm-pkg
rpm -i rpmbuild/RPMS/x86_64/jupiter-0.1-1.x86_64.rpm
jupiter-service的默认配置文件路径是/etc/jupiter/jupiter.cfg
[DPDK]
argv = -c 0xf00 -n 4
[DEVICE0]
name = jupiter0
ipv4 = 1.1.1.2 # 本机Jupiter0 IP、gw信息
netmask = 255.255.255.0
gw = 1.1.1.254
rxqsize = 256
txqsize = 512
mtu = 1500
rxoffload = 0
txoffload = 0
# jupiter采用fullnat模式,这些是后端realserver主机交互的IP。local-ip的个数需要大于jupiter的worker线程数
local-ipv4 = 10.0.2.1/32, 10.0.2.2/32, 10.0.2.3/32, 10.0.2.4/32
pci = 0000:01:00.2 # 网卡的pci。 ethtool -i eth0 | awk '/bus-info/{print $2}'
网卡bond情况:
# 网卡分别查下这些物理卡的pci,填到配置文件的pci字段,用逗号隔开,mode模式选择rr或者active-backup
mode = rr
# 目前日期2018年5月:bond模式支持 0、1
# bond7种模式介绍地址:http://www.cnblogs.com/lcword/p/5914089.html
echo 4096 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages
注:更改网卡驱动,网络会中断,需要有管理IP,或idrac口配置
modprobe uio
insmod /usr/share/jupiter/kmod/igb_uio.ko
# 如果配有ip并且是up状态,需要先down掉,再用脚本绑驱动
/usr/share/jupiter/tools/dpdk-devbind.py --bind=igb_uio eth0
加载KNI模块:
insmod /usr/share/jupiter/kmod/rte_kni.ko
启动jupier-service进程:
jupiter-service --daemon
说一下网络环境:
1、正常环境网段:1.1.1.0/24
2、jupiter主机 1.1.1.2 ' VIP: 10.0.1.1 ' 所以ab-client需要加到10.0.1.0/24的路由
3、采用fullnat模式,所以后端realserver,需要加到上面local-ipv4网段的路由
4、' client 与 realserver 主机IP均指向 jupiter主机IP 。如果是全三层bgp 网络是不用配置静态路由的,会自动学习'
ifconfig eth0 1.1.1.1/24 up
route add -net 10.0.1.0 netmask 255.255.255.0 gw 1.1.1.2
ifconfig eth0 1.1.1.3/24 up
route add -net 10.0.2.0 netmask 255.255.255.0 gw 1.1.1.2
配置虚拟TCP服务10.0.1.1:8888,并添加两个后端服务1.1.1.3:80和1.1.1.4:80.
ifconfig jupiter0 1.1.1.2/24 up
jupiter-ctl vs/add 10.0.1.1:8888 tcp wrr
jupiter-ctl rs/add 10.0.1.1:8888 tcp 1.1.1.3:80 7 # 最后的是权重,rr轮询算法,不需要写这部分
jupiter-ctl rs/add 10.0.1.1:8888 tcp 1.1.1.4:80 7
jupiter-ctl rs/del 10.0.1.1:8888 tcp 1.1.1.5:80 # 删除rs
权重调整
jupiter-ctl rs/weight 10.0.1.1:8888 tcp 1.1.1.3:80 # 查询
jupiter-ctl rs/weight 10.0.1.1:8888 tcp 1.1.1.3:80 0 # 调整
ab http://10.0.1.1:8888/
# 查看网卡驱动
/usr/share/jupiter/tools/dpdk-devbind.py --status
# 如果网卡配有ip并且是up状态,需要先down掉,再用命令绑驱动
# eth0的网卡驱动换成igb_uio
/usr/share/jupiter/tools/dpdk-devbind.py -b igb_uio eth0
# 更改网卡驱动为系统正常驱动
/usr/share/jupiter/tools/dpdk-devbind.py -b igb eth0
# 查看 vip信息
jupiter-ctl vs/list
# 查看 realserver 信息
jupiter-ctl rs/list 10.0.1.1:8888 tcp
# 查看KNI | LOCAL ipv4地址
jupiter-ctl netdev/ipaddr
# 查看NIC包统计信息
jupiter-ctl netdev/stats
# 查看arp地址
jupiter-ctl arp/list
多个jupiter主机实现高可用,需要交换机配置ecmp。支持多个jupiter可以配置相同的vip,但是local ip不能配置一样的。
感谢 tiglabs 团队
jupiter GitHub地址:https://github.com/tiglabs/jupiter
转载请务必保留此出处:https://blog.csdn.net/fgf00/article/details/80629295