In some cases it might be useful to compare remote load values of different servers and use these values to determine the server with the lowest load. Practical examples would be a provisioning server or a load balancing server.
The current load averages (1min, 5min, 15min) can be displayed by using /proc/loadavg:
cat /proc/loadavg
0.18 0.24 0.20 1/563 28186
For balancing or provisioning purposes, the value to take a look at is the third value which is the load average during the last 15 minutes.
cat /proc/loadavg | awk '{print $3}'
0.20
This of course also possible by using a remote SSH command (don't forget to escape the Dollar sign):
ssh root@remoteserver "cat /proc/loadavg | awk '{print \$3}'"
0.05
To get the current load average on a bunch of server and to show the server with the lowest cpu load (in the last 15 minutes), the following script can be launched:
for server in server01 server02 server03 server04; do
case $server in
server01) load[1]=$(ssh root@$server "cat /proc/loadavg | awk '{print \$3}'");;
server02) load[2]=$(ssh root@$server "cat /proc/loadavg | awk '{print \$3}'");;
server03) load[3]=$(ssh root@$server "cat /proc/loadavg | awk '{print \$3}'");;
server04) load[4]=$(ssh root@$server "cat /proc/loadavg | awk '{print \$3}'");;
esac
done
echo "${load[*]}" | tr ' ' '\n' | awk 'NR==1{min=$0}NR>1 && $1
Server #:3 Load: 0.07
This can of course easily be verified
echo ${load[@]}
0.22 0.36 0.07 0.20 0.30
As a short explanation what this scriopt is doing:
For each server, a remote ssh command is executed to get the current 15min load average value. This value is saved into an array "load" and the array index number "1" (because I start with server #1, the array index should have the same number as the servername). After the for loop, the full array "load" is returned. Each array value is compared with the previous array value. If the current array value is smaller than the previous one, then the variable "min" is set with the value value of the new lowest value. Besides that, the variable "pos" is set, which defines the position of the current value (NR).
At the end, the information is printed to stdout with additional information ("Server #" and "Load:") as strings.
This of course also works without the case loop (see below) but the case loop may be helpful if additional information wants to be gathered at the same time.
i=1; for server in server01 server02 server03 server04 server05; do
myload[$i]=$(ssh root@$server "cat /proc/loadavg | awk '{print \$3}'")
let i++
done
echo "${myload[*]}" | tr ' ' '\n' | awk 'NR==1{min=$0}NR>1 && $1
Server #:3 Load: 0.06
Source for this very neat awk comparison: http://stackoverflow.com/questions/16610162/bash-return-position-of-the-smallest-entry-in-an-array
Update September 29th 2014: I had an issue today with exactly this method, when every variable in the array had the same value. See "awk issue when trying to sort variables with same values" for a solution.
No comments yet.
AWS Android Ansible Apache Apple Atlassian BSD Backup Bash Bluecoat CMS Chef Cloud Coding Consul Containers CouchDB DB DNS Database Databases Docker ELK Elasticsearch Filebeat FreeBSD Galera Git GlusterFS Grafana Graphics HAProxy HTML Hacks Hardware Icinga Influx Internet Java KVM Kibana Kodi Kubernetes LVM LXC Linux Logstash Mac Macintosh Mail MariaDB Minio MongoDB Monitoring Multimedia MySQL NFS Nagios Network Nginx OSSEC OTRS Office PGSQL PHP Perl Personal PostgreSQL Postgres PowerDNS Proxmox Proxy Python Rancher Rant Redis Roundcube SSL Samba Seafile Security Shell SmartOS Solaris Surveillance Systemd TLS Tomcat Ubuntu Unix VMWare VMware Varnish Virtualization Windows Wireless Wordpress Wyse ZFS Zoneminder