阿里的一些论文

google,Facebook等国外大佬经常在顶级会议上(SOSP/PLDI/NSDI等等)发论文,阿里也发表了好些的论文。以前整理了相关东西,不成章法,凑了这篇文章,以后研究的话再捡起来。

SIGCOMM 2020

《VTrace: Automatic Diagnostic System for Persistent Packet Loss in Cloud-Scale Overlay Network》

超大规模下的云网络异常定位、

传统网络工具 VS 大数据染色报文分析

云网络碰到类似问题只能用网工三板斧来处理: 抓包,ping, trace。

阿里云网络团队首次采用大数据结合染色报文的方式,通过大数据技术给这个交警配备了一个超强的大脑,让他能实时处理千万级网络数据,同时,结合染色报文技术让所有网络里面的数据包信息实时传递给我们的云网络交警。最后的结果就是这个云网络交警能实时感知到整个云网络每台设备的丢包和拥塞情况。阿里云网络给这个交警取了一个名字,叫vTrace。当用户在上网过程中碰到网络问题时,vTrace能很快找到对应链路上出现问题的节点在哪里,解决了云网络排查问题难的痛点,加快用户网络问题恢复过程。

SIGCOMM2019

来自阿里云智能的两篇论文

  • 《HPCC: High Precision Congestion Control》 高速网络拥塞控制协议HPCC
    • 阿里巴巴此前已通过对RDMA网络的改造,从网卡底层开始设计,结合自研交换机能力,建成全球最大规模的“RDMA高速网络”。
    • 在这次的论文中,阿里巴巴就提出了一种全新的网络协议——新一代高速网络拥塞控制协议HPCC(High Precision Congestion Control),不仅保证传输性能快,还能保证传输稳定,真正适用于当下的网络需求。
  • 《Safelyand Automatically Updating In-Network ACL Configurations with Intent Language》 使用意图语言安全且自动地更新网络内ACL配置

FAST2020

存储行业顶级国际会议FAST2020(18th USENIX Conference on File and Storage Technologies)在美国圣克拉拉举行,大会公开论文名单显示,阿里巴巴3篇第一作者论文入选,是全球入选数最多的企业。

在《POLARDB结合可计算存储: 高效支持云原生关系数据库的复杂查询操作》一文中,阿里团队针对PolarDB,把SQL和存储引擎的计算逻辑下推到底层共享存储,并通过定制SSD内部的FPGA进一步下推计算至存储节点的SSD内部,完成更高效率计算的同时,大幅降低主机和网络带宽占用,为PolarDB在复杂查询场景下带来4~5倍的吞吐提升。

另两篇文章,聚焦键值存储(KVS)。

在《FPGA加速Compactions操作,基于 LSM-tree的键值存储》一文中,研究团队首次引入异构硬件FPGA,实现KVS核心操作Compaction加速,较仅CPU处理能力提升2~5倍,整体吞吐性能提升23%,能效提升31.7%。

在《HotRing:热点感知的无锁内存键值系统》一文中,阿里团队提出新型热点感知内存KVS — HotRing,采用轻量级的热点识别策略,在未增加元数据存储开销的同时,还对幂率分布的热点场景进行大量优化,使得HotRing的引擎吞吐性能可达600M ops/s,单次访问平均只需100ns,比目前最快KVS性能提升2.58倍。

ASPLOS’19

摘要: 阿里云首次在ASPLOS上发表论文,第24届ACM编程语言和操作系统(ASPLOS’19),于2019年4月13日至17日,在普罗维登斯召开,阿里云高级技术专家郑晓代表团队在会上发表了技术报告。

第24届ACM编程语言和操作系统(ASPLOS’19),于2019年4月13日至17日,在普罗维登斯召开,阿里云高级技术专家郑晓代表团队在会上发表了技术报告。

论文主题为《Fast and Scalable VMM Live Upgrade in Large Cloud Infrastructure》,作者是张献涛,郑晓,沈益斌等。这篇论文被计算机系统结构的顶级会议ASPLOS’19接受,是业界对于VMM热升级这项突破性技术的认可。

