manac ham chơi

7 September, 2006

I/O scheduler: bạn là ai?

Filed under: linux-unix — manac @ 1:29 pm

Khi bạn xem một thư mục với lệnh ls, hoặc chép một tập tin từ thư mục này qua thư mục khác, hoặc từ vùng đĩa này qua vùng đĩa khác, Linux sẽ thực hiện bằng cách đọc/viết từng block trên ổ đĩa đang chứa những thông tin này. Về mặt kỹ thuật các block này đều có số gán cho nó. Ví dụ, người dùng A cần đọc block 20, trong khi người dùng B cần viết xuống block 500 và người dùng C cần đọc block 320. Tưởng tượng có 5 người dùng cần đọc/viết tới các block theo thứ tự sau 20, 500, 27, 55 và 700. Bạn thấy trong ví dụ này sau khi đầu đĩa đang ở block 20 phải chạy lại block 500 rồi lại quay ngược lại block 27 và…cho đến khi thực hiện xong block 700. Có phải cả một quá trình như vậy quá mệt mõi không? Tại sao ta không dùng biện pháp nào, sắp xếp lại cho chúng được đọc/viết theo thứ tự block 20, rồi 27, rồi 55 và 700. Đó là lý do I/O (Input/Output) scheduling đã ra đời.

Bằng cách tận dụng thêm I/O scheduling, hệ thống Linux của bạn sẽ được sử dụng với hiệu quả cao hơn, tùy vào môi trường sử dụng (cho desktop hay cho máy chủ), cấu hình phần cứng (IDE, SCSI, RAID, ..v..v.). Mục đích chính của I/O scheduler là để sắp xếp lại các yêu cầu đọc/viết theo thứ tự để đầu đọc đĩa không phải mệt mõi chạy từ đầu này đến đầu kia, đồng thời I/O scheduler sẽ gộp lại những yêu cầu đọc/viết đĩa ở gần nhau để tránh việc lãng phí (resource) tài nguyên của hệ thống. Mội điều quan trọng nữ là khi thực hiện đọc, kernel sẽ đọc từng mảng (chunk) data. Đọc xong mãng nào nó sẽ đọc tiếp mãng tới. Trong khi viết thì kernel sẽ thực hiện đồng loạt (stream). Hiện nay Linux đang có 4 loại I/O schedulers khác nhau: NOOP, Deadline, Anticipatory và Complete Fair Queuing (CFQ). Scheduler chuẩn khi bạn biên dịch kernel sẽ là Anticipatory. Mỗi nhà phân phối sử dụng scheduler khác nhau. Gentoo, Debian, Mandriva và Ubuntu sử dụng anticipatory. FC, OpenSUSE và Ubuntu server sử dụng CFQ. Vậy thì chúng khác nhau như thế nào? Và cái nào sẽ đem lại hiệu quả cao nhất?

1. Deadline I/O scheduler

Deadline sẽ sắp xếp những yêu cầu đọc/viết đĩa theo từng queue (hàng) và mỗi hàng đều có thời gian cố định. Nếu bạn không sử dụng I/O scheduler, Linux sẽ sắp xếp tất cả các yêu cầu đọc viết trong một hàng thôi. Với deadline bạn sẽ có 3 hàng, hàng chuẩn (khi không dùng scheduler) và hai hàng đọc và viết FIFO (Cái nào vô trước sẽ ra trước: First In First Out). Mỗi lần có yêu cầu đọc/viết, chúng sẽ vào hàng chuẩn trước sau đó sẽ được phân phát ra hàng read FIFO hay write FIFO. Và mỗi hàng này đều có thời gian giới hạn. Nghĩa là với ví dụ trên, nếu hệ thống đang block 20 nhừng vì block 20 đọc tập tin khá lớn deadline scheduler sẽ tạm ngừng đọc block 20 mà nhảy tới block kế tiếp và bắt đầu việc đọc/viết ở block này. Nếu không sử dụng deadline I/O scheduler thì có lẽ hệ thống cứ phải chờ đọc block 20 cho xong rồi mới tiếp tục đọc/viết block kế tiếp. Tường tưởng một máy chủ phục vụ hàng ngàn yêu cầu searching database mà cứ phải đứng xếp hàng chờ dài cổ thì…hệ thống sẽ bị trì trệ.

