Vielleicht interessiert euch das ja auch.
Jeder der unter Linux einen Rechner aufsetzen und dabei die
Disk-Performance optimieren will, könnte daran potenziell Bedarf haben.
Es geht um die verschiedenen I/O-Scheduler die man unter Kernel 2.6 wählen kann, und für welche Szenarien meiner Ansicht nach welcher Scheduler am besten geeignet ist.
Vorab möchte ich aber klarstellen, dass dieses Posting meine persönlichen, subjektiven Schlussfolgerungen beinhaltet wie ich die Sachverhalte zur Zeit nach bestem Wissen verstehe; ohne jeden Anspruch auf Vollständigkeit oder absolute Korrektheit. Ich freue mich auf ergänzende Kommentare von anderen Usern, die meine Annahmen bestätigen oder korrigieren können.
-------- Original-Nachricht --------
Betreff: Ein sehr empfehlenswerter Artikel über die I/O Scheduler von Linux
Datum: Wed, 21 Nov 2007 13:21:24 +0100
Von: Guenther Brunthaler
[...]
Bislang war mir immer sehr unklar, welchen I/O-Scheduler man für welche
Art von Arbeit verwenden sollte.
Der Artikel
http://kerneltrap.org/node/7637
brachte nun einiges Licht in diese Thematik - ich kann ihn nur empfehlen.
Vorab meine Interpretation des Textes, welcher I/O Scheduler für was gut
ist:
- "noop" - wie der Name schon sagt, scheduled der gar nichts. Simples
FIFO-Queuing für alle I/O Requests egal woher sie stammen. Ist gedacht
für wirklich intelligente Hardware, die ihr eigenes internes Scheduling
macht, und wo jedes Scheduling durchs OS kontraproduktiv wäre. (Etwa
SANs, könnte ich mir vorstellen.) Update: Angeblich ist dies auch der beste Scheduler für Flash-Medien. - "deadline": I/O-Requests werden nach der Blocknummer sortiert in eine
Warteschlange eingeordnet unabhängig woher sie stammen. Diese Queue wird
dann zyklisch von vorn nach hinten abgearbeitet. Damit I/O-Requests
nicht unmäßig warten müssen falls die Schlange zu lange wird, werden die
I/O-Requests überdies in separate FIFOs für Read und Write-Requests
eingeordnet, nach Alter sortiert. Jedem Request wird dabei eine
Maximaldauer zur Erledigung zugewiesen. Solange diese Maximaldauern
nicht überschritten werden werden die I/Os wie zuvor beschrieben in der
Sortierreihenfolge der Blocknummern durchgeführt. Sobald die
Maximaldauern aber überschritten werden, werden nur mehr abwechselnd die
ältesten Read- und Write-Requests aus den FIFOs bedient, bis sich die
Situation wieder gebessert hat - dann wird wieder das zyklische
Schedulen in Blockreihenfolge angeworfen. - "anticipatory": Tut dasselbe wie "deadline", wartet aber nach jedem
I/O-Vorgang (ich hoffe nur bei Schreibvorgängen aus den Deadline-FIFOs)
einige Millisekunden ob vielleicht ein Nachfolge-Request daher kommt.
Dadurch werden zahlreiche sequenzielle I/Os besser unterstützt, welche
an verschiedenen Stellen der Disk gleichzeitig erfolgen. Sprich, wenn
verschiedene Prozesse zur selben Zeit verschiedene Dateien bearbeiten.
Der "deadline" geht dabei nämlich ziemlich ein und "seekt" sich blöd. - "cfq": Der "Completely Fair Queueing" Scheduler arbeitet völlig
anders. Er scheduled Zeitscheiben, in denen nur die I/O eines bestimmten
Prozesses auf die Disk erfolgt. Die Größe der Zeitscheiben ist von
Statistiken und der Prozesspriorität abhängig, und ausserdem wird
innerhalb eines Prozesses noch zwischen synchronen und asynchronen
Requests unterschieden. Aber zwischen den Prozessen gibt es ein Round
Robin, daher kommt jeder Prozess nach einer relativ kurzen Zeit wieder
dran, und keiner "verhungert" auch wenn sehr viel I/O durchzuführen ist.
schnellsten. Daher ist es für den typischen Desktop-Betrieb
normalerweise der am besten geeignete I/O Scheduler. In vielen
Linux-Distris wird er daher auch als Default-Scheduler eingesetzt.
Allerdings scheduled der cfq die Requests nicht optimal aus der Sicht
der Arbeit welche die Disk zu erledigen hat. Hier ist der anticipatory
normalerweise am effizientesten - insbesondere wenn Batch-Jobs laufen
die ihrerseits jede Menge sequenzielle Dateien (gleichzeitig)
bearbeiten. Auch zum Ansehen von Videos etc. ist er wohl der geeignetste.
Der deadline wiederum glänzt bei völligen Random-Zugriffen, wie sie vor
allem bei Datenbanken oft vorkommen. Hier sorgt er dafür, dass die Seeks
minimiert werden welche für das Durchführen der Random-Zugriffe
erforderlich sind. Zwar ist der anticipatory dem deadline sehr ähnlich,
aber durch die kleinen Wartepausen die er einlegt um "Sequenzialität zu
erkennen" (die bei Datenbankzugriffen nicht vorkommt), vergeudet das
anticipatory Zeit welche der deadline nicht vergeudet.
Wenn Datenbankzugriffe aber nicht andauernd erfolgen, kann der
anticipatory doch wieder besser sein: Bei Datenbankzugriffen zwar etwas
langsamer, kann er aber zwischendurch bei sequenziellen Zugriffen wieder
Zeit und Seeks sparen.
Wenn neben den Datenbanken und Batch-Jobs aber auch noch "normal"
gearbeitet werden soll, empfiehlt sich wieder der cfq: Durch seine
Zeitscheiben werden auch sequenzielle Jobs - zumindest innerhalb der
Zeitscheibe - halbwegs effizient abgearbeitet, durch seine verschieden
langen Zeitscheiben kann er aber auch Datenbanken ausreichend effizient
bedienen obwohl nicht ganz so gut wie der deadline. Vor allem aber
verhungern während dessen keine interaktiven Benutzerprozesse.
Ich werde aus diesen Erkenntnissen die Konsequenz ziehen, den cfq als
Default-Scheduler einzustellen.
Wenn ich aber fette Batch-Jobs laufen lasse, wie große emerge-Orgien wo
der Compiler ständig sequeziell Source-Dateien liest und Object-Files
erzeugt, werde ich temporär auf den anticipatory umschalten. Dasselbe
gilt beim Movie-Ansehen, oder wenn sehr große Dateien möglichst schnell
durch die Gegend kopiert werden sollen und mir Interaktivität
währenddessen nicht so wichtig ist.
Wenn ich hingegen einen Rechner als dezidierten Datenbankserver unter
hoher Last einsetze, ist hingegen der "deadline" die beste Wahl. (cfq
dürfte auch OK sein wenn die Last nicht ganz so hoch ist.)
Tja, soweit meine Erkenntnisse.
Hier noch wie man die Scheduler umschaltet (geht im laufenden Betrieb):
Script "set_iosched":
Code: Select all
#! /bin/sh
SCHEDULER=${1:-cfq}
lsmod | grep "$SCHEDULER[_-]iosched" > /dev/null 2>& 1 || {
modprobe "$SCHEDULER-iosched"
}
for D in /sys/block/*; do
S="$D/queue/scheduler"
test -e "$S" || continue
echo "Assigning $SCHEDULER to $S."
echo "$SCHEDULER" > "$S"
done
Code: Select all
set_iosched cfq
set_iosched # setzt ebenfalls cfq
set_iosched noop
set_iosched anticipatory
set_iosched deadline
Kernel oder als Modul kompiliert wurden.
Das Script setzt hier denselben Scheduler für alle Blockgeräte; wenn man
will kann man aber für jedes Gerät einen anderen Scheduler wählen. So
etwa setzt man für alle Geräte den cfq, fürs cdrom aber den
cd-rom-freundlicheren anticipatory:
Code: Select all
# set_iosched cfq
# echo anticipatory > /sys/block/hdc/queue/scheduler
in diesem Sinne,
Günther