论文ACM下载地址:https://dl.acm.org/citation.cfm?id=3304034 PDF下载地址:https://yq.aliyun.com/download/3532

该论文系统的阐述了当前云计算领域面临的基础架构带业务热升级问题。提出了一种新型的,比热迁移更行之有效的方法,特别适合超大规模集群范围的使用,解决了困扰云计算行业多年的问题。该方案在阿里云大规模采用,服务百万级别的客户虚拟机数量。论文解决了在客户业务不中断的情况下以毫秒级的速度更换底层虚拟化组件。

阿里云热升级技术特点决定了可以同时热升级任意数量任意规格的虚拟机,并且升级时间恒定。更难得的是,在业界尚未有异构计算设备热迁移方案的情况下,阿里云热升级技术同时支持异构计算等以设备直通方式工作的虚拟机。帮助ECS在过去五年进行了快速的升级迭代,保障了产品和业务的快速奔跑。

ASPLOS(编程语言和操作系统的体系结构支持会议)会议全称为ACM International Conference on Architectural Support for Programming Languages and Operating Systems,是综合体系结构、编程语言和操作系统三个方向的计算机系统领域顶级会议,为CCF A类会议。从1982年创办至今的三十多年里,ASPLOS推动了多项计算机系统技术的发展,包括(但不限于)RISC、RAID、大规模多处理器、Cluster架构和网络存储等。


查看并记录服务器硬件信息

查了相关的文章做个记录,从CPU、内存、网卡、硬盘、主板、BIOS、操作系统几个方面。

一、硬件

1.1 服务器型号、序列号

dmidecode|grep "System Information" -A9|egrep  "Manufacturer|Product|Serial" 

image-20210604175015800

1.2 主板型号

dmidecode |grep -A16 "System Information$" 

image-20210604175154526

1.3 查看BIOS信息

 dmidecode -t bios

image-20210604175234570

1.4 查看内存槽及内存条

dmidecode -t memory | more

image-20210604175550817

1.5 查看主板所有硬件槽信息

lspci # 可列出每个pci总线上的设备, 通过grep过滤后可得到网卡设备列表

image-20210604180408326

1.6 查看网卡信息

lspci | grep -i net

image-20210604180408326

二、CPU

(1)查看 cpu 核数和型号,主频等

cat /proc/cpuinfo | grep name | cut -f2 -d: | uniq -c

image-20210604180928552

(2)查看系统有几颗CPU

grep 'physical id' /proc/cpuinfo | sort | uniq | wc -l
1

(3)CPU的逻辑个数(开启超线程时1个core相当于2个逻辑cpu)

cat /proc/cpuinfo |grep 'processor'|wc -l
8

(4)查看每颗 CPU 中的内核个数

cat /proc/cpuinfo |grep "cores"|uniq 
cpu cores : 4

(5)查看CPU的主频

cat /proc/cpuinfo |grep MHz|uniq 

cpu MHz         : 4102.000
cpu MHz         : 4105.465
cpu MHz         : 4100.059
cpu MHz         : 4147.903
cpu MHz         : 4100.493
cpu MHz         : 4100.521
cpu MHz         : 4160.260
cpu MHz         : 4138.348

(6)查看CPU的详细信息

cat /proc/cpuinfo
processor : 0 //逻辑处理器的ID
vendor_id : GenuineIntel
cpu family : 6
model : 158
model name : Intel(R) Core(TM) i7-7700 CPU @ 3.60GHz   //CPU型号
stepping : 9
microcode : 0x84
cpu MHz : 4070.787
cache size : 8192 KB
physical id : 0
siblings : 8 //相同物理封装处理器中逻辑处理器数
core id : 0
cpu cores : 4 //相同物理封装处理器中的内核数

image-20210605161138951

(7)查看CPU的相关信息

lscpu

(8)查看 cpu 是32位还是64位

[root@Master ~]# getconf LONG_BIT
64

三、内存

