下面所有编译安装操作是以 root 用户权限进行操作
编译安装fastsocket内核
下载代码到/opt目录下
git clone https://github.com/fastos/fastsocket.git
编译安装
下载之后进入其目录
cd fastsocket/kernel
涉及到内核,编译之前需要做一些参数选项配置,使用make config会累死人的。
好几千个选项参数需要一一配置,大部分时间,默认配置就可以。
make defconfig
编译内核
make
内核编译相当耗费时间,至少20分钟时间。之后紧接着是编译所需的内核模块,fastsocket模块:
make modules_install
编译完成之后,最后一条输出,会看到:
DEPMOD 2.6.32-431.17.1.el6.FASTSOCKET
fastsocket内核模块编译好之后,需要安装内核:
make install
上面命令其实执行shell脚本进行安装:
sh /opt/fastsocket/kernel/arch/x86/boot/install.sh 2.6.32-431.17.1.el6.FASTSOCKET arch/x86/boot/bzImage \ System.map "/boot"
基本上,fastsocket内核模块已经构建安装完毕了,但需要告知Linux系统在下次启动的时候切换到新编译的、包含有fastsocket模块的内核。
配置启动时需要切换的内核
这部分需要在/etc/grup.conf中配置,现在看一下其文件内容:
default=1
timeout=5
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
title CentOS (2.6.32-431.17.1.el6.FASTSOCKET)
root (hd0,0)
kernel /vmlinuz-2.6.32-431.17.1.el6.FASTSOCKET ro root=/dev/mapper/vg_centos6-lv_root rd_NO_LUKS rd_NO_MD rd_LVM_LV=vg_centos6/lv_swap crashkernel=auto LANG=zh_CN.UTF-8 rd_LVM_LV=vg_centos6/lv_root KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet
initrd /initramfs-2.6.32-431.17.1.el6.FASTSOCKET.img
title CentOS (2.6.32-431.el6.x86_64)
root (hd0,0)
kernel /vmlinuz-2.6.32-431.el6.x86_64 ro root=/dev/mapper/vg_centos6-lv_root rd_NO_LUKS rd_NO_MD rd_LVM_LV=vg_centos6/lv_swap crashkernel=auto LANG=zh_CN.UTF-8 rd_LVM_LV=vg_centos6/lv_root KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet
initrd /initramfs-2.6.32-431.el6.x86_64.img
defautl=1 ,表示目前系统选择的以原先内核作作为启动项,原先位于第二个 root (hd0,0) 后面,需要切换到新的内核下面,需要修改 default=0 ,保存后,reboot重启系统,使之生效。
检测生效
系统重启后,需要加载fastsocket模块到系统运行中去,下面以默认选项参数方式加载:
modprobe fastsocket
加载之后,列出当前系统所加载模块列表,检查是否成功
lsmod | grep fastsocket
若能看到类似输出信息,表示OK:
fastsocket 39766 0
开始构建libfastsocket.so链接库文件
上面内核模块安装好之后,可以构建fastsocket的动态链接库文件了:
cd /opt/fastsocket/library/
make
可能会收到一些警告信息,无碍:
gcc -g -shared -ldl -fPIC libsocket.c -o libfsocket.so -Wall
libsocket.c: 在函数‘fastsocket_init’中:
libsocket.c:59: 警告:隐式声明函数‘open’
libsocket.c: 在函数‘fastsocket_expand_fdset’中:
libsocket.c:109: 警告:隐式声明函数‘ioctl’
libsocket.c: 在函数‘accept’中:
libsocket.c:186: 警告:对指针赋值时目标与指针符号不一致
libsocket.c: 在函数‘accept4’中:
libsocket.c:214: 警告:对指针赋值时目标与指针符号不一致
最后,可以看到gcc编译之后生成的 libfsocket.so 库文件,说明编译成功。
编译后使用
设置网卡
[root@localhost ~]# cd fastsocket
[root@localhost fastsocket]# scripts/nic.sh -i eth0
加载libfsocket.so并运行openresty
Fastsocket is enabled by preloading a shared library named libfsocket.so when launching an application. For example, ngnix can be started with Fastsocket by:
[root@localhost fastsocket]# cd library
###运行openresty 并加载libfsocket.so
[root@localhost library]# LD_PRELOAD=./libfsocket.so openresty -p
错误处理
执行脚本scripts/nic.sh -i eth3时报错:
echo: write error: Value too large for defined data type
只要是设置 echo 100000000 > /sys/class/net/eth3/queues/tx-32/xps_cpus 以及大于100000000 的数值报错
还有 echo 100000000 > /proc/irq/206/smp_affinity 以及大于100000000 的数值报错
XPS: XPS解决的是一个在多队列网卡场景下才存在的问题:默认情况下当协议栈处理到需要向一个网卡设备发包时,如果是多队列网卡(有多个TX-Queue),会使用四元组hash的方式选择一个TX-Queue进行发送。这里有一个性能损耗是,在多核的场景下,可能会存多个核同时向一个TX-Queue发送数据的情况,因为这个操作需要写相应的tx_ring等内存,会引发cache line bouncing的问题,带来系统整体性能的下降。而XPS提供这样一种机制,可以将不同的TX-Queue固定地分配给不同的CPU集合去操作,这样对于某一个TX-Queue,仅有一个或少数几个CPU核会去写,可以避免或大大减少冲突写带来的cache line bouncing问题
smp_affinity: 但我们也曾发现过例外,虽然两块网卡的中断请求被调度到2个core上,但它们是超线程技术对同一物理core虚拟出的2个逻辑core,并不能有效地并行处理。
解决方法是手工配置中断亲和(绑定中断号与具体的core),如下命令:
echo 02 > /proc/irq/123/smp_affinity