2. Anticipatory I/O scheduler

Giả sử đang có một yêu cầu đọc/viết ở block 20. Đột nhiên lại có thêm một yêu cầu đọc ở block 700. Deadline sẽ đọc block 20 trong khoảng thời gian cho phép rồi, sau khi hết hạn, lại đổi qua block 700. Nhưng giả sử nếu vừa bắt đầu đang đọc ở block 700 lại có một yêu cầu mới đọc ở block 27. Với anticipatory I/O scheduler, Linux sẽ đứng lại tại block 20 khoảng 10 milliseconds vì nó sẽ trông đợi (anticipate) sẽ có một yêu cầu đọc gần block 20 này, nếu có thì quá tốt tôi không phải nhảy từ block 700 qua lại block 27 sau khi block 20 đã bắt đầu. Vậy thì sự khác nhau rõ rệt giữa Deadline và Anticipatory ở chỗ với AS, nó sẽ đứng chờ vị trí đang đọc khoảng 10 milliseconds, trước khi thực hiện tiếp. Nếu trong khoảng 10 milliseconds này lại có một yêu cầu đọc viết kế bên ví trí nó đang đứng, nó sẽ thực hiện ngay yêu cầu này –> đầu đọc đĩa không phải nhảy tới lui các khoảng cách xa nhau trên ổ đĩa.

3. Complete Fair Queuing I/O scheduler

Với CFQ, nó sẽ tạo hàng (queue) cho mỗi process, thay vì 1 read FIFO queu và 1 write FIFO queue như deadline. Rồi nó sẽ ráng cung cấp băng thông cho những process này một cách hiệu quả nhất sử dụng round-robin scheduling. Với round-robin nó không phân biệt yêu cầu nào tới trước mà sẽ cung cấp thời gian cần thiết cho mỗi yêu cầu và băng thông như nhau. Ví dụ bạn muốn nghe nhạc mp3/ogg cùng lúc thực hiện các thao tác khác trên desktop, CFQ sẽ cho hiệu quả cao nhất.

4. NOOP (No-op) I/O scheduler

NOOP hoạt động scheduling ít nhất. Nó vẫn sắp xếp (sorting) và gom lại các yêu cầu gần nhau(merging) như các I/O scheduler trên. Tại sao lại cần nó? NOOP hoạt động rất tốt trên các thiết bị không phải dựa vào ổ cứng để có được hiệu quả cao. Huh? các thiết bị như flash drive, USB stick (sử dụng memory) hoặc các ổ cứng đã có sự giúp đỡ như RAID controller.

Để xem hệ thống sử dụng đang dùng I/O scheduler nào, gõ

    cat /sys/block/hdx/queue/scheduler

với hdx là hda, hdb, hdc, sda, sdb, v.v..

Nếu bạn thấy 1 trong 4 schedulers nằm trong ngoặc [] thì đây là schedule đang sử dụng.

Bạn cũng có thể dùng lệnh

    dmesg | grep scheduler

Thế làm sao đổi scheduler đang dùng?

Quá dễ. Gõ

    echo tên_scheduler_bạn_muốn > /sys/block/hdx/queue/scheduler

Còn cách nào để đổi scheduler nữa không?

Còn chứ. Trong dòng kernel của GRUB hoặc trong tập tin lilo.conf bạn có thể thêm dòng

    elevator=x

với x = deadline hoặc cfq hoặc noop, ..v..v..

Vậy thì scheduler nào sẽ cho hiệu quả cao nhất?

Tùy vào bạn sử dụng desktop cho những thao tác gì. Với máy tính sử dụng ổ cứng IDE, bạn nên dùng anticipatory scheduler. Nên nhớ mỗi máy tính hoạt động khác nhau do đó cách tốt nhất bạn nên dùng thử các scheduler khác nhau, để xem scheduler nào bạn cảm thấy hài lòng nhất.

References:

2.6.11+ I/O Scheduler
Modular IO Schedulers
Kernel korner: I/O Schedulers
Interview Nick Piggin

(http://tapchi.vnlinux.org/index.php?q=node/24)

Leave a Comment »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a comment

Blog at WordPress.com.