motool

模拟ceph的内部通信rdma

模拟ceph的内部通信rdma
2022-03-11 · 13 min read
ceph

前言

ceph内部通信是支持rdma的协议的,本篇就是基于网络配置一个soft roce,然后ceph在这个模拟的roce之上进行一个网络的替换,这个主要看是消息部分( "ms_type": "async+rdma"),这个应该是对于超高硬件情况下的性能提升的一种方式,通过rdma的方式降低中间的一些操作的延时

软硬件环境

环境采用的是物理机器进行搭建的,vmware里面的网卡可能比较老,有一些操作不支持,物理机也需要注意下网卡,首先需要搭建好一个集群,然后再进行中间的替换,由于每个版本涉及的参数可能不同,本篇只针对本次实验的版本

网卡

[root@lab102 ~]# lspci |grep Eth
02:00.0 Ethernet controller: Intel Corporation I350 Gigabit Network Connection (rev 01)
06:00.0 Ethernet controller: Intel Corporation 82599ES 10-Gigabit SFI/SFP+ Network Connection (rev 01)

上面的千兆和万兆的网卡都支持

ceph版本

[root@lab101 ~]# ceph -v
ceph version 15.2.16 (d46a73d6d0a67a79558054a3a5a72cb561724974) octopus (stable)

配置方法

ceph可以使用的是roce,而linux现在支持soft roce,所以全套环境的模拟并不需要物理的roce的环境,如果有的话,方法也是类似的

构建一个soft roce环境

加载rdma_rxe模块

我们是要在tcp的常规网卡上面去模拟rdma,所以需要创建一个虚拟的设备,这个功能,在内核的rdma_rxe这个模块里面实现了,从模块的介绍里面可以看到,在网络设备之上创建rxe设备

[root@lab101 ~]# modinfo rdma_rxe
filename:       /lib/modules/3.10.0-1062.el7.x86_64/kernel/drivers/infiniband/sw/rxe/rdma_rxe.ko.xz
license:        Dual BSD/GPL
description:    Soft RDMA transport
author:         Bob Pearson, Frank Zago, John Groves, Kamal Heib
retpoline:      Y
rhelversion:    7.7
srcversion:     4C6835BD434513A2BC5DA96
depends:        ib_core,ip6_udp_tunnel,udp_tunnel
intree:         Y
vermagic:       3.10.0-1062.el7.x86_64 SMP mod_unload modversions
signer:         CentOS Linux kernel signing key
sig_key:        51:08:4E:41:88:03:02:BE:5C:B0:74:AC:0D:A3:FE:10:23:3B:7F:1C
sig_hashalgo:   sha256
parm:           add:Create RXE device over network interface
parm:           remove:Remove RXE device over network interface
[root@lab101 ~]# modprobe rdma_rxe
[root@lab101 ~]# dmesg
[   75.528074] rdma_rxe: loaded

这个在3.10内核里面已经有这个模块了,这个是比较新的内核里面集成的功能,3.10是红帽维护的,所以做了集成,如果是其它版本内核,可以确认下这个模块是否打进去了,没有的话就开启下就行

安装rxe_cfg工具

这个工具是用于配置rxe设备的,新版本的描述是在rdma-core删除掉了rxe_cfg这个工具,然后在iproute2里面实现了这个添加功能,但是我测试那个方式添加失败,这里我们还是用rxe_cfg的方式就行验证,这个本身也只是一个脚本而已

安装软件

yum install libibverbs libibverbs-utils infiniband-diags perftest

查看网卡

[root@lab101 ~]# rxe_cfg status
  Name   Link  Driver  Speed  NMTU  IPv4_addr      RDEV  RMTU
  ens33  yes   e1000          1500  192.168.0.101

这个ens33就是我们准备绑定的网卡

启动rxe_cfg

[root@lab101 ~]# rmmod rdma_rxe
[root@lab101 ~]# lsmod |grep rdma_rxe
[root@lab101 ~]# rxe_cfg start
  Name   Link  Driver  Speed  NMTU  IPv4_addr      RDEV  RMTU
  ens33  yes   e1000          1500  192.168.0.101
