最後更新: 2019-10-23



 * Non-multiqueue have been deprecated (no longer supported in the Linux 5.3 kernel)


查看 Kernel 支援什麼 scheduler


cat  /sys/block/sda/queue/scheduler

noop [anticipatory] deadline cfq

kernel 一共支援 4 種 scheduler, 而現在在用  anticipatory


設定 scheduler


echo deadline > /sys/block/sda/queue/scheduler


Linux 2.6.32 default cfq




  • noop
  • deadline
  • mq-deadline
  • cfq
  • as


noop scheduler:

just service next request in the queue without any algorithm to prefer this or that request.

使用情況: CPU-bound and the storage is fast

deadline scheduler: (database systems)

* guarantees a start service time for each I/O request

   (requests are given a deadline by which they get served)

* Prioritizes read requests higher than write requests

   (since applications are more likely to block on read I/O)

* Deadline dispatches I/Os in batches

   (read or write I/Os which are in increasing LBA order(one-way elevator))

Latency measurement

starts when the requests gets down to the I/O scheduler

Expiration request time:

- read queues: 500 ms

- write queues: 5 sec


If the first request in the deadline queue expired

1 The Deadline I/O scheduler services the first request in the deadline queue immediately.

    (or sorts deadline queues by the expiration times)

2 services a batch of requests near the disk location of the request

    (sorts the other queues by the positions)


fifo_batch (Default: 16)

the number of reads or writes to issue in a single batch.

read_expire (Default: 500 ms)

to set the number of milliseconds in which a read request should be serviced

write_expire (Default: 5000 ms)

the number of milliseconds in which a write request should be serviced


controls how many read batches can be processed before processing a single write batch.

front_merges (Default: 1)

0 if you know your workload will never generate front merges

1 Unless you have measured the overhead of this check, it is advisable to leave it at its

Sometimes it happens that a request enters the io scheduler that is contiguous

with a request that is already on the queue. Either it fits in the back of that request, or it fits at the front.

That is called either a back merge candidate or a front merge candidate.

Due to the way files are typically laid out, back merges are much more common than front merges.


mq-deadline ( Debian 10.1 Default )


cfq (Complete Fair Queueing Scheduler):(multiuser system)

different sort of stab at fairness


as (Anticipatory IO Scheduler): (Apache web server)

  • anticipatory reads
    (pausing for a short time (a few milliseconds) after a read operation in anticipation(預期) of another close-by read requests)
  • avoiding harddisk head movements if possible


Kyber will throttle requests in order to meet these target latencies

 -> intended for fast multiqueue devices

throughput-sensitive server loads are more likely to run with Kyber (merging of requests)

I/O requests passing through Kyber are split into two primary queues

* Synchronous requests (e.g. blocked reads)

* Asynchronous requests (e.g. writes)

The scheduler tunes the actual number of requests allowed into the dispatch queues

by measuring the completion time of each request and adjusting the limits to achieve the desired latencies.


read_lat_nsec              # Target latency for reads (in nanoseconds)

write_lat_nsec             # Target latency for synchronous writes (in nanoseconds)

Default to 2ms for read requests and 10ms for writes


To use mq-deadline


# Ubuntu 16.04.6 LTS

modinfo mq-deadline

modprobe mq-deadline

cat /sys/block/sda/queue/scheduler

noop deadline [cfq]

# To enable it

echo "mq-deadline" > /sys/block/sda/queue/scheduler


Script set scheduler

for DISK in sda sdb sdc sdd
    # Select deadline scheduler first
    echo deadline > /sys/block/${DISK}/queue/scheduler
    # Now set deadline scheduler parameters
    echo 100 > /sys/block/${DISK}/queue/iosched/read_expire
    echo 4 > /sys/block/${DISK}/queue/iosched/writes_starved