free -mh                 								# 概要查看内存情况
dmidecode -t memory      								# 查看内存硬件信息
dmidecode|grep -P 'Maximum\s+Capacity' 	# 最大支持多少内存

image-20210605161653092

dmidecode|grep -A5 "Memory Device"|grep Size | grep -v Range # Linux 查看内存已经使用插槽数

image-20210605161857039

dmidecode|grep -A16 "Memory Device"|grep 'Speed' # 内存频率

image-20210605162129768

cat /proc/meminfo |head -20 # 内存详细信息

image-20210605162344913

free -mh # 内存使用情况

image-20210605162459550

四、网卡

ifconfig
ethtool bond0
ethtool bond1

ifconfig -a
ip link show

五、硬盘

lsblk  # fdisk一般用来磁盘分区,也可以用来查看磁盘分区情况
fdisk -l # 硬盘和分区的详细信息

image-20210607163611855

image-20210607163644643

# lsblk命令用于列出所有可用块设备的信息,而且还能显示他们之间的依赖关系
lsblk

image-20210608230402740

image-20210608230420949

# 其他命令

mount | column -t
swapon -s Filename Type Size Used Priority
df -hT
du --max-depth=1 -ah 2> /dev/null | sort -hr | head
smartctl -a /dev/sda

操作系统

uname -a
cat /etc/redhat-release
dmidecode -s system-serial-number # 系统序列号

一个简单的脚本

#!/usr/bin/env bash

if  [ ! -e '/usr/bin/wget' ]; then
    echo "Error: wget command not found. You must be install wget command at first."
    exit 1
fi

# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;36m'
PLAIN='\033[0m'

get_opsy() {
    [ -f /etc/redhat-release ] && awk '{print ($1,$3~/^[0-9]/?$3:$4)}' /etc/redhat-release && return
    [ -f /etc/os-release ] && awk -F'[= "]' '/PRETTY_NAME/{print $3,$4,$5}' /etc/os-release && return
    [ -f /etc/lsb-release ] && awk -F'[="]+' '/DESCRIPTION/{print $2}' /etc/lsb-release && return
}

next() {
    printf "%-70s\n" "-" | sed 's/\s/-/g'
}

calc_disk() {
    local total_size=0
    local array=$@
    for size in ${array[@]}
    do
        [ "${size}" == "0" ] && size_t=0 || size_t=`echo ${size:0:${#size}-1}`
        [ "`echo ${size:(-1)}`" == "K" ] && size=0
        [ "`echo ${size:(-1)}`" == "M" ] && size=$( awk 'BEGIN{printf "%.1f", '$size_t' / 1024}' )
        [ "`echo ${size:(-1)}`" == "T" ] && size=$( awk 'BEGIN{printf "%.1f", '$size_t' * 1024}' )
        [ "`echo ${size:(-1)}`" == "G" ] && size=${size_t}
        total_size=$( awk 'BEGIN{printf "%.1f", '$total_size' + '$size'}' )
    done
    echo ${total_size}
}

cname=$( awk -F: '/model name/ {name=$2} END {print name}' /proc/cpuinfo | sed 's/^[ \t]*//;s/[ \t]*$//' )
cores=$( awk -F: '/model name/ {core++} END {print core}' /proc/cpuinfo )
freq=$( awk -F'[ :]' '/cpu MHz/ {print $4;exit}' /proc/cpuinfo )
tram=$( free -m | awk '/Mem/ {print $2}' )
uram=$( free -m | awk '/Mem/ {print $3}' )
swap=$( free -m | awk '/Swap/ {print $2}' )
uswap=$( free -m | awk '/Swap/ {print $3}' )
up=$( awk '{a=$1/86400;b=($1%86400)/3600;c=($1%3600)/60} {printf("%d days, %d hour %d min\n",a,b,c)}' /proc/uptime )
load=$( w | head -1 | awk -F'load average:' '{print $2}' | sed 's/^[ \t]*//;s/[ \t]*$//' )
opsy=$( get_opsy )
arch=$( uname -m )
lbit=$( getconf LONG_BIT )
kern=$( uname -r )
#ipv6=$( wget -qO- -t1 -T2 ipv6.icanhazip.com )
disk_size1=($( LANG=C df -hPl | grep -wvE '\-|none|tmpfs|devtmpfs|by-uuid|chroot|Filesystem|udev|docker' | awk '{print $2}' ))
disk_size2=($( LANG=C df -hPl | grep -wvE '\-|none|tmpfs|devtmpfs|by-uuid|chroot|Filesystem|udev|docker' | awk '{print $3}' ))
disk_total_size=$( calc_disk "${disk_size1[@]}" )
disk_used_size=$( calc_disk "${disk_size2[@]}" )

