Difference between revisions of "TCP-Tuning"

Un article de lcgwiki.
Jump to: navigation, search
(External links)
(Kernel tuning)
Ligne 100: Ligne 100:
  
 
Par exemple sur un SUN X4500 si vous faites "echo 256 > /sys/block/sda/device/queue_depth", vous aurez en fait 31 (la valeur max autorisée) dans queue_depth.
 
Par exemple sur un SUN X4500 si vous faites "echo 256 > /sys/block/sda/device/queue_depth", vous aurez en fait 31 (la valeur max autorisée) dans queue_depth.
 +
 +
Voici le script que je lance automatiquement à l'IPNO sur chaque disk server après le boot (je ne suis pas sur qu'il est universel et il a été écrit il y a des années). A tester voir s'il peut marcher chez vous:
 +
 +
<pre>
 +
[root@ipngridxrd2 bin]# pwd
 +
/usr/local/bin
 +
[root@ipngridxrd2 bin]# cat tune_disks_io.sh
 +
#!/bin/bash
 +
 +
function f_get_disks_list {
 +
  # Obtenir la liste des disques de donnes
 +
  # Je suppose qu'il n'y a pas de melange RAID linux (/dev/mdXX) et hardware (/dev/sdXX) sur la meme machine
 +
 +
  # On supprime les disques systemes de la liste fournie par df
 +
  # Liste des disks avec le type de fs (xfs, ext3, ext4)
 +
  local l_disks_type_list=$(df -P -T |egrep -v "Filesystem|\/$|\/opt|\/tmp|\/var|\/usr|\/boot|tmpfs|varvol|tmpvol|usrvol|optvol" |egrep 'xfs|ext4|ext3' | awk '{print $1 " " $2 }')
 +
  echo  ${l_disks_type_list}
 +
}
 +
 +
