场景:测远端RDMA读SSD的带宽,使用InfiniBand网卡
RDMA prepare
RDMA在CPU-DRAM层面的连接是比较常规的,但是对于新手来说容易忽略一些事情,而且这种代码比较繁琐,也没什么所谓的逻辑性,通常是哪里细节之类的没处理好导致寄了
- 在RDMA连接之前,需要先TCP连接,交换彼此的GID/LID/QP等一众元数据,而且是需要双方都互相交换的
- 交换完元数据之后,两侧的RDMA程序都需要将自己的状态转为RTS(Ready to Send),顺序一般是INIT->RTR->RTS
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| read(tcp_fd, &meta, sizeof(meta)); write(tcp_fd, &client_meta, sizeof(client_meta)); ... memset(&attr, 0, sizeof(attr)); attr.qp_state = IBV_QPS_RTS; attr.sq_psn = 0; attr.timeout = 14; attr.retry_cnt = 7; attr.rnr_retry = 7; attr.max_rd_atomic = 1; ret = ibv_modify_qp(qp, &attr, IBV_QP_STATE | IBV_QP_TIMEOUT | IBV_QP_RETRY_CNT | IBV_QP_RNR_RETRY | IBV_QP_SQ_PSN | IBV_QP_MAX_QP_RD_ATOMIC);
|
然后就能连成功了
连成功之后,需要将mmap
的地址传给server.c
的准备给client.c
读的远端地址,这样就可以实现远端通过RDMA网卡读SSD了
双节点自动化脚本
由于RDMA实验需要两台服务器,所以自动化测试脚本需要能够让两个服务器一起启动起来
- 需要先将两台机器的
public_key
互相转给对面的authorized_key
文件中,这样他们就可以通过公私钥配对的方式进行连接
python
的paramiko
库可以用来创建登录远端的ssh
连接,注意和普通的ssh
连接一样,会默认登录的时候处于/home/user
这个目录中!所以建议通过这个自动化脚本执行的其他脚本写绝对路径
1 2 3 4 5 6 7
| ssh_client = paramiko.SSHClient() ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh_client.connect(remote_host, port=remote_port, username=remote_user, key_filename="/path/to/your/private/key")
command = "your command" ssh_client.exec_command(command)
|
server
端脚本,主要是对脚本语言不熟每次都要查循环的语法
1 2 3 4 5 6 7 8 9 10 11 12
| block_size=$((16 * 1024 * 1024)) file_size=$((4 * 1024 * 1024 * 1024)) min_block_size=$((4 * 1024))
while [ $block_size -ge $min_block_size ]; do echo "Testing with block size: $block_size" ./server & ./rdma_test.py -b $block_size -s $file_size sleep 22 block_size=$((block_size / 2)) file_size=$((file_size / 2)) done
|
client
端脚本,之前一直用什么awk
指令,但是估计不太会用所以也没搞出来,后面用正则表达式,$1
为脚本参数
1 2 3 4 5 6
| output=$(/home/weiquan/RDMA-Tutorial/client $1 $2)
bandwidth=$(echo "$output" | sed -n 's/.*Bandwidth: \([0-9.]*\) MB\/s.*/\1/p') latency=$(echo "$output" | sed -n 's/.*latency per block: \([0-9.]*\) us.*/\1/p') iops=$(echo "$output" | sed -n 's/.*iops: \([0-9.]*\).*/\1/p') echo "$2,$bandwidth,$latency,$iops" >> /path/to/your/csv
|
- 给
python
脚本传参的方式:argparse
,具体使用方式见下:
1 2 3 4 5 6 7 8 9
| def main(): parser = argparse.ArgumentParser(description="SSH Key Management and Remote Program Execution") parser.add_argument("-b", "--block_size", type=int, default=2048, help="block size for RDMA") parser.add_argument("-s", "--size", type=int, default=1024, help="file size for RDMA") args = parser.parse_args() block_size = args.block_size size = args.size
|
然后就大功告成了,磨刀不误砍柴工~