- Yüksek performanslı web sunucuları oluşturmak için geçmişte select(), poll(), epoll gibi çeşitli olay tabanlı modeller kullanıldı
- Ancak bu sistem çağrılarının performans sınırları nedeniyle io_uring ortaya çıktı ve isteklerin kuyruğa eklenip çekirdek tarafından asenkron işlenmesi yaklaşımını getirdi
- kTLS ile TLS şifreleme işlemlerini çekirdek üstleniyor; bu da sendfile() kullanımı ve donanım offload gibi ek optimizasyonları mümkün kılıyor
- Descriptorless files yaklaşımı, dosya tanıtıcılarını doğrudan iletmeden io_uring için optimize edilmiş bir erişim yöntemi sağlıyor
- Rust, io_uring ve kTLS'yi birleştiren tarweb açık kaynak projesi, istek başına ek sistem çağrısı olmadan HTTPS sunmayı hedefliyor; ayrıca güvenlik ve bellek yönetimi konuları da ele alınıyor
Yüksek performanslı web sunucusu mimarisinin evrimi
- 2000'lerin başından itibaren yüksek kapasiteli web sunucularına olan ihtiyaç arttı
- İlk dönemde her istek için yeni bir süreç oluşturma yaklaşımı yaygındı; ancak bunun yüksek maliyeti nedeniyle preforking tekniği ortaya çıktı
- Sonrasında thread kullanımının ve select(), poll() mekanizmalarının devreye girmesiyle, bağlam değiştirme maliyetini azaltan bir yapıya doğru evrildi
- Ancak select() ve poll() yöntemleri de bağlantı sayısı arttıkça çekirdeğe büyük dizilerin sık sık iletilmesini gerektirdiği için ölçeklenebilirlik sınırlarına sahipti
epoll'un ortaya çıkışı
- Linux ortamında epoll kullanıma girdi ve önceki yöntemlere göre çoklu bağlantıları daha verimli işlemek mümkün hale geldi
- epoll yalnızca değişiklikleri (delta) işleyerek gereksiz kaynak tüketimini azaltır
- Tüm sistem çağrıları tamamen ortadan kalkmasa da, maliyet önemli ölçüde düşer
io_uring'e genel bakış
- io_uring, her istek için sistem çağrısı yapmak yerine, çekirdeğin asenkron işleyebilmesi için isteklerin bellekteki bir kuyruğa eklenmesini sağlar
- Örneğin accept() kuyruğa konulduğunda, çekirdek işlemi tamamladıktan sonra sonucu tamamlanma kuyruğuna döndürür
- Web sunucusu isteği kuyruğa ekler, sonuçları ise ayrı bir bellek alanından kontrol eder
- Yoğun döngüden (busy loop) kaçınmak için, kuyrukta değişiklik yoksa hem web sunucusu hem de çekirdek yalnızca gerektiğinde sistem çağrısı yaparak enerji tasarrufu sağlar
- Uygun kütüphaneler kullanıldığında, aktif bir sunucu istekleri işlerken ek sistem çağrısı olmadan çalışabilir
Çok çekirdekli ve NUMA ortamları
- Modern CPU'ların çok çekirdekli yapısı göz önüne alındığında, çekirdek başına tek thread çalıştırmak ve veri yapılarının paylaşımını en aza indirmek etkili bir stratejidir
- NUMA ortamında her thread'in yalnızca kendi yerel düğüm belleğine erişmesi optimizasyon sağlar
- İstek dağıtımında kusursuz denge ise ek araştırma gerektirir
Bellek tahsisi
- Hem çekirdekte hem de web sunucusunda bellek tahsisi devam eder; kullanıcı alanındaki tahsisler de sonunda sistem çağrılarına bağlanır
- Web sunucusu tarafında bağlantı başına sabit boyutlu bellek blokları önceden ayırarak parçalanma ve yetersizlik sorunları önlenebilir
- Çekirdek tarafında da bağlantı başına G/Ç tamponları gerekir ve bunlar soket seçenekleriyle kısmen ayarlanabilir
- Bellek yetersizliği oluştuğunda ciddi arızalara yol açabilir
kTLS (çekirdek TLS) tanıtımı
- kTLS, Linux çekirdeğinde şifreleme ve şifre çözme işlemlerini üstlenen bir özelliktir
- Handshake uygulama tarafından yapılır; sonrasında çekirdek veriyi düz metinmiş gibi aktarır
sendfile() kullanılabildiği için kullanıcı alanı ile çekirdek alanı arasındaki bellek kopyaları azaltılabilir
- Ağ kartı destekliyorsa, şifreleme işlemleri donanıma da offload edilebilir
Descriptorless Files
- Kullanıcı alanından çekirdek alanına dosya tanıtıcısı doğrudan aktarılırken oluşan ek yükü azaltmak için ortaya çıkan bir yaklaşımdır
register_files kullanılarak yalnızca io_uring içinde geçerli olan ayrı bir “tamsayı” dosya numarası kullanılır ve bu değer /proc/pid/fd altında görünmez
- Sistemin
ulimit sınırı yine de geçerlidir
tarweb projesine giriş
- tarweb, yukarıdaki tüm teknolojileri uygulayan örnek bir açık kaynak web sunucusu projesidir
- Tek bir tar dosyasının içeriğini sunan bir yapıya sahiptir ve Rust, io_uring, kTLS gibi modern yüksek performans teknolojilerini bir araya getirir
- Gerçek kullanım sırasında io_uring ile kTLS arasında uyumluluk sorunları (ör.
setsockopt desteğinin olmaması) yaşanmış ve bazı problemler Pull Request ile çözülmüştür
- Proje hâlâ tamamlanmış değildir; ayrıca Rust'ın rustls kütüphanesi handshake sürecinde bellek tahsisi yapabilir
- Temel nokta, her istek için ek sistem çağrısı olmadan HTTPS hizmeti sunmanın mümkün olmasıdır
Benchmark ve performans ölçümü
- Yazar henüz yeterli benchmark yapmadı; kod düzenlendikten sonra performans testleri planlanıyor
io_uring ve Rust'ta güvenlik sorunları
- Eşzamanlı sistem çağrılarından farklı olarak, io_uring'de tamamlanma olayı gelene kadar bellek tamponları serbest bırakılmamalıdır
- io-uring crate'i, Rust'ın derleme zamanındaki güvenliğini garanti etmez ve çalışma zamanındaki kontroller de yetersizdir
- Yanlış kullanım, C++'takine benzer şekilde ciddi sorunlara yol açabilir; bu da Rust'ın doğal güvenliğini zayıflatır
- Pinning ve borrow checker'ı aktif kullanan ayrı bir safer-ring crate'ine ihtiyaç vardır
- Bu konu topluluk içinde zaten tartışılmaktadır
Referanslar ve ek bağlantılar
- Bu içerik, 2025-08-22 itibarıyla HackerNews'te tartışılan bir gönderiye dayanmaktadır
Henüz yorum yok.