精华内容
下载资源
问答
  • 有的人搭建SSR ,配一个什么锐速,还需要降内核版本, 而且还容易出错,降了之后更加容易出现兼容性问题,所以偶尔看到了google的BBR 拥塞阻塞算法 算法原理不知道,也不想去深究 。 原理 这篇博客讲得还是很清楚的 ...
    为什么想到这个呢,算法什么的又不太懂,这是 因为搭建VPN + BBR 与之简直绝配

    有的人搭建SSR ,配一个什么锐速,还需要降内核版本, 而且还容易出错,降了之后更加容易出现兼容性问题,所以偶尔看到了google的BBR 拥塞阻塞算法 

    算法原理不知道,也不想去深究 。 原理 这篇博客 讲得还是很清楚的 ,可以一探

    Google 开源了其 TCP BBR 拥塞控制算法,并提交到了 Linux 内核,从 4.9 开始,Linux 内核已经用上了该算法。根据谷歌的风格,Google 总是先在自家的生产环境上线运用后,才会将代码开源,此次也不例外。
    根据大佬的实地测试,在部署了最新版内核并开启了 TCP BBR 的机器上,网速甚至可以提升好几个数量级。

    根据某个大佬开发的一键安装的脚本,可以实现最新内核的安装和 TCP BBR 脚本
    脚本如下:

      1 #!/usr/bin/env bash
      2 #
      3 # Auto install latest kernel for TCP BBR
      4 #
      5 # System Required:  CentOS 6+, Debian7+, Ubuntu12+
      6 #
      7 # Copyright (C) 2016-2018 Teddysun <i@teddysun.com>
      8 #
      9 # URL: https://teddysun.com/489.html
     10 #
     11 
     12 red='\033[0;31m'
     13 green='\033[0;32m'
     14 yellow='\033[0;33m'
     15 plain='\033[0m'
     16 
     17 cur_dir=$(pwd)
     18 
     19 [[ $EUID -ne 0 ]] && echo -e "${red}Error:${plain} This script must be run as root!" && exit 1
     20 
     21 [[ -d "/proc/vz" ]] && echo -e "${red}Error:${plain} Your VPS is based on OpenVZ, which is not supported." && exit 1
     22 
     23 if [ -f /etc/redhat-release ]; then
     24     release="centos"
     25 elif cat /etc/issue | grep -Eqi "debian"; then
     26     release="debian"
     27 elif cat /etc/issue | grep -Eqi "ubuntu"; then
     28     release="ubuntu"
     29 elif cat /etc/issue | grep -Eqi "centos|red hat|redhat"; then
     30     release="centos"
     31 elif cat /proc/version | grep -Eqi "debian"; then
     32     release="debian"
     33 elif cat /proc/version | grep -Eqi "ubuntu"; then
     34     release="ubuntu"
     35 elif cat /proc/version | grep -Eqi "centos|red hat|redhat"; then
     36     release="centos"
     37 else
     38     release=""
     39 fi
     40 
     41 is_digit(){
     42     local input=${1}
     43     if [[ "$input" =~ ^[0-9]+$ ]]; then
     44         return 0
     45     else
     46         return 1
     47     fi
     48 }
     49 
     50 is_64bit(){
     51     if [ $(getconf WORD_BIT) = '32' ] && [ $(getconf LONG_BIT) = '64' ]; then
     52         return 0
     53     else
     54         return 1
     55     fi
     56 }
     57 
     58 get_valid_valname(){
     59     local val=${1}
     60     local new_val=$(eval echo $val | sed 's/[-.]/_/g')
     61     echo ${new_val}
     62 }
     63 
     64 get_hint(){
     65     local val=${1}
     66     local new_val=$(get_valid_valname $val)
     67     eval echo "\$hint_${new_val}"
     68 }
     69 
     70 #Display Memu
     71 display_menu(){
     72     local soft=${1}
     73     local default=${2}
     74     eval local arr=(\${${soft}_arr[@]})
     75     local default_prompt
     76     if [[ "$default" != "" ]]; then
     77         if [[ "$default" == "last" ]]; then
     78             default=${#arr[@]}
     79         fi
     80         default_prompt="(default ${arr[$default-1]})"
     81     fi
     82     local pick
     83     local hint
     84     local vname
     85     local prompt="which ${soft} you'd select ${default_prompt}: "
     86 
     87     while :
     88     do
     89         echo -e "\n------------ ${soft} setting ------------\n"
     90         for ((i=1;i<=${#arr[@]};i++ )); do
     91             vname="$(get_valid_valname ${arr[$i-1]})"
     92             hint="$(get_hint $vname)"
     93             [[ "$hint" == "" ]] && hint="${arr[$i-1]}"
     94             echo -e "${green}${i}${plain}) $hint"
     95         done
     96         echo
     97         read -p "${prompt}" pick
     98         if [[ "$pick" == "" && "$default" != "" ]]; then
     99             pick=${default}
    100             break
    101         fi
    102 
    103         if ! is_digit "$pick"; then
    104             prompt="Input error, please input a number"
    105             continue
    106         fi
    107 
    108         if [[ "$pick" -lt 1 || "$pick" -gt ${#arr[@]} ]]; then
    109             prompt="Input error, please input a number between 1 and ${#arr[@]}: "
    110             continue
    111         fi
    112 
    113         break
    114     done
    115 
    116     eval ${soft}=${arr[$pick-1]}
    117     vname="$(get_valid_valname ${arr[$pick-1]})"
    118     hint="$(get_hint $vname)"
    119     [[ "$hint" == "" ]] && hint="${arr[$pick-1]}"
    120     echo -e "\nyour selection: $hint\n"
    121 }
    122 
    123 version_ge(){
    124     test "$(echo "$@" | tr " " "\n" | sort -rV | head -n 1)" == "$1"
    125 }
    126 
    127 get_latest_version() {
    128     latest_version=($(wget -qO- https://kernel.ubuntu.com/~kernel-ppa/mainline/ | awk -F'\"v' '/v[4-9]./{print $2}' | cut -d/ -f1 | grep -v - | sort -V))
    129 
    130     [ ${#latest_version[@]} -eq 0 ] && echo -e "${red}Error:${plain} Get latest kernel version failed." && exit 1
    131 
    132     kernel_arr=()
    133     for i in ${latest_version[@]}; do
    134         if version_ge $i 4.14; then
    135             kernel_arr+=($i);
    136         fi
    137     done
    138 
    139     display_menu kernel last
    140 
    141     if [[ `getconf WORD_BIT` == "32" && `getconf LONG_BIT` == "64" ]]; then
    142         deb_name=$(wget -qO- https://kernel.ubuntu.com/~kernel-ppa/mainline/v${kernel}/ | grep "linux-image" | grep "generic" | awk -F'\">' '/amd64.deb/{print $2}' | cut -d'<' -f1 | head -1)
    143         deb_kernel_url="https://kernel.ubuntu.com/~kernel-ppa/mainline/v${kernel}/${deb_name}"
    144         deb_kernel_name="linux-image-${kernel}-amd64.deb"
    145         modules_deb_name=$(wget -qO- https://kernel.ubuntu.com/~kernel-ppa/mainline/v${kernel}/ | grep "linux-modules" | grep "generic" | awk -F'\">' '/amd64.deb/{print $2}' | cut -d'<' -f1 | head -1)
    146         deb_kernel_modules_url="https://kernel.ubuntu.com/~kernel-ppa/mainline/v${kernel}/${modules_deb_name}"
    147         deb_kernel_modules_name="linux-modules-${kernel}-amd64.deb"
    148     else
    149         deb_name=$(wget -qO- https://kernel.ubuntu.com/~kernel-ppa/mainline/v${kernel}/ | grep "linux-image" | grep "generic" | awk -F'\">' '/i386.deb/{print $2}' | cut -d'<' -f1 | head -1)
    150         deb_kernel_url="https://kernel.ubuntu.com/~kernel-ppa/mainline/v${kernel}/${deb_name}"
    151         deb_kernel_name="linux-image-${kernel}-i386.deb"
    152         modules_deb_name=$(wget -qO- https://kernel.ubuntu.com/~kernel-ppa/mainline/v${kernel}/ | grep "linux-modules" | grep "generic" | awk -F'\">' '/i386.deb/{print $2}' | cut -d'<' -f1 | head -1)
    153         deb_kernel_modules_url="https://kernel.ubuntu.com/~kernel-ppa/mainline/v${kernel}/${modules_deb_name}"
    154         deb_kernel_modules_name="linux-modules-${kernel}-i386.deb"
    155     fi
    156 
    157     [ -z ${deb_name} ] && echo -e "${red}Error:${plain} Getting Linux kernel binary package name failed, maybe kernel build failed. Please choose other one and try again." && exit 1
    158 }
    159 
    160 get_opsy() {
    161     [ -f /etc/redhat-release ] && awk '{print ($1,$3~/^[0-9]/?$3:$4)}' /etc/redhat-release && return
    162     [ -f /etc/os-release ] && awk -F'[= "]' '/PRETTY_NAME/{print $3,$4,$5}' /etc/os-release && return
    163     [ -f /etc/lsb-release ] && awk -F'[="]+' '/DESCRIPTION/{print $2}' /etc/lsb-release && return
    164 }
    165 
    166 opsy=$( get_opsy )
    167 arch=$( uname -m )
    168 lbit=$( getconf LONG_BIT )
    169 kern=$( uname -r )
    170 
    171 get_char() {
    172     SAVEDSTTY=`stty -g`
    173     stty -echo
    174     stty cbreak
    175     dd if=/dev/tty bs=1 count=1 2> /dev/null
    176     stty -raw
    177     stty echo
    178     stty $SAVEDSTTY
    179 }
    180 
    181 getversion() {
    182     if [[ -s /etc/redhat-release ]]; then
    183         grep -oE  "[0-9.]+" /etc/redhat-release
    184     else
    185         grep -oE  "[0-9.]+" /etc/issue
    186     fi
    187 }
    188 
    189 centosversion() {
    190     if [ x"${release}" == x"centos" ]; then
    191         local code=$1
    192         local version="$(getversion)"
    193         local main_ver=${version%%.*}
    194         if [ "$main_ver" == "$code" ]; then
    195             return 0
    196         else
    197             return 1
    198         fi
    199     else
    200         return 1
    201     fi
    202 }
    203 
    204 check_bbr_status() {
    205     local param=$(sysctl net.ipv4.tcp_congestion_control | awk '{print $3}')
    206     if [[ x"${param}" == x"bbr" ]]; then
    207         return 0
    208     else
    209         return 1
    210     fi
    211 }
    212 
    213 check_kernel_version() {
    214     local kernel_version=$(uname -r | cut -d- -f1)
    215     if version_ge ${kernel_version} 4.9; then
    216         return 0
    217     else
    218         return 1
    219     fi
    220 }
    221 
    222 install_elrepo() {
    223 
    224     if centosversion 5; then
    225         echo -e "${red}Error:${plain} not supported CentOS 5."
    226         exit 1
    227     fi
    228 
    229     rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
    230 
    231     if centosversion 6; then
    232         rpm -Uvh https://www.elrepo.org/elrepo-release-6-9.el6.elrepo.noarch.rpm
    233     elif centosversion 7; then
    234         rpm -Uvh https://www.elrepo.org/elrepo-release-7.0-4.el7.elrepo.noarch.rpm
    235     fi
    236 
    237     if [ ! -f /etc/yum.repos.d/elrepo.repo ]; then
    238         echo -e "${red}Error:${plain} Install elrepo failed, please check it."
    239         exit 1
    240     fi
    241 }
    242 
    243 sysctl_config() {
    244     sed -i '/net.core.default_qdisc/d' /etc/sysctl.conf
    245     sed -i '/net.ipv4.tcp_congestion_control/d' /etc/sysctl.conf
    246     echo "net.core.default_qdisc = fq" >> /etc/sysctl.conf
    247     echo "net.ipv4.tcp_congestion_control = bbr" >> /etc/sysctl.conf
    248     sysctl -p >/dev/null 2>&1
    249 }
    250 
    251 install_config() {
    252     if [[ x"${release}" == x"centos" ]]; then
    253         if centosversion 6; then
    254             if [ ! -f "/boot/grub/grub.conf" ]; then
    255                 echo -e "${red}Error:${plain} /boot/grub/grub.conf not found, please check it."
    256                 exit 1
    257             fi
    258             sed -i 's/^default=.*/default=0/g' /boot/grub/grub.conf
    259         elif centosversion 7; then
    260             if [ ! -f "/boot/grub2/grub.cfg" ]; then
    261                 echo -e "${red}Error:${plain} /boot/grub2/grub.cfg not found, please check it."
    262                 exit 1
    263             fi
    264             grub2-set-default 0
    265         fi
    266     elif [[ x"${release}" == x"debian" || x"${release}" == x"ubuntu" ]]; then
    267         /usr/sbin/update-grub
    268     fi
    269 }
    270 
    271 reboot_os() {
    272     echo
    273     echo -e "${green}Info:${plain} The system needs to reboot."
    274     read -p "Do you want to restart system? [y/n]" is_reboot
    275     if [[ ${is_reboot} == "y" || ${is_reboot} == "Y" ]]; then
    276         reboot
    277     else
    278         echo -e "${green}Info:${plain} Reboot has been canceled..."
    279         exit 0
    280     fi
    281 }
    282 
    283 install_bbr() {
    284     check_bbr_status
    285     if [ $? -eq 0 ]; then
    286         echo
    287         echo -e "${green}Info:${plain} TCP BBR has already been installed. nothing to do..."
    288         exit 0
    289     fi
    290     check_kernel_version
    291     if [ $? -eq 0 ]; then
    292         echo
    293         echo -e "${green}Info:${plain} Your kernel version is greater than 4.9, directly setting TCP BBR..."
    294         sysctl_config
    295         echo -e "${green}Info:${plain} Setting TCP BBR completed..."
    296         exit 0
    297     fi
    298 
    299     if [[ x"${release}" == x"centos" ]]; then
    300         install_elrepo
    301         [ ! "$(command -v yum-config-manager)" ] && yum install -y yum-utils > /dev/null 2>&1
    302         [ x"$(yum-config-manager elrepo-kernel | grep -w enabled | awk '{print $3}')" != x"True" ] && yum-config-manager --enable elrepo-kernel > /dev/null 2>&1
    303         if centosversion 6; then
    304             if is_64bit; then
    305                 rpm_kernel_name="kernel-ml-4.18.20-1.el6.elrepo.x86_64.rpm"
    306                 rpm_kernel_devel_name="kernel-ml-devel-4.18.20-1.el6.elrepo.x86_64.rpm"
    307                 rpm_kernel_url_1="http://repos.lax.quadranet.com/elrepo/archive/kernel/el6/x86_64/RPMS/"
    308             else
    309                 rpm_kernel_name="kernel-ml-4.18.20-1.el6.elrepo.i686.rpm"
    310                 rpm_kernel_devel_name="kernel-ml-devel-4.18.20-1.el6.elrepo.i686.rpm"
    311                 rpm_kernel_url_1="http://repos.lax.quadranet.com/elrepo/archive/kernel/el6/i386/RPMS/"
    312             fi
    313             rpm_kernel_url_2="https://dl.lamp.sh/files/"
    314             wget -c -t3 -T60 -O ${rpm_kernel_name} ${rpm_kernel_url_1}${rpm_kernel_name}
    315             if [ $? -ne 0 ]; then
    316                 rm -rf ${rpm_kernel_name}
    317                 wget -c -t3 -T60 -O ${rpm_kernel_name} ${rpm_kernel_url_2}${rpm_kernel_name}
    318             fi
    319             wget -c -t3 -T60 -O ${rpm_kernel_devel_name} ${rpm_kernel_url_1}${rpm_kernel_devel_name}
    320             if [ $? -ne 0 ]; then
    321                 rm -rf ${rpm_kernel_devel_name}
    322                 wget -c -t3 -T60 -O ${rpm_kernel_devel_name} ${rpm_kernel_url_2}${rpm_kernel_devel_name}
    323             fi
    324             if [ -f "${rpm_kernel_name}" ]; then
    325                 rpm -ivh ${rpm_kernel_name}
    326             else
    327                 echo -e "${red}Error:${plain} Download ${rpm_kernel_name} failed, please check it."
    328                 exit 1
    329             fi
    330             if [ -f "${rpm_kernel_devel_name}" ]; then
    331                 rpm -ivh ${rpm_kernel_devel_name}
    332             else
    333                 echo -e "${red}Error:${plain} Download ${rpm_kernel_devel_name} failed, please check it."
    334                 exit 1
    335             fi
    336             rm -f ${rpm_kernel_name} ${rpm_kernel_devel_name}
    337         elif centosversion 7; then
    338             yum -y install kernel-ml kernel-ml-devel
    339             if [ $? -ne 0 ]; then
    340                 echo -e "${red}Error:${plain} Install latest kernel failed, please check it."
    341                 exit 1
    342             fi
    343         fi
    344     elif [[ x"${release}" == x"debian" || x"${release}" == x"ubuntu" ]]; then
    345         [[ ! -e "/usr/bin/wget" ]] && apt-get -y update && apt-get -y install wget
    346         echo -e "${green}Info:${plain} Getting latest kernel version..."
    347         get_latest_version
    348         if [ -n ${modules_deb_name} ]; then
    349             wget -c -t3 -T60 -O ${deb_kernel_modules_name} ${deb_kernel_modules_url}
    350             if [ $? -ne 0 ]; then
    351                 echo -e "${red}Error:${plain} Download ${deb_kernel_modules_name} failed, please check it."
    352                 exit 1
    353             fi
    354         fi
    355         wget -c -t3 -T60 -O ${deb_kernel_name} ${deb_kernel_url}
    356         if [ $? -ne 0 ]; then
    357             echo -e "${red}Error:${plain} Download ${deb_kernel_name} failed, please check it."
    358             exit 1
    359         fi
    360         [ -f ${deb_kernel_modules_name} ] && dpkg -i ${deb_kernel_modules_name}
    361         dpkg -i ${deb_kernel_name}
    362         rm -f ${deb_kernel_name} ${deb_kernel_modules_name}
    363     else
    364         echo -e "${red}Error:${plain} OS is not be supported, please change to CentOS/Debian/Ubuntu and try again."
    365         exit 1
    366     fi
    367 
    368     install_config
    369     sysctl_config
    370     reboot_os
    371 }
    372 
    373 
    374 clear
    375 echo "---------- System Information ----------"
    376 echo " OS      : $opsy"
    377 echo " Arch    : $arch ($lbit Bit)"
    378 echo " Kernel  : $kern"
    379 echo "----------------------------------------"
    380 echo " Auto install latest kernel for TCP BBR"
    381 echo
    382 echo " URL: https://teddysun.com/489.html"
    383 echo "----------------------------------------"
    384 echo
    385 echo "Press any key to start...or Press Ctrl+C to cancel"
    386 char=`get_char`
    387 
    388 install_bbr 2>&1 | tee ${cur_dir}/install_bbr.log
    View Code

    也可以采用在线安装的方式:

    wget --no-check-certificate https://github.com/teddysun/across/raw/master/bbr.sh && chmod +x bbr.sh && ./bbr.sh

    安装完成后,脚本会提示需要重启 VPS,输入 y 并回车后重启。
    重启完成后,进入 VPS,验证一下是否成功安装最新内核并开启 TCP BBR,输入命令: 

    uname -r

    查看内核版本,显示为最新版就表示 OK了

    sysctl net.ipv4.tcp_available_congestion_control
    返回值一般为:
    net.ipv4.tcp_available_congestion_control = bbr cubic reno
    或者为:
    net.ipv4.tcp_available_congestion_control = reno cubic bbr
    =================================================================================
    sysctl net.ipv4.tcp_congestion_control
    返回值一般为:
    net.ipv4.tcp_congestion_control = bbr
    =================================================================================
    sysctl net.core.default_qdisc
    返回值一般为:
    net.core.default_qdisc = fq
    ==================================================================================
    lsmod | grep bbr
    返回值有 tcp_bbr 模块即说明 bbr 已启动。注意:并不是所有的 VPS 都会有此返回值,若没有也属正常。

    另外:

    附上大佬的CentOS 下最新版内核 headers 安装方法

    本来打算在脚本里直接安装 kernel-ml-headers,但会出现和原版内核 headers 冲突的问题。因此在这里添加一个脚本执行完后,手动安装最新版内核 headers 之教程。
    执行以下命令
    
    yum --enablerepo=elrepo-kernel -y install kernel-ml-headers
    根据 CentOS 版本的不同,此时一般会出现类似于以下的错误提示:
    
    Error: kernel-ml-headers conflicts with kernel-headers-2.6.32-696.20.1.el6.x86_64
    Error: kernel-ml-headers conflicts with kernel-headers-3.10.0-693.17.1.el7.x86_64
    因此需要先卸载原版内核 headers ,然后再安装最新版内核 headers。执行命令:
    
    yum remove kernel-headers
    确认无误后,输入 y,回车开始卸载。注意,有时候这么操作还会卸载一些对内核 headers 依赖的安装包,比如 gcc、gcc-c++ 之类的。不过不要紧,我们可以在安装完最新版内核 headers 后再重新安装回来即可。
    卸载完成后,再次执行上面给出的安装命令。
    
    yum --enablerepo=elrepo-kernel -y install kernel-ml-headers
    成功安装后,再把那些之前对内核 headers 依赖的安装包,比如 gcc、gcc-c++ 之类的再安装一次即可。
    
    为什么要安装最新版内核 headers 呢?
    这是因为 ss-libev 版有个 tcp fast open 功能,如果不安装的话,这个功能是无法开启的。
    
    内核升级方法
    如果是 CentOS 系统,执行如下命令即可升级内核:
    
    yum -y install kernel-ml kernel-ml-devel
    如果你还手动安装了新版内核 headers ,那么还需要以下命令来升级 headers :
    
    yum -y install kernel-ml-headers
    CentOS 6 的话,执行命令:
    
    sed -i 's/^default=.*/default=0/g' /boot/grub/grub.conf
    CentOS 7 的话,执行命令:
    
    grub2-set-default 0
    如果是 Debian/Ubuntu 系统,则需要手动下载最新版内核来安装升级。
    去这里下载最新版的内核 deb 安装包。
    如果系统是 64 位,则下载 amd64 的 linux-image 中含有 generic 这个 deb 包;
    如果系统是 32 位,则下载 i386 的 linux-image 中含有 generic 这个 deb 包;
    安装的命令如下(以最新版的 64 位 4.12.4 举例而已,请替换为下载好的 deb 包):
    
    dpkg -i linux-image-4.12.4-041204-generic_4.12.4-041204.201707271932_amd64.deb
    安装完成后,再执行命令:
    
    /usr/sbin/update-grub
    最后,重启 VPS 即可。
    
    特别说明
    如果你使用的是 Google Cloud Platform (GCP)更换内核,有时会遇到重启后,整个磁盘变为只读的情况。只需执行以下命令即可恢复:
    
    mount -o remount rw /

     参考链接:

    https://github.com/google/bbr/blob/master/Documentation/bbr-quick-start.md
    http://elrepo.org/tiki/tiki-index.php
    http://kernel.ubuntu.com/~kernel-ppa/mainline/

    https://teddysun.com/489.html

     

    展开全文
  • Linux kernel 4.9及以上开启TCP BBR拥塞算法 BBR 目的是要尽量跑满带宽, 并且尽量不要有排队的情况, 效果并不比速锐差 Linux kernel 4.9+ 已支持 tcp_bbr 下面简单讲述基于KVM架构VPS如何开启 安装Linuxkernel ...

    Linux kernel 4.9及以上开启TCP BBR拥塞算法

    BBR 目的是要尽量跑满带宽, 并且尽量不要有排队的情况, 效果并不比速锐差

    Linux kernel 4.9+ 已支持 tcp_bbr 下面简单讲述基于KVM架构VPS如何开启

    安装Linux kernel 4.9以上的版本

      一般安装最新版本内核

    Debian 8+ / Ubuntu 14.04

    • 下载最新内核
    # wget http://kernel.ubuntu.com/~kernel-ppa/mainline/v4.14.12/linux-image-4.14.12-041412-generic_4.14.12-041412.201801051649_amd64.deb
    • 安装内核
    # dpkg -i linux-image-4.*.deb
    • 删除旧版内核(可选)
    # dpkg -l | grep linux-image 
    # apt-get purge 旧内核
    • 更新grub并重启服务器
    # update-grub
    # reboot

    Ubuntu16.04

    • 安装 Hardware Enablement Stack (HWE),自动更新内核
    # apt install --install-recommends linux-generic-hwe-16.04
    • 删除旧版内核(可选)
    # apt autoremove
    • 重启服务器以启用最新内核
    # reboot

    CentOS6.x

    • 启用elrepo源并安装kernel-ml
    # rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
    # rpm -Uvh http://www.elrepo.org/elrepo-release-6-8.el6.elrepo.noarch.rpm
    # yum --enablerepo=elrepo-kernel install kernel-ml -y
    • 检查内核是否已经安装
    # rpm -qa | grep kernel
    • 更新grub并重启服务器
    # sed -i 's:default=.*:default=0:g' /etc/grub.conf
    # reboot

    CentOS7.x

    • 启用elrepo源并安装kernel-ml
    # rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
    # rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-3.el7.elrepo.noarch.rpm
    # yum --enablerepo=elrepo-kernel install kernel-ml -y
    • 检查内核是否已经安装
    # rpm -qa | grep kernel
    • 更新grub2.cfg
    # grub2-mkconfig -o /boot/grub2/grub.cfg
    • 重启服务器
    # reboot

     

    检查内核版本

    通过uname -r命令检查内核版本是否大于4.9

    # uname -r

    启用BBR拥塞算法

    • 加载内核模块
    # modprobe tcp_bbr
    # echo "tcp_bbr" >> /etc/modules-load.d/modules.conf
    • 修改内核参数
    # echo "net.core.default_qdisc=fq" >> /etc/sysctl.conf
    # echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.conf
    # sysctl -p
    • 检查BBR是否已经开启
    # lsmod | grep bbr
    # sysctl net.ipv4.tcp_available_congestion_control
    # sysctl net.ipv4.tcp_congestion_control

    如结果都有bbr,则表示已经开启BBR算法

    转载于:https://www.cnblogs.com/luanlengli/p/8733660.html

    展开全文
  • 为何当前基于丢包探测的TCP拥塞控制算法还有优化空间? BBR算法的优化极限在哪儿? 图1 为了理解这张图花了我整整一个晚上的时间,它使我重新审视了所有基础概念,而我以下的讨论对于TCP定义的RTT、带宽、...

    TCP BBR的ACM论文中,开篇就引入了图1,以此来说明BBR算法的切入点:

    • 为何当前基于丢包探测的TCP拥塞控制算法还有优化空间?
    • BBR算法的优化极限在哪儿?

    图1

    为了理解这张图花了我整整一个晚上的时间,它使我重新审视了所有基础概念,而我以下的讨论对于TCP定义的RTT、带宽、Inflight data都作了简化,从而使讨论更易于满足物理直觉,但又不影响最终结论。

    为了便于讨论,先引入形式符号。当我们使用TCP从A端到B端传输数据时,A与B间的网络链路是复杂的并且是动态变化的,但我们可以把A到B的网络想象成一段黑盒链路,这条链路有以下物理属性:

    • RTprop:光信号从A端到B端的最小时延(其实是2倍时延,因为是一个来回,但不影响讨论),这取决于物理距离
    • BtlBw:在A到B的链路中,它的带宽取决于最慢的那段链路的带宽,称为瓶颈带宽,可以想象为光纤的粗细
    • BtlBufSize:在A到B的链路中,每个路由器都有自己的缓存,这些缓存的容量之和,称为瓶颈缓存大小
    • BDP:整条物理链路(不含路由器缓存)所能储藏的比特数据之和,BDP = BtlBw * RTprop

    仅有物理属性还不够,在实际应用中我们最关心的是TCP链接的两个真实属性:

    • T(时延):数据从A到B的实际时延,对应于图中的round-trip time(其实是单程的trip time,2倍即为RTT,不影响讨论)
    • R(带宽):数据的实际传输带宽,对应于图中的delivery rate(并非严格对应,与T一样做了等效简化)

    我再啰嗦一句:TCP BBR协议定义的带宽(delivery rate)与我们的直觉不一样,它的定义是:

    带宽 = 数据量/从发送出去至收到ACK的时长

    而我们的直觉是:数据穿过网线的速度

    为了利于的直觉想象,本文使用T来代替RTT,使用R来代替delivery rate,下文的所有概念也一样作为简化,请注意!

    此外,为了定量分析T与R,再引入一个概念:

    • D:已经从A发出但未被B收到的数据(对应于inflight data,我故意修改了它的原始定义——A已经发出但未收到B返回的ACK的数据——是为了直觉想象,不影响结论)

    有了以上定义,很自然就有了以下3个式子:

    • T >= RTprop,即实际时延总是大于等于最小时延
    • R <= BtlBw,即实际带宽总是小于等于瓶颈带宽
    • R = D/T

    由以上3式可得:

    1. T/S >= 1/BtlBw
    2. R/S <= 1/RTprop

    1,2两式就是图中两个斜率(slope)的由来。

    有了上面的讨论,就可以较为轻松地理解上半图与下半图的物理意义了:

    上半图

    • 当链路上正在传输的比特数据未超过整条链路的物理容量(BDP)之前,传输时延的极限就是RTprop,对应上半图中蓝色的横线
    • 当数据塞满了整条链路的物理容量后,路由器开始启用缓存来存储比特数据,这相当于拉长了整个链路,造成传输时延开始变大,偏离了物理极限RTprop,于是有了slope = 1/BtlBw那条绿色斜线
    • 当路由器的缓存填满后(BDP+BtlBufSize),整条链路开始丢数据,1/BtlBw斜线消失,对应于上半图中红点虚线

    下半图

    • 当链路上正在传输的比特数据未超过整条链路的物理容量(BDP)之前,在B端观察到的数据带宽是逐渐往上涨的,这个带宽的上涨速率由5式确定,即slope = 1/RTprop,对应下半图中蓝色斜线
    • 当数据塞满了整条链路的物理容量后,路由器开始启用缓存来存储比特数据,但不影响B端观察到的带宽,这个带宽的极限就是BtlBw,对应于图中那条绿色的BtlBw横线
    • 当路由器的缓存填满后(BDP+BtlBufSize),整条链路开始丢数据,但B端观察到的带宽极限还是BtlBw,对应于下半图中红点虚线

    由此就可以解答这两个问题了:

    • 为何当前基于丢包探测的TCP拥塞控制算法还有优化空间?

    因为基于丢包探测的算法总会使inflight的数据量达到BDP+BtlBufSize这个状态,在现代的路由器中由于缓存很大,相当于把物理链路人为的拉长了,使数据传输的延时变大,即RTT变大。

    • BBR算法的优化极限在哪儿?

    BBR算法不再基于丢包探测,而是努力去估算BDP和RTprop,从而使RTT向它的物理极限RTprop靠近,从而减少传输时延,达到提速TCP的目的。

    那么BBR与丢包探测算法的共同点在哪里?——它们都试图使链路的带宽趋于它的物理极限:BtlBw。

    基于BBR算法,由于瓶颈路由器的队列为空,最直接的影响就是RTT大幅下降,可以看到下图中CUBIC红色线条的RTT比BBR要高很多:

    而因为没有丢包,BBR传输速率也会有大幅提升,下图中插入的图为CDF累积概率分布函数,从CDF中可以很清晰的看到CUBIC下大部分连接的吞吐量都更低:

    如果链路发生了切换,新的瓶颈带宽升大或者变小怎么办呢?BBR会尝试周期性的探测新的瓶颈带宽,这个周期值为1.25、0.75、1、1、1、1,如下所示:

    1.25会使得BBR尝试发送更多的飞行中报文,而如果产生了队列积压,0.75则会释放队列。下图中是先以10Mbps的链路传输TCP,在第20秒网络切换到了更快的40Mbps链路,由于1.25的存在BBR很快发现了更大的带宽,而第40秒又切换回了10Mbps链路,2秒内由于RTT的快速增加BBR调低了发送速率,可以看到由于有了pacing_gain周期变换BBR工作得很好。

    pacing_gain周期还有个优点,就是可以使多条初始速度不同的TCP链路快速的平均分享带宽,如下图所示,后启动的连接由于过高估计BDP产生队列积压,早先连接的BBR便会在数个周期内快速降低发送速率,最终由于不产生队列积压下RTT是一致的,故平衡时5条链路均分了带宽:

    我们再来看看慢启动阶段,下图网络是10Mbps、40ms,因此未确认的飞行字节数应为10Mbps*0.04s=0.05MB。红色线条是CUBIC算法下已发送字节数,而蓝色是ACK已确认字节数,绿色则是BBR算法下的已发送字节数。显然,最初CUBIC与BBR算法相同,在0.25秒时飞行字节数显然远超过了0.05MB字节数,大约在 0.1MB字节数也就是2倍BDP:

    大约在0.3秒时,CUBIC开始线性增加拥塞窗口,而到了0.5秒后BBR开始降低发送速率,即排空瓶颈路由器的拥塞队列,到0.75秒时飞行字节数调整到了BDP大小,这是最合适的发送速率。

    当繁忙的网络出现大幅丢包时,BBR的表现也远好于CUBIC算法。下图中,丢包率从0.001%到50%时,可以看到绿色的BBR远好于红色的CUBIC。大约当丢包率到0.1%时,CUBIC由于不停的触发拥塞算法,所以吞吐量极速降到10Mbps只有原先的1/10,而BBR直到5%丢包率才出现明显的吞吐量下降。

    CUBIC造成瓶颈路由器的缓冲队列越来越满,RTT时延就会越来越大,而操作系统对三次握手的建立是有最大时间限制的,这导致建CUBIC下的网络极端拥塞时,新连接很难建立成功,如下图中RTT中位数达到 100秒时 Windows便很难建立成功新连接,而200秒时Linux/Android也无法建立成功。

    BBR算法的伪代码如下,这里包括两个流程,收到ACK确认以及发送报文:

    function onAck(packet) 
      rtt = now - packet.sendtime 
      update_min_filter(RTpropFilter, rtt) 
      delivered += packet.size 
      delivered_time = now 
      deliveryRate = (delivered - packet.delivered) / (delivered_time - packet.delivered_time) 
      if (deliveryRate > BtlBwFilter.currentMax || ! packet.app_limited) 
         update_max_filter(BtlBwFilter, deliveryRate) 
      if (app_limited_until > 0) 
         app_limited_until = app_limited_until - packet.size

    这里的app_limited_until是在允许发送时观察是否有发送任务决定的。发送报文时伪码为:

    function send(packet) 
      bdp = BtlBwFilter.currentMax × RTpropFilter.currentMin 
      if (inflight >= cwnd_gain × bdp) 
         // wait for ack or retransmission timeout 
         return 
      if (now >= nextSendTime) 
         packet = nextPacketToSend() 
         if (! packet) 
            app_limited_until = inflight 
            return 
         packet.app_limited = (app_limited_until > 0) 
         packet.sendtime = now 
         packet.delivered = delivered 
         packet.delivered_time = delivered_time 
         ship(packet) 
         nextSendTime = now + packet.size / (pacing_gain × BtlBwFilter.currentMax) 
      timerCallbackAt(send, nextSendTime)

    pacing_gain便是决定链路速率调整的关键周期数组。

    BBR算法对网络世界的拥塞控制有重大意义,尤其未来可以想见路由器的队列一定会越来越大。HTTP3放弃了TCP协议,这意味着它需要在应用层(各框架中间件)中基于BBR算法实现拥塞控制,所以,BBR算法其实离我们很近。理解BBR,我们便能更好的应对网络拥塞导致的性能问题,也会对未来的拥塞控制算法发展脉络更清晰。

     

    展开全文
  • TCP BBR(Bottleneck Bandwidth and Round-trip propagation time)是由Google设计,于2016年发布的拥塞算法。以往大部分拥塞算法是基于丢包来作为降低传输速率的信号,而BBR则基于模型主动探测。该算法使用网络最近...

    TCP BBR(Bottleneck Bandwidth and Round-trip propagation time)是由Google设计,于2016年发布的拥塞算法。以往大部分拥塞算法是基于丢包来作为降低传输速率的信号,而BBR则基于模型主动探测。该算法使用网络最近出站数据分组当时的最大带宽和往返时间来创建网络的显式模型。数据包传输的每个累积或选择性确认用于生成记录在数据包传输过程和确认返回期间的时间内所传送数据量的采样率。

    Google在YouTube上应用该算法,将全球平均的YouTube网络吞吐量提高了4%,在一些国家超过了14%。根据实地测试,在部署了最新版内核并开启了 TCP BBR 的机器上,网速甚至可以提升好几个数量级。

    从 4.9 开始,Linux 内核已经用上了该算法,并且对于QUIC可用。如果想在Linux使用BBR,那么首先就是判断内核版本是否大于4.9,如果符合版本标准,那么直接启动BBR就可以了,如果低于4.9,升级内核之后启动就行了。

    下面就介绍一下在CentOS 7.3上安装TCP BBR的方法。

    CentOS 7安装TCP BBR拥塞算法

    首先将Centos系统更新,更新到7.3版本。

    yum update

    查看系统版本,输出的release数值大于7.3即可。

    cat /etc/redhat-release

    对于某些机器来说,安装一下wget

    yum install wget

    方法1:自动安装,使用一键安装脚本

    wget --no-check-certificate https://github.com/teddysun/across/raw/master/bbr.sh && chmod +x bbr.sh && ./bbr.sh

    方法2:手动安装

    使用下面命令安装elrepo并升级内核

    rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org

    rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-2.el7.elrepo.noarch.rpm

    yum --enablerepo=elrepo-kernel install kernel-ml -y

    更新grub文件并重启(reboot后,ssh会断开,稍等一会儿重新连接)

    egrep ^menuentry /etc/grub2.cfg | cut -f 2 -d \'

    grub2-set-default 0

    reboot

    开机后查看内核是否已更换为4.9

    uname -r

    启动BBR。依次执行下面命令就可以了。

    echo "net.core.default_qdisc = fq" >> /etc/sysctl.conf

    echo "net.ipv4.tcp_congestion_control = bbr" >> /etc/sysctl.conf

    sysctl -p

    验证bbr是否已经开启

    A,验证当前TCP控制算法的命令:

    sysctl net.ipv4.tcp_available_congestion_control

    返回值一般为:net.ipv4.tcp_available_congestion_control = bbr cubic reno 或者为:net.ipv4.tcp_available_congestion_control = reno cubic bbr

    B,验证BBR是否已经启动。

    sysctl net.ipv4.tcp_congestion_control

    返回值一般为:net.ipv4.tcp_congestion_control = bbr

    lsmod | grep bbr

    返回值有 tcp_bbr 模块即说明 bbr 已启动。

    展开全文
  • Google tcp bbr拥塞算法实测

    千次阅读 2018-05-29 20:56:11
    TCP拥塞控制的策略可以总结为,“”增性加,乘性减“”。TCP每个包的数据大小MSS,由双方协议决定。如何决定什么时候应该往网络中扔多少数据包呢?一开始TCP拥塞策略采用慢...TCP拥塞算法是一种不贴合实际的算法,...
  • 之前其实写过一篇类似文章,也是有关于CUBIC与BBR算法的比较。但是那一篇文章大多是比较感性的探讨,并没有仿真数据作为支撑。所以这里我将会结合数据对CUBIC与BBR的公平性进行探讨。 (万分感谢@Soonyang Zhang学长...
  • Google BBR是一个TCP加速优化工具,类似于锐速,可用于优化 TCP 连接。最近一下就火起来了,说明还是有牛逼的地方,咱也别落后,用起来。GitHub 地址为:https://github.com/google/bbr仔细看了看,GitHub 主页上有...
  • RTMP视频源站一般都需要建在国内的服务器上。...据网络测试,在部署了最新版内核并开启了TCP BBR 的机器上,网速甚至可以提升好几个数量级。 首先,检查一下内核版本: #uname -r 查看内核版本,含有 >4....
  • bbr拥塞算法不再跟踪系统的TCP拥塞状态机,而旨在用统一的方式来应对pacing rate和cwnd的计算. tcp是根据丢包,bbr是根据bw和rtt?bbr发送加了一个pacer,防止一下发送太多. BBR的组成 bbr算法实际上非常简单,在...
  • BBR拥塞控制算法

    2016-12-25 21:16:00
    BBR拥塞控制算法是Google最新研发的单边TCP拥塞控制算法Linux 内核4.9 已引入这个BBR算法,本人在CAC测试Ubuntu 14.04 安装Linux 4.9内核,延迟优化效果和TCP连接速度提升效果明显好于锐速!Ubuntu更新内核、开启BBR...
  • Google's BBR拥塞控制算法模型解析.pdf
  • 开启TCP BBR拥塞控制算法

    千次阅读 2017-04-11 20:04:16
    什么是BBR TCP BBR是谷歌出品的TCP拥塞控制算法。... BBR算法,Google已经提交到Linux主线并发表在ACM queue期刊上的TCP-BBR拥塞控制算法。在新的linux内核上已经附带了BBR,升级内核即可开启。  BBR解决了两个问题
  • 谈TCP BBR拥塞控制算法

    千次阅读 2019-07-17 00:48:46
    说是tcp拥塞控制,也不完全是,因为quic也使用bbr作为拥塞控制算法。quic当道,其而bbr发布前,也已经在google和youtube证明了其在吞吐和延迟上优良的性能, 标准TCP的问题 基于丢包的拥塞控制算法,来说标准TCP...
  • Google BBR拥塞控制算法背后的数学解释
  • Google's BBR拥塞控制算法模型解析
  • CentOS使用bbr拥塞控制算法

    千次阅读 2017-07-03 17:34:29
    CentOS使用bbr拥塞控制算法 一.升级CentOS的Linux内核(bbr算法出现在Linux4.9及以上内核版本)   升级内核的方式有两种,一个是通过编译内核包进行安装升级,一个是直接使用rpm包进行升级; 为了提高升级速度...
  • BBR算法是Google推出的一套TCP拥塞控制算法,可优化TCP协议。 二,优化场景 BBR可优化因网络掉包引起的网络卡顿问题,比如云服务器在某个时段因网络链路质量抖动而出现掉包,当掉包达到一定程度时,业务访问就会...
  • TCP BBR拥塞控制算法解析

    万次阅读 多人点赞 2017-07-28 14:22:35
    2016年底,Google发表了一篇优化tcp传输算法的文章,极大的提高了tcp得throughput,并且已经集成到Linux ...本文给出了论文中省略的一些背景知识,并结合自己的理解做了更加细节的介绍,可以帮助读者理解整个bbr算法
  • Google's BBR拥塞控制算法如何对抗丢包
  • Ubuntu 17.04 开启 TCP BBR 拥塞控制算法 概述 TCP BBR 由谷歌开发,即 TCP 拥塞控制算法,其目的在于最大化利用网络链路。知乎上的解释非常贴切,一条网络链路就像一根水管,最大化利用这根水管的办法则是...
  • 一文解释清楚Google BBR拥塞控制算法原理

    千次阅读 多人点赞 2019-08-07 09:07:14
    BBR对TCP性能的提升是巨大的,它能更有效的使用当下网络环境,Youtube应用后在吞吐量上有平均4%提升(对于日本这样的网络环境有14%以上的提升): 报文的往返时延RTT降低了33%,这样如视频这样的大文件传输更快,...
  • 本文转载自《Linux Kernel 4.9 中的 BBR 算法与之前的 TCP 拥塞控制相比有什么优势?》 中国科大 LUG 的 @高一凡 在 LUG HTTP 代理服务器上部署了 Linux 4.9 的 TCP BBR 拥塞控制算法。从科大的移动出口到...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,001
精华内容 400
关键字:

bbr拥塞算法