november 2008 Archieven
Waarom atop niet op 1?
Geplaatst door gerlof op woensdag 19 november 2008 | Permanente link | Categorie: ATComputing | Reacties: 0
atop, de bijdrage van AT Computing aan de open source community heeft een zeer respectabele tweede plaats behaald in de Amerikaanse uitgave van het onafhankelijke Linux Magazine. Uiteraard vinden onze experts dat het eigenlijk een eerste plaats had moeten zijn, waarom? Dat kunt u hieronder lezen.
Met de ontwikkeling van atop is begonnen toen bleek dat we bij performance-gerelateerde consultancy-opdrachten met de oude trouwe top niet konden zien waar de werkelijke ''resource lekken'' zaten.
Net als atop, deelt top het scherm in tweeën: de bovenste helft voor systeemgegevens, de onderste helft voor individuele processen. Zoals een boekhouder graag ziet waar de post "uitgaven secretariaat" uit bestaat, zo ziet de performance analist graag waar de "kostenpost" 85% CPU-belasting uit bestaat. Boven de streep zien we dat die 85% bezetting bestaat uit bijv. 45% user-mode CPU-belasting en 40% kernel-mode CPU-belasting.
Top splitst op systeemniveau het CPU-verbruik wel op in user mode en kernel mode, maar niet voor individuele processen; top drukt slechts het totaal van die twee af.
Ten tweede kan "top" de totaaltelling niet rond krijgen: de totaaltelling van CPU-tijden onder de streep klopt bijna nooit met de gegevens op systeem-niveau boven de streep. De reden daarvoor is dat top alleen informatie geeft (en kan geven) over processen die lopen op het moment dat top weer een snapshot neemt; processen die tijdens het interval gestopt zijn worden dus niet getoond. Atop krijgt via de standaard Linux-faciliteit "process accounting" ook informatie over processen die sinds de vorige snapshot geëindigd zijn, en neemt het CPU-verbruik van deze processen (voordat ze eindigden) mee in de telling. Bij atop klopt de totaaltelling van CPU-verbruik "onder de streep" dus met de systeemgegevens.
Niet alleen CPU-tijd is van belang: ook over de gebruikte disk- en netwerk-I/O wil je graag weten wat het totaalverbruik is op systeemniveau en per proces. Dat is iets dat top in het geheel niet kan. Daarnaast is atop nauwkeuriger als het gaat om het geheugengebruik. Snelle en voortdurende groeiers in geheugengebruik zijn belangrijker om ``bovenaan'' te zetten dan processen die al geruime tijd draaien en een constant (groot) geheugengebruik laten zien.
Op deze manier kan atop van de vier belangrijkste resources CPU, geheugen, disk-I/O en netwerk-I/O een actuele, kloppende boekhouding laten zien, waar top dat niet of slechts gedeeltelijk kan.
Daarnaast biedt atop nog een bijzondere faciliteit: je kunt atop iedere N minuten een snapshot laten nemen en op laten slaan in een logfile. Vervolgens kun je interactief door deze file heenwandelen, net zoals je dat op de normale manier met atop kunt. Een klacht als "om kwart voor vier was het systeem zó traag..." kun je op deze manier ook de volgende dag nog herleiden tot een op hol geslagen geheugenvretend proces dat het systeem ernstig deed swappen. Uiteraard kan atop ook een tekst-gebaseerde datastroom opleveren zodat je makkelijk met grep, awk en dergelijke aan de slag kunt.
Omdat atop toch al iedere N minuten een snapshot neemt, kan atop -- op dezelfde manier als het commando sar dat doet -- voor systeem-resources een overzicht geven van de belasting door de tijd.
Al met al geeft atop meer en nuttiger informatie dan top. Enthousiast geworden? Kijk op http://www.atcomputing.nl/Tools/atop/ voor meer informatie, screenshots en downloads!
Zie http://www.linux-magazine.com/w3/issue/97/TheBestTopToolsReview.pdf voor het artikel van Linux Magazine.
Shell scripting
Geplaatst door miekg op woensdag 12 november 2008 | Permanente link | Categorie: Tips and Tricks | Reacties: 0
Als je in de UNIX shell programmeert dan gebruik je veel
externe utilities om files te manipuleren. Standaard
utilities zoals head en tail bijvoorbeeld.
Het telkens opstarten van zo'n tooltje levert
een (kleine) performance hit op. Zou het daarom niet beter
zijn om deze te vervangen door pure shell varianten?
Voor head en tail hebben we dit gedaan in de
zsh shell (homepage). Er was wel
een paar problemen die opgelost moesten worden:
- interpretatie van escape sequences (bv
\n) in de files. - lege regels die hier en daar op de proppen kwamen.
Samen met Ton Kersten kwamen we tot de volgende implementaties.
head
Het volgende zsh script implementeert head, er worden twee
opties ondersteund: -n N om het aantal regels te selecteren
en een -h voor een kleine help.
1 #!/bin/zsh
2 IAM="${0##*/}"
3 typeset -i n=0
4
5 o_line=(-n 10)
6 zparseopts -D -K -- n:=o_line h=o_help
7 if [[ $? != 0 || "$o_help" != "" ]]; then
8 echo "Usage: $IAM [-n LINES] [-h]"
9 exit 1
10 fi
11
12 o_line=$o_line[2]
13 files=($@)
14 [[ $o_line -le 0 ]] && exit
15 [[ $# -eq 0 ]] && files=(/dev/stdin)
16
17 IFS=''
18 for f in $files; do
19 n=0
20 while read -r line; do
21 print "${line//\\/\\\\}"
22 n=n+1
23 [[ $n -ge $o_line ]] && break
24 done < $f
25 done
De regels 1-10 zorgen voor de optie parsering en initialiseren wat
variabelen. Vanaf regel 12 wordt het interessant. De variabele $o_line
heeft in het tweede element het aantal regels dat we willen zien.
Hier pakken we dat getal.
Regel 13; de array files wordt gevuld met de overgebleven argumenten.
Regel 14; als het aantal regels dat we willen zien kleiner gelijk 0 is, zijn we snel klaar.
Regel 15; geen files opgegeven? Dan gebruiken we standaard input.
Regel 17; zorg ervoor de er geen interpretaties plaatsvinden door
IFS (Internal Field Seperator) variabele leeg te maken.
Regel 18; start de loop die over onze files heen loopt, deze loop eindigt op regel 25.
Regel 20; lees een regel uit de file, gebruik -r voor raw mode
(geen interpretatie).
Regel 21: als we een escape karakter tegenkomen, escape deze dan nogmaals, zodat deze weer normaal op het scherm terecht komt als we gaan printen.
Regels 22-23: hebben we al genoeg regels gelezen? Zo ja, ga dan verder met de volgende file.
Regel 24: laat de while-read-loop uit de huidige file lezen.
tail
Hier de implementatie voor tail:
1 #!/bin/zsh
2 IAM="${0##*/}"
3 typeset -i n=0
4
5 o_line=(-n 10)
6 zparseopts -D -K -- n:=o_line h=o_help
7 if [[ $? != 0 || "$o_help" != "" ]]; then
8 echo "Usage: $IAM [-n LINES] [-h]"
9 exit 1
10 fi
11
12 o_line=$o_line[2]
13 files=($@)
14 [[ $o_line -le 0 ]] && exit
15 [[ $# -eq 0 ]] && files=(/dev/stdin)
16
17 IFS=''
18 for f in $files
19 do
20 lines=()
21 n=1
22 while read -r line
23 do
24 lines[$n]+="${line//\\/\\\\}\n"
25 n=n+1
26
27 if [[ $n -gt $o_line ]]
28 then
29 let b=$n-$o_line-1
30 lines[$b]=""
31 fi
32 done < $f
33 print "${lines%%\\n}"
34 done
Het begin van tail is bijna identiek aan die van head. De
belangrijkste loop begint hier op regel 18. Het gebruikte algoritme van tail is om
de laatste N regels te onthouden zodat die, als we het einde van de file
hebben bereikt, geprint kunnen worden.
Een tweede iets dat hier gebruikt wordt is dat een waarde in een array in ZSH geleegd kan worden door er een lege string aan toe te wijzen (regels 30 en 31). Zo houden we niet de hele file in memory, maar alleen het stuk dat we willen tailen.
Regel 33 is nodig om de laatste newline in $lines er weer af te strippen.
Is het nu sneller?
Laten we een paar tests doen met een file op een Linuxsysteem,
namelijk /proc/interrupts. De scripts hierboven zijn voor
deze tests omgebouwd tot de functies: tail_zsh en head_zsh. Dit
heeft tot gevolg dat er geen fork wordt uitgevoerd.
Voor de tests gebruiken we de volgende command line:
time ( for i in $(seq 0 20000); do $prog -n 15 /proc/interrupts > /dev/null; done )
Waarbij $prog, respectievelijk head, head_zsh, tail en tail_zsh
is.
head vs head_zsh
Voor head:
0.11s user 0.01s system 0.12s elapsed
En head_zsh:
0.11s user 0.01s system 0.12s elapsed
tail vs tail_zsh
Voor tail is de timing:
0.11s user 0.02s system 0.12s elapsed
En voor tail_zsh:
0.11s user 0.01s system 0.12s elapsed
Het lijkt erop dat onze implementaties dus net zo snel zijn als de standaard
Linux tools. Waarschijnlijk is de standaard tail implementatie bij
grotere files wel veel sneller, aangezien die in een keer naar het einde van
de file kan springen. Onze tail moet eerst de gehele file
doorspitten.