[root@lab101 ~]# lsmod |grep rdma_rxe
rdma_rxe              114188  0
ip6_udp_tunnel         12755  1 rdma_rxe
udp_tunnel             14423  1 rdma_rxe
ib_core               255469  13 rdma_cm,ib_cm,iw_cm,rpcrdma,ib_srp,ib_iser,ib_srpt,ib_umad,ib_uverbs,rdma_rxe,rdma_ucm,ib_ipoib,ib_isert

从上面的命令我们可以看到,这个启动的命令是会去把相关的模块加载起来的

创建rxe设备

[root@lab101 ~]# rxe_cfg start
[root@lab101 ~]# rxe_cfg add ens33
[root@lab101 ~]# rxe_cfg status
  Name   Link  Driver  Speed  NMTU  IPv4_addr      RDEV  RMTU
  ens33  yes   e1000          1500  192.168.0.101  rxe0  1024  (3)

[root@lab101 ~]# ibv_devices
  device          	   node GUID
  ------          	----------------
  rxe0            	020c29fffe2aea96
  
[root@lab101 ~]# ibstat rxe0
CA 'rxe0'
	CA type:
	Number of ports: 1
	Firmware version:
	Hardware version:
	Node GUID: 0x020c29fffe2aea96
	System image GUID: 0x0000000000000000
	Port 1:
		State: Active
		Physical state: LinkUp
		Rate: 2.5
		Base lid: 0
		LMC: 0
		SM lid: 0
		Capability mask: 0x00890000
		Port GUID: 0x020c29fffe2aea96
		Link layer: Ethernet  

可以看到已经创建好了这个rxe0的设备,并且后面已经生成了node 的guid

删除设备的命令

rxe_cfg remove ens33

验证通信

这里有多个工具验证通信,之前测试有的工具可以,有的工具不行,后来发现,验证不行的时候,在ceph去通信的时候也会出问题,所以这里要保证下面的这个工具是可以的

可以用这个工具

Server:  ibv_rc_pingpong -d rxe0 -g 0
Client:  ibv_rc_pingpong -d rxe0 -g 0 192.168.0.101

错误的显示是

[root@lab101 ~]# ibv_rc_pingpong -d rxe0 -g 0
  local address:  LID 0x0000, QPN 0x000011, PSN 0xa4fdcc, GID fe80::20c:29ff:fe2a:ea96
Failed to modify QP to RTR
Couldn't connect to remote QP
[root@lab102 ~]# ibv_rc_pingpong -d rxe0 -g 0 192.168.0.101
  local address:  LID 0x0000, QPN 0x000011, PSN 0xe316fe, GID fe80::20c:29ff:fe0d:19c9
client read/write: Protocol not supported
Couldn't read/write remote address

这个时候,需要重启下机器

(上面的错误在vmware上面是存在的,并且没找到办法解决,如果这个问题存在,可以在ceph的log里面看到一个类似的错误日志,提示无法转换状态,所以需要物理机器)

[root@lab101 ~]# ibv_rc_pingpong -d rxe0 -g 0
  local address:  LID 0x0000, QPN 0x0003e4, PSN 0xfe022b, GID fe80::92e2:baff:fe34:52b9
  remote address: LID 0x0000, QPN 0x0000a2, PSN 0x31cbc1, GID fe80::21b:21ff:fe89:4e75
8192000 bytes in 0.13 seconds = 516.40 Mbit/sec
1000 iters in 0.13 seconds = 126.91 usec/iter


[root@lab102 ~]# ibv_rc_pingpong -d rxe0 -g 0 192.168.19.101
  local address:  LID 0x0000, QPN 0x0000a2, PSN 0x31cbc1, GID fe80::21b:21ff:fe89:4e75
  remote address: LID 0x0000, QPN 0x0003e4, PSN 0xfe022b, GID fe80::92e2:baff:fe34:52b9