clear
next
echo -e "CPU                  : ${BLUE}$cname${PLAIN}"
echo -e "核心数               : ${BLUE}$cores${PLAIN}"
echo -e "CPU 主频             : ${BLUE}$freq MHz${PLAIN}"
echo -e "硬盘                 : ${BLUE}$disk_total_size GB ($disk_used_size GB Used)${PLAIN}"
echo -e "内存                 : ${BLUE}$tram MB ($uram MB Used)${PLAIN}"
echo -e "交换分区             : ${BLUE}$swap MB ($uswap MB Used)${PLAIN}"
echo -e "OS                   : ${BLUE}$opsy${PLAIN}"
echo -e "Arch                 : ${BLUE}$arch ($lbit Bit)${PLAIN}"
echo -e "内核                 : ${BLUE}$kern${PLAIN}"
echo -e "运行时间             : ${BLUE}$up${PLAIN}"
echo -e "平均负载             : ${BLUE}$load${PLAIN}"
next

附:dmidecode 是什么

dmidecode可以让你在Linux系统下获取有关硬件方面的信息。

dmidecode的作用是将DMI数据库中的信息解码,以可读的文本方式显示。由于DMI信息可以人为修改,因此里面的信息不一定是系统准确的信息。

dmidecode遵循SMBIOS/DMI标准,其输出的信息包括BIOS、系统、主板、处理器、内存、缓存等等。

DMI(Desktop Management Interface,DMI)就是帮助收集电脑系统信息的管理系统,DMI信息的收集必须在严格遵照SMBIOS规范的前提下进行。SMBIOS(System Management BIOS)是主板或系统制造者以标准格式显示产品管理信息所需遵循的统一规范。SMBIOS和DMI是由行业指导机构Desktop Management Task Force(DMTF)起草的开放性的技术标准,其中DMI设计适用于任何的平台和操作系统。

DMI充当了管理工具和系统层之间接口的角色。它建立了标准的可管理系统更加方便了电脑厂商和用户对系统的了解。DMI的主要组成部分是Management Information Format(MIF)数据库。这个数据库包括了所有有关电脑系统和配件的信息。通过DMI,用户可以获取序列号、电脑厂商、串口信息以及其它系统配件信息。

参考资料


Debian 9/10 安装 WireGuard 备忘

不升级内核,或者内核ok但没有头文件,都有可能会遇到这样的错误:

RTNETLINK answers: Operation not supported

升级内核先参考我先前这篇文章:《debian 升级内核》

安装

sudo apt-get install libmnl-dev linux-headers-$(uname -r) build-essential make git # 安装必要的包

# 如果无法安装headlers,那么应该是内核偏老,先升级到比较新的内核

echo "deb http://deb.debian.org/debian/ unstable main" | sudo tee /etc/apt/sources.list.d/unstable.list
echo -e "Package: *\nPin: release a=unstable\nPin-Priority: 150\n" | tee /etc/apt/preferences.d/limit-unstable

apt-get update
apt-get upgrade
apt-get install wireguard-dkms wireguard-tools

配置

sudo mkdir -p /etc/wireguard
cd /etc/wireguard
sudo umask 077

# 快速生成密钥
sudo wg genkey | tee privatekey | wg pubkey > publickey

新建配置文件 wg0.conf

