Linux 101: Hangi I/O Zamanlayıcı?

İster performans optimizasyonunun ölçüsünü kaçırmak, ister entellektüel bir teknik dalaşa girişmek olarak algılayın, müşteri eğer “Hangi I/O Scheduler’ı kullanmamızı önerirsiniz?” diye sorarsa cevap vermek zorundasınız.

Evet, tamamen retorik bir soru olduğunun farkındayım bu hali ile. Zira, çevresel değişkenleri ben biliyorum ama siz henüz bilmiyorsunuz; soracaksınız: Hangi disk, hangi RAID, hangi amaç, hangi uygulama, hangi işletim sistemi, sanal/fiziksel… Uzayıp gidecek sorular. Bilmeyenler için önce “Neden çevresel değişkenler önemli?” sorusunun cevabını vermek gerek, bunun için I/O Zamanlayıcı / Scheduler 101 dersi aşağıda:

I/O Scheduler Nedir?

Linux sistemlerde, çekirdeğin blok aygıtlara (örn: disk) yazma ve aygıtlardan okuma esnasında işleme (commit) yöntemini belirleyen düzenektir. Bu düzenek, hengi okuma, yazma işlemlerinin ileten sürecin önem derecesine, aygıtın türüne, işlemin uzunluğuna vb değişkenlerle hangi sırayla diske yazılacağını veya diskten okunacağını belirleyen görevlidir.

Değişen disk yapıları, RAID sistemleri (Donanımsal, Yazılımsal vb), disk teknolojileri (SCSI, SATA, SSD) vb sebeplerle, zaman içerisinde birden fazla ve farklı I/O zamanlayıcıları geliştirilmiş, çekirdek sürümünden sürümüne farklı zamanlayıcılar varsayılan olarak atanmışlardır. Bu durum hem çekirdeğe hem de dağıtıma göre değişir bir hal almış, 2.6 sürüm çekirdeklerden itibaren komut satırından veya açılış esnasında değiştirilebilir bir hale gelmiştir. En sık kullanılan zamanlayıcılar CFQ, NOOP, Anticipatory, Deadline olmuştur.

Farklı Zamanlayıcılar

CFQ, Completely Fair Queuing, Tamamen Adil Kuyruklama olarak tanımlayabileceğimiz zamanlayıcı senkron ve asenkron istekler için farklı kuyruklar oluştururken, süreçler için de duruma göre bir takım farklı kuyruklar oluşturarak okuma/yazma işlemlerini sıralar. I/O önceliğine göre isteklere farklı zaman dilimleri atayarak kuyruğun düzenini sağlar. Her işlemin sonunda bir zaman aralığı mevcuttur. Bu aralık yeni kuyruk açma, süreçten yeni istek bekleme vb konularda optimizasyonu sağlamak amaçlı belirlenmiş olsa da performans ayarı yapılırken ilk olarak ele alınan değişken olarak yeniden yapılandırılabilir.

NOOP Zamanlayıcı, en basit zamanlayıcıdır. Çalışma yöntemi basitçe tüm gelen isteklerin bir FIFO (First In First Out – İlk Gelen İlk Çıkar) kuyruğuna atılması prensibine dayanır. Bu tür bir çalışma mekanizması, sadece ve sadece host sistemin gelen isteklerin önceliği konusunda bilgi sahibi olmadığı durumlarda veya okuma/yazma verimliliğinde disk kafasının pozisyonunun bu verimliliğe etkisinin olmadığı SSD diskler gibi diskler söz konusu olduğunda etkin olabilir. Buna karşın, SSD veya Flash diskler de söz konusu olsa yine de tam anlamıyla efektif bir zamanlayıcı değildir. Zira, düşük gecikmeli bu tür disklerde dahi, sistem bazı isteklerin aynı süreçlerde birleştirilerek işlenmesinden fayda görmektedir.

Anticipatory Zamanlayıcı, kafalı disklerin I/O performansına yönelik performans arttırıcı bir algoritma içerir. İşlemleri kuyruk içerisinde sıralarken, diskin kafa pozisyonuna, kafa sayısına (RAID), disk türüne vb değişkenlerle karar vererek, bir sonraki okuma/yazma işlemine hangi istekten başlayacağını belirleyerek çalışır. 2.6.33 sürümünden itibaren çekirdekten çıkartılmış olmasının sebebi, benzeri bir ince ayarın ve performans artışının CFQ’nun yeni sürümleri ile ulaşılabilmesinden ve hizmet ettiği donanım tipinin limitli olmasından kaynaklanmasıdır.