8192000 bytes in 0.13 seconds = 517.02 Mbit/sec
1000 iters in 0.13 seconds = 126.76 usec/iter

正常的情况应该是上面的这个样的

获取机器的gid

用下面的脚本

[root@lab101 ceph]# cat showgid.sh
#!/bin/bash
black='\E[30;50m'
red='\E[31;50m'
green='\E[32;50m'
yellow='\E[33;50m'
blue='\E[34;50m'
magenta='\E[35;50m'
cyan='\E[36;50m'
white='\E[37;50m'
bold='\033[1m'
gid_count=0
# cecho (color echo) prints text in color.
# first parameter should be the desired color followed by text
function cecho ()
{
echo -en $1
shift
echo -n $*
tput sgr0
}
# becho (color echo) prints text in bold.
becho ()
{
echo -en $bold
echo -n $*
tput sgr0
}
function print_gids()
{
dev=$1
port=$2
for gf in /sys/class/infiniband/$dev/ports/$port/gids/* ; do
gid=$(cat $gf);
if [ $gid = 0000:0000:0000:0000:0000:0000:0000:0000 ] ; then
continue
fi
echo -e $(basename $gf) "\t" $gid
done
}
echo -e "DEV\tPORT\tINDEX\tGID\t\t\t\t\tIPv4 \t\tVER\tDEV"
echo -e "---\t----\t-----\t---\t\t\t\t\t------------ \t---\t---"
DEVS=$1
if [ -z "$DEVS" ] ; then
DEVS=$(ls /sys/class/infiniband/)
fi
for d in $DEVS ; do
for p in $(ls /sys/class/infiniband/$d/ports/) ; do
for g in $(ls /sys/class/infiniband/$d/ports/$p/gids/) ; do
gid=$(cat /sys/class/infiniband/$d/ports/$p/gids/$g);
if [ $gid = 0000:0000:0000:0000:0000:0000:0000:0000 ] ; then
continue
fi
if [ $gid = fe80:0000:0000:0000:0000:0000:0000:0000 ] ; then
continue
fi
_ndev=$(cat /sys/class/infiniband/$d/ports/$p/gid_attrs/ndevs/$g 2>/dev/null)
__type=$(cat /sys/class/infiniband/$d/ports/$p/gid_attrs/types/$g 2>/dev/null)
_type=$(echo $__type| grep -o "[Vv].*")
if [ $(echo $gid | cut -d ":" -f -1) = "0000" ] ; then
ipv4=$(printf "%d.%d.%d.%d" 0x${gid:30:2} 0x${gid:32:2} 0x${gid:35:2} 0x${gid:37:2})
echo -e "$d\t$p\t$g\t$gid\t$ipv4 \t$_type\t$_ndev"
else
echo -e "$d\t$p\t$g\t$gid\t\t\t$_type\t$_ndev"
fi
gid_count=$(expr 1 + $gid_count)
done #g (gid)
done #p (port)
done #d (dev)
echo n_gids_found=$gid_count

执行查询

[root@lab101 ceph]# sh showgid.sh
DEV	PORT	INDEX	GID					IPv4 		VER	DEV
---	----	-----	---					------------ 	---	---
rxe0	1	0	fe80:0000:0000:0000:92e2:baff:fe34:52b9			v2	enp6s0f1
rxe0	1	1	0000:0000:0000:0000:0000:ffff:c0a8:1365	192.168.19.101 	v2	enp6s0f1
n_gids_found=2

可以看到两个,这个地方选择第二个,测试的时候发现第一个不行,使用下面这个带ip的就可以(也就是port 1,index 1)

配置ceph集群

那么需要在ceph里面添加配置文件(写在global就行)

修改配置文件

ms_type=async+rdma
ms_async_rdma_device_name=rxe0
ms_async_rdma_port_num = 1
ms_async_rdma_gid_idx = 1
ms_cluster_type = async+rdma
# ms_async_rdma_roce_ver=2

还需要修改启动的systemctl的文件,这个地方是因为roce 需要一些特殊的设备访问权限,和内存的无锁配置,上面的rxe0就是虚拟出的设备名称

roce_ver这个参数默认是1,我测试的1和2都是可以的,这个可以比对下

需要修改的如下:

/usr/lib/systemd/system/:

ceph-disk@.service
LimitMEMLOCK=infinity

ceph-mds@.service
LimitMEMLOCK=infinity
PrivateDevices=no

ceph-mgr@.service
LimitMEMLOCK=infinity

ceph-mon@.service
LimitMEMLOCK=infinity
PrivateDevices=no

ceph-osd@.service
LimitMEMLOCK=infinity

ceph-radosgw@.service
LimitMEMLOCK=infinity
PrivateDevices=no

修改完成后,重载下

systemctl daemon-reload

添加内存相关配置

[root@lab101 ceph]# cat /etc/security/limits.conf|tail -n 6
# ceph rdma
* soft memlock unlimited
* hard memlock unlimited
root soft memlock unlimited
root hard memlock unlimited
# End of file

修改好了以后重启所有的ceph 进程

那么我们怎么检查是不是启用了rdma了,可以通过下面的几个地方确认

检查配置

[root@lab101 ceph]# ceph daemon osd.3 config show|grep rdma
    "ms_async_rdma_buffer_size": "131072",
    "ms_async_rdma_cm": "false",
    "ms_async_rdma_device_name": "rxe0",
    "ms_async_rdma_dscp": "96",
    "ms_async_rdma_enable_hugepage": "false",
    "ms_async_rdma_gid_idx": "1",
    "ms_async_rdma_local_gid": "",
    "ms_async_rdma_polling_us": "1000",
    "ms_async_rdma_port_num": "1",
    "ms_async_rdma_receive_buffers": "32768",
    "ms_async_rdma_receive_queue_len": "4096",
    "ms_async_rdma_roce_ver": "1",
    "ms_async_rdma_send_buffers": "1024",
    "ms_async_rdma_sl": "3",
    "ms_async_rdma_support_srq": "true",
    "ms_async_rdma_type": "ib",
    "ms_cluster_type": "async+rdma",
    "ms_type": "async+rdma",

可以看到上面的配置都是使用了rdma了

检查效果

检查是不是有rdma的通信记录

开启一个rados bench写入

[root@lab102 ~]# rados -p data bench 10 write

检查消息计数器

[root@lab101 ceph]# ceph daemon osd.3 perf dump AsyncMessenger::RDMAWorker-1
{
    "AsyncMessenger::RDMAWorker-1": {
        "tx_no_mem": 0,
        "tx_parital_mem": 0,
        "tx_failed_post": 0,
        "tx_chunks": 3504,
        "tx_bytes": 247930356,
        "rx_chunks": 5970,
        "rx_bytes": 545746439,
        "pending_sent_conns": 0
    }
}
[root@lab101 ceph]# ceph daemon osd.3 perf dump AsyncMessenger::RDMAWorker-1
{
    "AsyncMessenger::RDMAWorker-1": {
        "tx_no_mem": 0,
        "tx_parital_mem": 0,
        "tx_failed_post": 0,
        "tx_chunks": 4577,
        "tx_bytes": 373838556,
        "rx_chunks": 8254,
        "rx_bytes": 847183076,
        "pending_sent_conns": 0
    }
}

可以看到这个数值发生变化了,说明环境是使用了rdma了

总结

环境是使用的soft roce来实现的ceph 的rdma的功能开启,如果有真实的环境的roce,这个应该差不多,因为ib卡有ib模式和ethnet模式,纯ib模式的是没有ip这个信息的,用gid进行相关的通信,而ceph里面很多信息还是跟ip相关联的,所以这个推测应该使用的是roce模式,也就是以太网之上的rdma协议,并且从参数里面看,也是roce相关的参数

备注

如果需要硬件网卡,可以使用

Mellanox ConnectX-4, ConnectX-4 Lx

参考资料:https://www.nvidia.com/zh-tw/networking/ethernet/connectx-4-lx/

鄂ICP备2022001545号-1