注意修改监听端口ListenPort,如果启用了防火墙,还需要开通相关端口

[Interface]
PrivateKey = #服务端的密钥
Address = 10.0.0.1/24, fd86:ea04:1115::1/64 #服务端的地址
ListenPort = 28472 #服务端的端口
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE; ip6tables -A FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE; ip6tables -D FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
SaveConfig = true

启动

快速启动:

sudo wg-quick up wg0

开机启动:

systemctl enable wg-quick@wg0

查看运行状况:

wg

配置客户端

其实 wireguard 中没有严格的客户端服务端的区别,配置客户端过程和服务端过程一样。只要把服务端的公钥和自己的公钥写入配置文件中,再填好对端的IP,会自动连接配对好。

以下是配置参考:

[Interface]
PrivateKey = #客户端的密钥
Address = 100.100.100.2/32 #客户端的内网地址
MTU = 1420
[Peer]
PublicKey = #服务端的公钥
Endpoint = 12.32.42.52:28472 #服务端的IP和端口
AllowedIPs = 100.100.100.0/24, 10.64.0.0/10, 10.128.0.0/10 #允许走wireguard的目的IP
PersistentKeepalive = 25

把这个配置连同客户端的公钥密钥一起放到客户端的/etc/wireguard文件夹中,就能启动了。

如果希望生成二维码,方便iOS和android刷二维码,还可以使用qrencode命令:

qrencode -t ansiutf8 < wg0.conf

Debian 10安装

  1. 增加源信息

    echo "deb http://deb.debian.org/debian/ unstable main" > /etc/apt/sources.list.d/unstable-wireguard.list
    printf 'Package: *\nPin: release a=unstable\nPin-Priority: 150\n' > /etc/apt/preferences.d/limit-unstable
    
  2. 更新源然后安装相关软件,用来编译 wireguard内核模块

    apt update
    apt install wireguard-dkms wireguard-tools
    

仍然报错

