Deadline schemaläggare

Deadline -schemaläggaren är en I/O-schemaläggare för Linux-kärnan som skrevs 2002 av Jens Axboe .

Översikt

Huvudmålet med Deadline-schemaläggaren är att garantera en starttid för en förfrågan. Det gör det genom att införa en deadline för alla I/O-operationer för att förhindra svältande av förfrågningar. Den upprätthåller också två deadline- köer , utöver de sorterade köerna (både läs och skriv). Deadline-köer är i princip sorterade efter deras deadline (förfallotiden), medan de sorterade köerna sorteras efter sektornummer.

Innan nästa förfrågan serveras bestämmer tidsplaneraren vilken kö som ska användas. Läsköer ges högre prioritet, eftersom processer vanligtvis blockerar läsoperationer. Därefter kontrollerar deadline-schemaläggaren om den första begäran i deadlinekön har löpt ut. Annars betjänar schemaläggaren en grupp förfrågningar från den sorterade kön. I båda fallen betjänar schemaläggaren också en grupp förfrågningar efter den valda begäran i den sorterade kön.

Som standard har läsbegäranden en utgångstid på 500 ms, skrivbegäranden löper ut om 5 sekunder.

En tidig version av schemaläggaren publicerades av Jens Axboe i januari 2002.

Mätningar har visat att deadline I/O-schemaläggaren överträffar CFQ I/O-schemaläggaren för vissa flertrådade arbetsbelastningar.

sysfs tunables

fifo_batch (heltal)

Deadline utför I/O-operationer (IOP) genom konceptet "batcher" som är uppsättningar av operationer ordnade i termer av ökande antal sektorer. Denna inställning avgör hur stor en batch måste vara innan förfrågningarna köas till disken (förutom utgången av en för närvarande byggd batch). Mindre partier kan minska fördröjningen genom att se till att nya förfrågningar exekveras tidigare (istället för att eventuellt vänta på att fler förfrågningar kommer in), men kan försämra den totala genomströmningen genom att öka den totala rörelsen av drivhuvuden (eftersom sekvensering sker inom en batch och inte mellan dem) . Dessutom, om antalet IOP är tillräckligt högt kommer batcherna att utföras i tid ändå.

read_expire (heltal)

"read_expire"-tiden är den maximala tiden i millisekunder efter vilken läsningen anses vara "expired". Tänk på det här mer som utgångsdatumet på en mjölkkartong. Mjölken används bäst före utgångsdatum. Samma sak med deadline-schemaläggaren. Det kommer INTE att försöka se till att alla IO är utfärdade före dess utgångsdatum. Men om IO har passerat utgångsdatum, får den en bump i prioritet…. med varningar.

Lästidens utgångskön kontrolleras ENDAST när deadlineschemaläggaren omvärderar läskön. För läsningar betyder detta varje gång en sorterad läsning skickas UTOM för fallet med streaming io. Medan schemaläggaren streamar io från läskön utvärderas inte läsningen som har gått ut. Vid omvärdering av läskön är logiken

kontrollera för utgångna läsningar (titta på huvudet av FIFO [tidsordnad]-kön) kontrollera om den cachade läspekaren är giltig (så även om den inte streamas har den cachade pekaren fortfarande företräde så den sorterade kön passeras tipp till tail i ett svep) plocka upp den första läsningen från den sorterade kön (börja vid spetsen igen för ett nytt svep) Om det finns utgångna läsningar, så dras den första från FIFO. Observera att denna utgångna läsning då är den nya kopplingen för lässortering. Den cachade nästa pekaren kommer att ställas in på att peka på nästa io från sorteringskön efter att denna har gått ut... Saken att notera är att algoritmen inte bara exekverar ALLA utgångna io när de har passerat sitt utgångsdatum. Detta gör att en rimlig prestanda kan upprätthållas genom att gruppera "write_starved"-sorterade läsningar tillsammans innan du kontrollerar den utgångna läskön igen.

Så det maximala antalet io som kan utföras mellan läs utgången io är 2 * 'fifo_batch' * 'writes_starved'. En uppsättning av 'fifo_batch'-strömning läser efter den första utgångna läsningen io och om denna ström råkade orsaka skrivsvälttillståndet, kan en annan 'fifo_batch'-strömning skriva. Detta är värre fall, varefter den lästa kön skulle omvärderas. I bästa fall kommer den förfallna läskön att utvärderas 'write_starved' gånger i rad innan den hoppas över eftersom skrivkön skulle användas.

write_expire (heltal)

Identiskt med read_expire men för skrivoperationer (grupperade i separata batcher från läsningar).

skriver_svält (heltal)

Som tidigare nämnts föredrar deadline läsning framför skrivning. Som en konsekvens kan detta leda till situationer där operationerna utförs nästan helt läses. Detta blir mer av en viktig tunable eftersom write_expire förlängs eller den totala bandbredden närmar sig mättnad. Att minska detta ger mer bandbredd till skrivningar (relativt sett) på bekostnad av läsoperationer. Om applikationsarbetsbelastningen däremot är lästung (till exempel de flesta HTTP- eller katalogservrar) med endast enstaka skrivningar, kan minskad latens för genomsnittliga IOP:er uppnås genom att öka denna (så att fler läsningar måste utföras innan en skrivbatch köas till disk).

front_merges (bool heltal)

En "front merge" är en operation där I/O Scheduler, som försöker kondensera (eller "sammanfoga") mindre förfrågningar till färre (större) operationer, kommer att ta en ny operation och sedan undersöka den aktiva batchen och försöka lokalisera operationer där början sektor är densamma eller omedelbart efter en annan operations början sektor. En "back merge" är motsatsen, där slutsektorer i den aktiva batchen söks efter sektorer som antingen är samma eller omedelbart efter den aktuella operationens börjansektorer. Sammanslagning avleder operationer från den aktuella batchen till den aktiva, vilket minskar "rättvisheten" för att öka genomströmningen.

På grund av hur filer vanligtvis är upplagda är backsammanslagningar mycket vanligare än frontsammanslagningar. För vissa arbetsbelastningar kanske du till och med vet att det är slöseri med tid att lägga ner tid på att försöka fronta sammanslagningsförfrågningar. Att sätta front_merges till 0 inaktiverar denna funktionalitet. Front sammanslagningar kan fortfarande förekomma på grund av den cachade last_merge-tipset, men eftersom det kostar i princip noll, utförs det fortfarande. Denna boolean inaktiverar helt enkelt frontsektorsökning när I/O-schemaläggarens sammanslagningsfunktion anropas. Disksammanslagningssummor registreras per blockenhet i /proc/diskstats.

Andra I/O-schemaläggare