Deadline Zamanlayıcı, bir isteğe bir son teslim tarihi (deadline) verebilmesi ile diğerlerinden farklılaşır. Okuma ve Yazma işlemleri için iki farklı kuyruk kullanır. Bir son teslim tarihi verebilmesi sayesinde süreçlerin okuma/yazma (I/O) beklerken ne kadar bekleyeceklerini bilmemekten kaynaklı, süreci başlatan ana sürecin (örn: apache) kendi verimliliğinin düşmesinin (starvation) engellenmesi amaçlanmıştır. Eğer zamanlayıcı isteklerin yoğunluğundan kaynaklı olarak bir sürece ait işlemin son teslim tarihini geçirirse, kuyruktan bir sonraki isteği çekerek işlem yapar. Böylece kullanım tarihi dolmuş bir I/O isteğine sahip olan süreç duruma uygun exit kodunu üst sürecine ileterek çıkış yapar ve bellekte, işlemcide daha fazla yer kaplamasını önler. Okuma işlemlerine daha fazla öncelik verir, zira okuma işlemi aygıt üzerindeki alanı değişime bloklamaktadır. Okuma işlemlerinde varsayılan son teslim tarihinin kullanımının dolması için bekleme süresi 500 milisaniye iken, yazma işlemlerinde bu 5 saniyedir.

sysfs üzerinden yukarıda bahsedilen ayarlar performans optimizasyonu amacıyla yeniden düzenlenebilir: fifo_batch (int), read_expire (int), write_expire (int), writes_starved (int), front_merges (int)

Performans Optimizasyonunda I/O Scheduler’ın Rolü

Bir Linux işletim sisteminde birden fazla I/O zamanlayıcı mevcut olmakla beraber, çekirdeğin sizin adınıza en performanslı zamanlayıcıyı seçme kabiliyeti yoktur. Bu sebeple kullanım amacınıza ve ne kadar performans istediğinizi bağlı olarak gerektiğinde ilgili disk birimleri için io zamanlayıcıyı sizin seçmeniz gerekir.

Tarihçeye bakarsak, uzun bir dönem anticipatory zamanlayıcı varsayılan olmuş, CFQ geliştirildikten sonra ise, CFQ’nun varklı sürümleri arasında sadece kısa bir dönem 2.6.0 ve 2.6.18 arasında varsayılan zamanlayıcı olarak en kısa ömürlü varsayılan zamanlayıcı olmuştur. Kendi dizüstü bilgisayarınızda SSD diskler varsa basitçe NOOP, sanallaştırmada konuk sistemler için deadline veya noop, ne yapacağınızı bilmiyorsanız varsayılan CFQ zamanlayıcıyı kullanabilirsiniz.

Sistemde var olan zamanlayıcıları ve kullanılmakta olanı görmek için aşağıdaki komutu kullanabilirsiniz. Bu sistemde noop, deadline ve cfq mevcuttur, ve köşeli parantez içerisinde yer alan cfq’nun aktif zamanlayıcı olduğunu görebiliriz.

root@dev:~# cat /sys/block/sda/queue/scheduler
noop deadline [cfq]

Dikkat ederseniz zamanlayıcı diske göre değişebilmektedir. Yani çalışma zamanı parametreleri ile, sistemin kendi diski üzerinde cfq zamanlayıcı kullanırken, veritabanı dosyalarının yer aldığı disk üzerinde farklı bir zamanlayıcı örneğin noop kullanılabilmektedir. Bu sayede birden fazla disk türünün bulunduğu günümüz sistemlerinde depolama biriminin türüne veya çalışan uygulamaya göre zamanlayıcı belirlemek mümkün hale gelmiştir.

Sanallaştırma için RedHat tarafından önerilen zamanlayıcı ile Oracle kullanımı için önerilen zamanlayıcı farklı olabilir.

Son olarak, yukarıda bahsedilen neredeyse tüm zamanlayıcıların yazarı, Linux çekirdeğinde blok sisteminin yürütücüsü, çok uzun zamandan beri bir Linux çekirdek geliştiricisi olan Jens Axboe‘ye selam ve saygılarımızı sunmak isteriz.