[#] ip link add wg0 type wireguard
RTNETLINK answers: Operation not supported
Unable to access interface: Protocol not supported
[#] ip link delete dev wg0
Cannot find device "wg0"

还是升级内核吧:

apt-get dist-upgrade
update-grub
/sbin/reboot

不过很奇怪,我重启之后内核其实并没有升级,但是 wireguard 能跑起来了。可能是中途某些步骤需要重启系统。下次遇到再补充了。


什么叫网元?

时常在文章里看到“网元”这个词,一看到就害怕,因为完全不知道是什么东西。

一番谷歌就理解了,如果你知道它的英文可能瞬间就理解了——Network Element。

网元就是网络中的元素,网络中的设备。

在GSM网络系统中, 一个基站就是一个网元。

交换机 路由器等也是一个网元。


BGP中的 Keepalive time 和 hold time

http://www.jiancenj.com/2209.aspx

在BGP学习中,我们了解到,BGP有个keepalive time,默认是60秒,还有hold time,是keepalive time的3倍关系,也就是180秒。同时我们也了解到,hold time的值是协商值,那这个值是怎么协商的呢?我们来看一下:

图片1.jpg

拓扑如上:两台设备之间建立IBGP连接。

我们可以通过display bgp peeripv4 verbose 命令查看keepalive time和hold time,如下图:

图片2.jpg

我们可以看到,在没有修改的情况下,keepalive和hold时间都是默认值。

在路由器2上的BGP进程中,修改keepalive和hold值。用timer keepalive +时间 hold +时间修改。注意:修改时间值时,holdtime ≥ 3*keepalive time。

首先我们先修改hold time =3*keepalive time:

图片3.jpg

然后去路由器1上查看协商的hold值。注意:查看之前要重新启用bgp进程,使用reset bgp 100 ipv4命令。因为协商参数的传递由open报文负责,而在BGP邻居状态使能的情况下,只有keepalive和update报文交互。reset之后,再去查看。我们可以看到:

图片4.jpg

路由器1上协商的hold time,为60秒,keepalive time为20秒。

接下来我们再路由器2上继续修改,hold time > 3*keepalive time。

图片5.jpg

再次到路由器1上查看:

图片6.jpg

这时候我们发现,协商的hold time为100秒,keepalive time是33秒。这时候的keepalive time并不是我们设置的20秒。这是因为在open报文中只携带hold time值,不携带keepalive值,keepalive是根据与hold 值的三倍关系计算出来的。

那我们继续做一个修改:在路由器1 上设置keepalive time为30秒,hold time为90秒,路由器2上keepalive time 为20秒 hold time 为100秒保持不变。

这时候我们发现:

路由器1上:

图片7.jpg

路由器2上:

图片8.jpg

我们发现,路由器1和路由器2上hold 值是一致的,为90秒。但是keepalive 值,路由器1上是30秒,路由器2上是20秒。这是因为,当路由器接收到对方传来的hold值时,首先与自己的做比较,如果接收到的hold值小,则hold值修改为接收到的值,在比较keepalive值,若自己的keepalive值小于接收到的(hold值/3),则用自己的keepalive值,若自己的keepalive值大于接收到的(hold值/3),则使用接收到的(hold值/3);当路由器接收到的hold值比自己的hold值大时,则不做任何修改。

参考


物理机将CPU频率固定在最高运行频率上

cpufreq

cpufreq是一个动态调整cpu频率的模块,系统启动时生成一个文件夹/sys/devices/system/cpu/cpu0/cpufreq/,里面有几个文件,其中scaling_min_freq代表最低频率,scaling_max_freq代表最高频率,scalin_governor代表cpu频率调整模式,用它来控制CPU频率。

  1. performance: 顾名思义只注重效率,将CPU频率固定工作在其支持的最高运行频率上,而不动态调节。
  2. Userspace:最早的cpufreq子系统通过userspace governor为用户提供了这种灵活性。系统将变频策略的决策权交给了用户态应用程序,并提供了相应的接口供用户态应用程序调节CPU 运行频率使用。也就是长期以来都在用的那个模式。可以通过手动编辑配置文件进行配置
  3. powersave: 将CPU频率设置为最低的所谓“省电”模式,CPU会固定工作在其支持的最低运行频率上。因此这两种governors 都属于静态governor,即在使用它们时CPU 的运行频率不会根据系统运行时负载的变化动态作出调整。这两种governors 对应的是两种极端的应用场景,使用performance governor 是对系统高性能的最大追求,而使用powersave governor 则是对系统低功耗的最大追求。
  4. ondemand: 按需快速动态调整CPU频率, 一有cpu计算量的任务,就会立即达到最大频率运行,等执行完毕就立即回到最低频率;ondemand:userspace是内核态的检测,用户态调整,效率低。而ondemand正是人们长期以来希望看到的一个完全在内核态下工作并且能够以更加细粒度的时间间隔对系统负载情况进行采样分析的governor。 在 ondemand governor 监测到系统负载超过 up_threshold 所设定的百分比时,说明用户当前需要 CPU 提供更强大的处理能力,因此 ondemand governor 会将CPU设置在最高频率上运行。但是当 ondemand governor 监测到系统负载下降,可以降低 CPU 的运行频率时,到底应该降低到哪个频率呢? ondemand governor 的最初实现是在可选的频率范围内调低至下一个可用频率,例如 CPU 支持三个可选频率,分别为 1.67GHz、1.33GHz 和 1GHz ,如果 CPU 运行在 1.67GHz 时 ondemand governor 发现可以降低运行频率,那么 1.33GHz 将被选作降频的目标频率。
  5. conservative: 与ondemand不同,平滑地调整CPU频率,频率的升降是渐变式的,会自动在频率上下限调整,和ondemand的区别在于它会按需分配频率,而不是一味追求最高频率;

cpupower

# CentOS 安装 kernel-tools
yum install kernel-tools

# Ubuntu 安装 CPU 模式无图形化切换器
apt install cpufrequtils

# cpupower设置performance
cpupower frequency-set -g performance

# 查看当前的调节器
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
performance

参考资料