使用qemu运行内核并使用Redis-benchmark测试迁移
前情提要:本来在实体机上想进行测试程序检验NUMA节点间的迁移,因为CPU型号问题无法开启NUMA(只有一个NUMA节点)。遂采用师兄的方法:使用qemu虚拟机来运行内核。
下边给出配置过程
编译内核镜像
1、先提前安装一些包
1 2
| sudo apt update && sudo apt upgrade sudo apt-get install git fakeroot build-essential ncurses-dev xz-utils libssl-dev bc flex libelf-dev bison
|
2、下载kernel
3、修改.config
1 2 3 4 5 6 7
| vim ./.config # 将下边两行注释 CONFIG_DEBUG_INFO=y CONFIG_DEBUG_INFO_BTF=y # 将下边一行引号内改为空 CONFIG_SYSTEM_TRUSTED_KEYS="debian/canonical-certs.pem" CONFIG_SYSTEM_REVOCATION_KEYS="debian/canonical-revoked-certs.pem"
|
4、编译
5、安装qemu
1
| sudo apt-get install qemu-system-x86
|
基于ubuntu base构建根文件系统
之前使用busybox会导致其中没有我们需要的bash指令,随使用ubuntu base
1、下载ubuntu base
去清华镜像源或者ubuntu官网,我这里选择的是22.04下的ubuntu-base-23.04-base-amd64.tar.gz
(因为我的ubuntu系统是22.04)
1 2
| cd ~/download wget https://cdimage.ubuntu.com/ubuntu-base/releases/23.04/release/ubuntu-base-23.04-base-amd64.tar.gz
|
2、创建image镜像(此处起名为ubuntu_rootfs.ext4)
下面给出我的方法,在download目录下
1 2
| dd if=/dev/zero of=ubuntu_rootfs.ext4 bs=1G count=30 # 创建30G容量的镜像文件 mkfs.ext4 ubuntu_rootfs.ext4 #格式化为ext4的文件系统
|
3、创建目录作为镜像文件的挂载点,将镜像文件挂在上去
在download目录下
1 2
| mkdir rootfs sudo mount ubuntu_rootfs.ext4 rootfs/
|
4、将ubuntu base解压到rootfs下
1
| sudo tar -zxvf ubuntu-base-22.04-base-amd64.tar.gz -C rootfs
|
5、拷贝主机中的网络配置信息到镜像中,方便后续用apt安装软件
1
| sudo cp /etc/resolv.conf rootfs/etc
|
6、创建mount.sh
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| mnt() { echo "MOUNTING" sudo mount -t proc /proc ${2}proc sudo mount -t sysfs /sys ${2}sys sudo mount -o bind /dev ${2}dev sudo mount -o bind /dev/pts ${2}dev/pts sudo chroot ${2} } umnt() { echo "UNMOUNTING" sudo umount ${2}proc sudo umount ${2}sys sudo umount ${2}dev/pts sudo umount ${2}dev sudo umount ${2} }
if [ "$1" == "-m" ] && [ -n "$2" ] ; then mnt $1 $2 elif [ "$1" == "-u" ] && [ -n "$2" ]; then umnt $1 $2 fi
|
7、执行挂载任务
其中的指令chroot
将rootfs
暂时设置为根目录,并启动终端。
8、安装必要的软件
1 2 3 4 5 6 7 8 9 10 11
| apt update && apt upgrade apt install git vim init linux-image-kvm ...... apt install redis-server #安装redis服务器
# 安装redis-benchmark wget http://download.redis.io/releases/redis-6.0.9.tar.gz tar xzf redis-6.0.9.tar.gz cd redis-6.0.9/src make make install redis-benchmark --help #检测是否安装成功
|
这些软件都将会安装到ubuntu_rootfs.ext4镜像中
9、设置密码等
1 2 3 4
| update-initramfs -u echo root:root | chpasswd echo ttyS0 > /etc/securetty systemctl enable serial-getty@ttyS0.service
|
10、退出卸载镜像
此后我们使用qemu启动这个镜像文件
特殊说明:我们使用qemu启动内核和之后,在里边是无法下载安装东西的,因为没有配置网络这些。因此比如当我们需要安装redis
时,需要执行7、8、10即可
输入exit
退出chroot
使用qemu启动
1、配置启动qemu的脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| ubuntuBaseImage="/home/wufang/download/ubuntu_rootfs.ext4" kernelDir=.
sudo qemu-system-x86_64 \ -enable-kvm\ -machine pc,nvdimm=on -s\ -m 2G,slots=4,maxmem=32G \ -nographic -kernel $kernelDir/vmlinux \ -smp cores=4,threads=1,sockets=2 \ -hda $ubuntuBaseImage \ -object memory-backend-ram,id=mem0,size=1G \ -object memory-backend-ram,id=mem1,size=1G \ -numa node,memdev=mem0,cpus=0-3,nodeid=0 \ -numa node,memdev=mem1,cpus=4-7,nodeid=1 \ -numa node,nodeid=2 -numa node,nodeid=3 \ -object memory-backend-ram,id=nvdimm1,size=4G\ -device nvdimm,memdev=nvdimm1,id=nv1,unarmed=off,node=2 \ -object memory-backend-ram,id=nvdimm2,size=4G\ -device nvdimm,memdev=nvdimm2,id=nv2,unarmed=off,node=3 \ -append "console=ttyS0 crashkernel=712M root=/dev/sda rootfstype=ext4 rw loglevel=8"\ -net nic -net tap,ifname=tap0,script=no,downscript=no
|
2、启动
使用redis-benchmark测试
1
| redis-benchmark -h 127.0.0.1 -p 6379 -n 10000000 -r 1000000 -c 200 -d 32 -t ping,set,get
|
- -n:测试包数量
- -r:随机key数量
- -c:客户端连接数
- -t:执行具体的测试命令合集
统计数据
1
| cat /proc/vmstat | grep numa
|
指令结果含义为如下:
- numa_hit:成功的本地内存访问次数
- numa_miss:表示无法从本地节点获取页面的失败次数,需要从其它节点获取
- numa_foreign:表示页面分配给一个节点,但是被从其它节点访问的次数
- numa_interleave:通过内存交错的方式分配的页面数量
编写脚本测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
| STRS=( "numa_hit" "numa_miss" "numa_foreign" "numa_interleave" "numa_local" "numa_other" "numa_pte_updates" "numa_huge_pte_updates" "numa_hint_faults" "numa_hint_faults_local" "numa_pages_migrated" )
output_file="output.txt"
for ((epooch=1; epooch<50; epooch++)) do
declare -a PRE_VALUES declare -a END_VALUES
PRE_TEST=$(cat /proc/vmstat | grep numa) IFS=$'\n' read -rd '' -a PRE_TEST_ARRAY <<<"$PRE_TEST" for key in "${PRE_TEST_ARRAY[@]}"; do value=$(echo "$key" | awk '{print $2}') PRE_VALUES+=("$value") done
redis-benchmark -h 127.0.0.1 -p 6379 -n 1000000 -r 200000 -c 10000 -d 32 -t ping,set,get & pid=$! wait "$pid"
END_TEST=$(cat /proc/vmstat | grep numa) IFS=$'\n' read -rd '' -a END_TEST_ARRAY <<<"$END_TEST"
for key in "${END_TEST_ARRAY[@]}"; do value=$(echo "$key" | awk '{print $2}') END_VALUES+=("$value") done
for ((i=0; i<${#STRS[@]}; i++)) do diff=$((END_VALUES[i] - PRE_VALUES[i])) echo -n "$diff " >> "$output_file" echo "${END_VALUES[i]} ${PRE_VALUES[i]} $diff" done
echo >> "$output_file" echo "The $epooch epo is over" unset PRE_VALUES unset END_VALUES unset PRE_TEST_ARRAY unset END_TEST_ARRAY sleep 60 done
|