function f_tune_io {
 +
  # Usage : f_tune_io block_device
 +
  # Exemple : f_tune_io.sh sdb
 +
  [ $# != 1 ] && echo "Usage: f_tune_io block_device" && return 1
 +
  local blockdev=$1
 +
  #echo ${blockdev}
 +
  echo "....................... Avant le tuning .........................."
 +
  f_check_tune ${blockdev}
 +
  QUEUE_DEPTH=$(cat /sys/block/${blockdev}/device/queue_depth)
 +
  [ $QUEUE_DEPTH -lt 128 ] && QUEUE_DEPTH=128 # si c'est plus grand on le garde
 +
  dmidecode  -s system-product-name | egrep -q 'Sun Fire X4500'
 +
  [ $? -eq 0 ] && QUEUE_DEPTH=31
 +
  dmidecode  -s system-product-name | egrep -q 'Sun Fire X4540'
 +
  [ $? -eq 0 ] && QUEUE_DEPTH=127
 +
  echo ${QUEUE_DEPTH} > /sys/block/${blockdev}/device/queue_depth # 31 sur les SUN X4500, 128 ou 256 sur Dell
 +
  echo 512 > /sys/block/${blockdev}/queue/nr_requests  #  (au lieu de 128)
 +
  echo deadline > /sys/block/${blockdev}/queue/scheduler #(au lieu de cfq)
 +
  blockdev --setra 16384 /dev/${blockdev} #(au lieu de 256)
 +
  echo "....................... Apres le tuning .........................."
 +
  f_check_tune ${blockdev}
 +
}
 +
 +
function f_tune_md_io {
 +
  # Usage : f_tune_md_io md_device
 +
  # Exemple : f_tune_md_io .sh md11
 +
  [ $# != 1 ] && echo "Usage: $0 md_device. Exemple: f_tune_md_io md11" && return 1
 +
 +
  local mddev=$1
 +
  echo "+++++++++++++++++++++++++ MD DEVICE = ${mddev} +++++++++++++++++++++++"
 +
 +
  local disks=$(mdadm --query --detail /dev/${mddev}|grep 'active sync'|awk '{print $NF}')
 +
  local i
 +
  local j
 +
  for i in ${disks}; do
 +
    # /dev/sde1 deviendra sde
 +
    j=$(echo $i | awk -F/ '{print $NF}') # /dev/sde1 ==> sde1
 +
    j=${j%%[0-9]}                    # sde1 ==> sde
 +
    echo "Tuning ${j} ....................................................."
 +
    f_tune_io $j
 +
  done
 +
}
 +
 +
 +
function f_check_tune {
 +
  # Usage : f_check_tune block_device
 +
  # Exemple : f_check_tune sdb
 +
  [ $# != 1 ] && echo "Usage: f_check_tune block_device. Exemple: f_check_tune sdb" && return 1
 +
 +
  local i=$1
 +
 +
  echo -n "blockdev --getra /dev/$i : "
 +
  blockdev --getra /dev/$i
 +
  echo -n "cat /sys/block/$i/device/queue_depth : "
 +
  cat /sys/block/$i/device/queue_depth
 +
  echo -n "cat /sys/block/$i/queue/nr_requests : "
 +
  cat /sys/block/$i/queue/nr_requests
 +
  echo -n "cat /sys/block/$i/queue/scheduler : "
 +
  cat /sys/block/$i/queue/scheduler
 +
}
 +
 +
# Debut tuning
 +
echo " ======= I/O tuning : $(date) ======= "
 +
disks_type_list=$(f_get_disks_list)
 +
disks_list=$(echo ${disks_type_list} | sed -e 's/\b\(xfs\|ext4\|ext3\)\b//g' |sort -u)
 +
echo ${disks_list}
 +
 +
#NB: effet su sed :remplace par exemple /dev/sda1 par sda
 +
sd_devices=$(echo ${disks_list} | grep "\/dev\/sd" | sed 's/\(\/dev\/\|[0-9]\)//g' | tr '[:space:]' "\n" | sort -u | tr "\n" " ")
 +
#NB: effet su sed :remplace par exemple /dev/md11 par md11
 +
md_devices=$(echo ${disks_list} | grep "\/dev\/md" | sed 's/\/dev\///g')
 +
lvm_devices=$(echo ${disks_list} | grep "\/dev\/mapper")
 +
 +
echo "sd_devices = ${sd_devices}"
 +
echo "md_devices = ${md_devices}"
 +
echo "lvm_devices = ${lvm_devices}"
 +
[ ! -z "${sd_devices}" ] && for d in ${sd_devices}; do
 +
  echo f_tune_io ${d}
 +
  f_tune_io ${d}
 +
done
 +
 +
[ ! -z "${md_devices}" ] && for d in ${md_devices}; do
 +
  echo f_tune_md_io ${d}
 +
  f_tune_md_io ${d}
 +
done
 +
 +
# Rechercher les VG puis les PV et les disque entiers puis tuner
 +
#[ ! -z "${lvm_devices}" ] && for d in ${lvm_devices}; do
 +
#  echo "tune_lvm_io ${d} not implemented yet"
 +
#done
 +
</pre>
  
 
== External links ==
 
== External links ==

Version du 15:54, 3 mars 2016

TCP Performance

This page describes how to enhance the performance of data transfers. It mainly focus on the optimization of the Linux kernel parameters.

Quattor

The Quattor TCP Tuning guide aims to be a good documentation for helping you tuning your TCP Performance with Quattor.


Kernel tuning

The following parameters are important for TCP tuning:

  • net.ipv4.tcp_rmem
  • net.ipv4.tcp_wmem
  • net.core.rmem_default
  • net.core.wmem_default
  • net.core.rmem_max
  • net.core.wmem_max
  • net.ipv4.tcp_dsack
  • net.ipv4.tcp_sack
  • net.ipv4.tcp_timestamps
  • net.core.netdev_max_backlog

They can be modified:

  • By directly passing the parameter to the sysctl command. This method is useful for testing a parameter, as the modification will not persist after the next reboot.
  • By adding the parameter to the /etc/sysctl.conf file and loading it with the sysctl command. This way is interesting when you want to preserve the modification over a reboot.

The following values are recommended:

  • net.ipv4.tcp_rmem = 131072 1048576 2097152
  • net.ipv4.tcp_wmem = 131072 1048576 2097152
  • net.core.rmem_default = 1048576
  • net.core.wmem_default = 1048576
  • net.core.rmem_max = 2097152
  • net.core.wmem_max = 2097152
  • net.ipv4.tcp_dsack = 0
  • net.ipv4.tcp_sack = 0
  • net.ipv4.tcp_timestamps = 0
  • net.core.netdev_max_backlog = 10000

External links

Tuning disk I/O

Kernel tuning

Le fait d'ajuster quelques paramètres du kernel permet d'améliorer les performances au niveau des I/O disques. Le tuning doit être fait au niveau des block devices après chaque reboot du serveur. Ce tuning peut être très utile sur les serveurs de fichiers (DPM disk servers, xrootd servers, ...).

Voici les valeurs recommandées pour un disque /dev/sdb par exemple :

  • getra : 16384
  • queue_depth : 256
  • nr_requests : 512
  • scheduler : deadline (au lieu de cfq)

Pour lire les valeurs actuelles de votre serveur pour le disque /dev/sdb, faire:

blockdev --getra /dev/sdb
cat /sys/block/sdb/device/queue_depth
cat /sys/block/sdb/queue/nr_requests
cat /sys/block/sdb/queue/scheduler

Exemple:

# blockdev --getra /dev/sdb
16384
# cat /sys/block/sdb/device/queue_depth
256
# cat /sys/block/sdb/queue/nr_requests
512
# cat /sys/block/sdb/queue/scheduler
noop anticipatory [deadline] cfq 
# 

Pour faire le tuning des I/O pour le disque sdb, faire:

blockdev=sdb
blockdev --setra 16384 /dev/${blockdev}
echo 512 > /sys/block/${blockdev}/queue/nr_requests
echo deadline > /sys/block/${blockdev}/queue/scheduler
echo 256 > /sys/block/${blockdev}/device/queue_depth

Le plus simple est de faire un script qui boucle sur tous les 'block devices' à tuner et d'ajuster les paramètres kernel pour chaque disque.

N.B.: chaque site peut tester éventuelement d'autres valeurs et benchmarker pour trouver les valeurs appropriées pour ses serveurs.

Une remarque concernant queue_depth: selon le modèle de serveur, il y a une valeur max qui ne peut être dépassée. Si on essaye d'affecter une valeur plus grande, c'est la valeur max possible qui sera affectée à queue_depth.

Par exemple sur un SUN X4500 si vous faites "echo 256 > /sys/block/sda/device/queue_depth", vous aurez en fait 31 (la valeur max autorisée) dans queue_depth.

Voici le script que je lance automatiquement à l'IPNO sur chaque disk server après le boot (je ne suis pas sur qu'il est universel et il a été écrit il y a des années). A tester voir s'il peut marcher chez vous:

[root@ipngridxrd2 bin]# pwd
/usr/local/bin
[root@ipngridxrd2 bin]# cat tune_disks_io.sh 
#!/bin/bash

function f_get_disks_list {
  # Obtenir la liste des disques de donnes
  # Je suppose qu'il n'y a pas de melange RAID linux (/dev/mdXX) et hardware (/dev/sdXX) sur la meme machine

  # On supprime les disques systemes de la liste fournie par df
  # Liste des disks avec le type de fs (xfs, ext3, ext4)
  local l_disks_type_list=$(df -P -T |egrep -v "Filesystem|\/$|\/opt|\/tmp|\/var|\/usr|\/boot|tmpfs|varvol|tmpvol|usrvol|optvol" |egrep 'xfs|ext4|ext3' | awk '{print $1 " " $2 }')
  echo  ${l_disks_type_list}
}

function f_tune_io {
  # Usage : f_tune_io block_device
  # Exemple : f_tune_io.sh sdb
  [ $# != 1 ] && echo "Usage: f_tune_io block_device" && return 1
  local blockdev=$1
  #echo ${blockdev}
  echo "....................... Avant le tuning .........................."
  f_check_tune ${blockdev}
  QUEUE_DEPTH=$(cat /sys/block/${blockdev}/device/queue_depth)
  [ $QUEUE_DEPTH -lt 128 ] && QUEUE_DEPTH=128 # si c'est plus grand on le garde
  dmidecode  -s system-product-name | egrep -q 'Sun Fire X4500'
  [ $? -eq 0 ] && QUEUE_DEPTH=31
  dmidecode  -s system-product-name | egrep -q 'Sun Fire X4540'
  [ $? -eq 0 ] && QUEUE_DEPTH=127
  echo ${QUEUE_DEPTH} > /sys/block/${blockdev}/device/queue_depth # 31 sur les SUN X4500, 128 ou 256 sur Dell
  echo 512 > /sys/block/${blockdev}/queue/nr_requests  #   (au lieu de 128)
  echo deadline > /sys/block/${blockdev}/queue/scheduler #(au lieu de cfq)
  blockdev --setra 16384 /dev/${blockdev} #(au lieu de 256)
  echo "....................... Apres le tuning .........................."
  f_check_tune ${blockdev}
}

function f_tune_md_io {
  # Usage : f_tune_md_io md_device
  # Exemple : f_tune_md_io .sh md11
  [ $# != 1 ] && echo "Usage: $0 md_device. Exemple: f_tune_md_io md11" && return 1

  local mddev=$1
  echo "+++++++++++++++++++++++++ MD DEVICE = ${mddev} +++++++++++++++++++++++"

  local disks=$(mdadm --query --detail /dev/${mddev}|grep 'active sync'|awk '{print $NF}')
  local i
  local j
  for i in ${disks}; do
    # /dev/sde1 deviendra sde
    j=$(echo $i | awk -F/ '{print $NF}') # /dev/sde1 ==> sde1
    j=${j%%[0-9]}                     # sde1 ==> sde
    echo "Tuning ${j} ....................................................."
    f_tune_io $j
  done
}


function f_check_tune {
  # Usage : f_check_tune block_device
  # Exemple : f_check_tune sdb
  [ $# != 1 ] && echo "Usage: f_check_tune block_device. Exemple: f_check_tune sdb" && return 1

  local i=$1

  echo -n "blockdev --getra /dev/$i : "
  blockdev --getra /dev/$i
  echo -n "cat /sys/block/$i/device/queue_depth : "
  cat /sys/block/$i/device/queue_depth
  echo -n "cat /sys/block/$i/queue/nr_requests : "
  cat /sys/block/$i/queue/nr_requests
  echo -n "cat /sys/block/$i/queue/scheduler : "
  cat /sys/block/$i/queue/scheduler
}

# Debut tuning
echo " ======= I/O tuning : $(date) ======= "
disks_type_list=$(f_get_disks_list) 
disks_list=$(echo ${disks_type_list} | sed -e 's/\b\(xfs\|ext4\|ext3\)\b//g' |sort -u)
echo ${disks_list}

#NB: effet su sed :remplace par exemple /dev/sda1 par sda
sd_devices=$(echo ${disks_list} | grep "\/dev\/sd" | sed 's/\(\/dev\/\|[0-9]\)//g' | tr '[:space:]' "\n" | sort -u | tr "\n" " ")
#NB: effet su sed :remplace par exemple /dev/md11 par md11
md_devices=$(echo ${disks_list} | grep "\/dev\/md" | sed 's/\/dev\///g')
lvm_devices=$(echo ${disks_list} | grep "\/dev\/mapper")

echo "sd_devices = ${sd_devices}"
echo "md_devices = ${md_devices}"
echo "lvm_devices = ${lvm_devices}"
[ ! -z "${sd_devices}" ] && for d in ${sd_devices}; do
  echo f_tune_io ${d}
  f_tune_io ${d}
done

[ ! -z "${md_devices}" ] && for d in ${md_devices}; do
  echo f_tune_md_io ${d}
  f_tune_md_io ${d}
done

# Rechercher les VG puis les PV et les disque entiers puis tuner
#[ ! -z "${lvm_devices}" ] && for d in ${lvm_devices}; do
#  echo "tune_lvm_io ${d} not implemented yet"
#done

External links