Linux ağ uygulaması performansı. giriiş

Web uygulamaları artık her yerde kullanılıyor ve tüm aktarım protokolleri arasında aslan payını HTTP alıyor. Web uygulaması geliştirmenin inceliklerini incelerken çoğu kişi bu uygulamaların gerçekte çalıştığı işletim sistemine çok az dikkat eder. Geliştirme (Dev) ve operasyonların (Ops) ayrılması durumu yalnızca daha da kötüleştirdi. Ancak DevOps kültürünün yükselişiyle birlikte geliştiriciler, uygulamalarını bulutta çalıştırmaktan sorumlu hale geliyor; bu nedenle, işletim sisteminin arka ucuna tamamen aşina olmaları onlar için çok faydalı. Bu, özellikle binlerce veya onbinlerce eşzamanlı bağlantı için bir sistem dağıtmaya çalışıyorsanız kullanışlıdır.

Web servislerindeki sınırlamalar diğer uygulamalardaki sınırlamalara çok benzer. İster yük dengeleyiciler ister veritabanı sunucuları olsun, bu uygulamaların tümü yüksek performanslı bir ortamda benzer sorunlara sahiptir. Bu temel sınırlamaları ve bunların genel olarak nasıl aşılacağını anlamak, web uygulamalarınızın performansını ve ölçeklenebilirliğini değerlendirmenize yardımcı olacaktır.

Bu makale dizisini, bilgili sistem mimarları olmak isteyen genç geliştiricilerin sorularına yanıt olarak yazıyorum. Linux uygulama optimizasyon tekniklerini, işletim sistemi düzeyinde nasıl çalıştıklarının temellerine dalmadan net bir şekilde anlamak imkansızdır. Pek çok uygulama türü olmasına rağmen bu seride tarayıcı veya metin düzenleyici gibi masaüstü uygulamalardan ziyade web tabanlı uygulamaları keşfetmek istiyorum. Bu materyal, Linux veya Unix programlarının nasıl çalıştığını ve bunların yüksek performans için nasıl yapılandırılacağını anlamak isteyen geliştiriciler ve mimarlar için tasarlanmıştır.

Linux sunucu odası işletim sistemidir ve çoğu zaman uygulamalarınız bu işletim sistemi üzerinde çalışır. Her ne kadar "Linux" desem de, çoğu zaman genel olarak Unix benzeri tüm işletim sistemlerini kastettiğimi rahatlıkla varsayabilirsiniz. Ancak, beraberindeki kodu diğer sistemlerde test etmedim. Yani FreeBSD veya OpenBSD ile ilgileniyorsanız sonuçlarınız farklılık gösterebilir. Linux'a özgü bir şey denediğimde bunu belirtiyorum.

Bu bilgiyi sıfırdan bir uygulama oluşturmak için kullanabilirsiniz ve uygulama mükemmel şekilde optimize edilecektir, ancak bunu yapmamak en iyisidir. Kuruluşunuzun iş başvurusu için C veya C++ dilinde yeni bir web sunucusu yazarsanız, bu, işteki son gününüz olabilir. Ancak bu uygulamaların yapısını bilmek mevcut programların seçiminde yardımcı olacaktır. Süreç tabanlı sistemleri, olay tabanlı sistemlerin yanı sıra iş parçacığı tabanlı sistemlerle karşılaştırabileceksiniz. Nginx'in neden Apache httpd'den daha iyi performans gösterdiğini, Tornado tabanlı bir Python uygulamasının Django tabanlı bir Python uygulamasına kıyasla neden daha fazla kullanıcıya hizmet verebileceğini anlayacak ve takdir edeceksiniz.

ZeroHTTPd: Öğrenme Aracı

SıfırHTTPd öğretme aracı olarak C dilinde sıfırdan yazdığım bir web sunucusudur. Redis'e erişim de dahil olmak üzere hiçbir dış bağımlılığı yoktur. Kendi Redis prosedürlerimizi yürütüyoruz. Daha fazla ayrıntı için aşağıya bakın.

Teoriyi uzun uzun tartışabilecek olsak da, kod yazmak, çalıştırmak ve tüm sunucu mimarilerini birbiriyle karşılaştırmak kadar güzel bir şey olamaz. Bu en belirgin yöntemdir. Bu nedenle, her modeli kullanarak basit bir ZeroHTTPd web sunucusu yazacağız: süreç tabanlı, iş parçacığı tabanlı ve olay tabanlı. Bu sunucuların her birine göz atalım ve birbirlerine kıyasla nasıl performans gösterdiklerini görelim. ZeroHTTPd tek bir C dosyasında uygulanır. Olay tabanlı sunucu şunları içerir: utaş, tek bir başlık dosyasında gelen harika bir karma tablo uygulaması. Diğer durumlarda projeyi karmaşıklaştırmamak için herhangi bir bağımlılık yoktur.

Kodda anlamanıza yardımcı olacak birçok yorum var. Birkaç satır koddan oluşan basit bir web sunucusu olan ZeroHTTPd, aynı zamanda web geliştirme için minimal bir çerçevedir. Sınırlı işlevselliğe sahiptir ancak statik dosyalar ve çok basit "dinamik" sayfalar sunma kapasitesine sahiptir. ZeroHTTPd'nin yüksek performanslı Linux uygulamalarının nasıl oluşturulacağını öğrenmek için iyi olduğunu söylemeliyim. Genel olarak çoğu web hizmeti istekleri bekler, kontrol eder ve işler. ZeroHTTPd'nin yapacağı da tam olarak budur. Bu bir üretim aracı değil, öğrenme aracıdır. Hata işleme konusunda pek iyi değil ve en iyi güvenlik uygulamalarıyla övünmesi pek mümkün değil (ah evet, kullandım strcpy) veya C dilinin zekice hileleri.Ama umarım işini iyi yapar.

Linux ağ uygulaması performansı. giriiş
ZeroHTTPd ana sayfası. Resimler de dahil olmak üzere farklı dosya türlerinin çıktısını alabilir

Ziyaretçi Defteri Uygulaması

Modern web uygulamaları genellikle statik dosyalarla sınırlı değildir. Çeşitli veritabanları, önbellekler vb. ile karmaşık etkileşimleri vardır. Bu nedenle, ziyaretçilerin kendi adlarıyla girişler bıraktıkları "Ziyaretçi Defteri" adı verilen basit bir web uygulaması oluşturacağız. Ziyaretçi defteri daha önce bırakılan girişleri saklar. Ayrıca sayfanın alt kısmında ziyaretçi sayacı bulunmaktadır.

Linux ağ uygulaması performansı. giriiş
Web uygulaması "Ziyaretçi Defteri" ZeroHTTPd

Ziyaretçi sayacı ve ziyaretçi defteri girişleri Redis'te saklanır. Redis ile iletişim için kendi prosedürleri uygulanır; bunlar harici kütüphaneye bağlı değildir. Kamuya açık ve iyi test edilmiş çözümler varken homebrew kodunu yayınlamanın büyük bir hayranı değilim. Ancak ZeroHTTPd'nin amacı Linux performansını ve harici hizmetlere erişimi incelemektir; HTTP isteklerinin sunulması ise ciddi bir performans etkisine sahiptir. Sunucu mimarilerimizin her birinde Redis ile olan iletişimi tam olarak kontrol etmemiz gerekiyor. Bazı mimarilerde çağrıları engellemeyi, bazılarında ise olaya dayalı prosedürleri kullanıyoruz. Harici bir Redis istemci kitaplığının kullanılması bu kontrolü sağlamaz. Ek olarak, küçük Redis istemcimiz yalnızca birkaç işlevi gerçekleştirir (bir anahtarı alma, ayarlama ve artırma; bir diziyi alma ve ekleme). Ayrıca Redis protokolü son derece zarif ve basittir. Özel olarak öğretmenize bile gerek yok. Protokolün tüm işi yaklaşık yüz satırlık kodla yapması, onun ne kadar iyi düşünülmüş olduğunu gösteriyor.

Aşağıdaki şekil istemci (tarayıcı) istekte bulunduğunda uygulamanın ne yaptığını göstermektedir /guestbookURL.

Linux ağ uygulaması performansı. giriiş
Ziyaretçi defteri uygulaması nasıl çalışır?

Bir ziyaretçi defteri sayfasının düzenlenmesi gerektiğinde, şablonu belleğe okumak için dosya sistemine bir çağrı ve Redis'e üç ağ çağrısı yapılır. Şablon dosyası, yukarıdaki ekran görüntüsündeki sayfaya ilişkin HTML içeriğinin çoğunu içerir. İçeriğin dinamik kısmı için de özel yer tutucular vardır: gönderiler ve ziyaretçi sayacı. Bunları Redis'ten alıyoruz, sayfaya ekliyoruz ve müşteriye tam olarak oluşturulmuş içerik sağlıyoruz. Redis'e üçüncü çağrı yapılmasından kaçınılabilir çünkü Redis artırıldığında yeni anahtar değerini döndürür. Ancak asenkron olay tabanlı bir mimariye sahip olan sunucumuz için çok sayıda ağ çağrısı, öğrenme amaçlı iyi bir testtir. Yani ziyaretçi sayısının Redis dönüş değerini atıp ayrı bir çağrı ile sorguluyoruz.

Sunucu mimarileri ZeroHTTPd

ZeroHTTPd'nin aynı işlevselliğe ancak farklı mimarilere sahip yedi sürümünü oluşturuyoruz:

  • Yinelemeli
  • Çatal sunucusu (istek başına bir alt süreç)
  • Ön çatallanma sunucusu (işlemlerin ön çatallanması)
  • Yürütme iş parçacıklarına sahip sunucu (istek başına bir iş parçacığı)
  • İş parçacığı öncesi oluşturma özelliğine sahip sunucu
  • Mimari tabanlı poll()
  • Mimari tabanlı epoll

Sunucuyu HTTP istekleriyle yükleyerek her mimarinin performansını ölçüyoruz. Ancak oldukça paralel mimarileri karşılaştırırken sorgu sayısı artıyor. Üç kez test yapıyoruz ve ortalamayı hesaplıyoruz.

Test metodolojisi

Linux ağ uygulaması performansı. giriiş
ZeroHTTPd yük testi kurulumu

Testleri çalıştırırken tüm bileşenlerin aynı makinede çalışmaması önemlidir. Bu durumda, bileşenler CPU için rekabet ettiğinden işletim sistemi ek zamanlama yüküne neden olur. Seçilen sunucu mimarilerinin her birinin işletim sistemi yükünü ölçmek bu çalışmanın en önemli hedeflerinden biridir. Daha fazla değişken eklemek sürece zarar verecektir. Bu nedenle yukarıdaki resimdeki ayar en iyi sonucu verir.

Bu sunucuların her biri ne yapar?

  • load.unixism.net: Çalıştırdığımız yer burası ab, Apache Benchmark yardımcı programı. Sunucu mimarilerimizi test etmek için gereken yükü üretir.
  • nginx.unixism.net: Bazen bir sunucu programının birden fazla örneğini çalıştırmak isteriz. Bunu yapmak için uygun ayarlara sahip Nginx sunucusu, gelen yük dengeleyici olarak çalışır. ab sunucu süreçlerimize.
  • Zerohttpd.unixism.net: Burada sunucu programlarımızı yedi farklı mimari üzerinde teker teker çalıştırıyoruz.
  • redis.unixism.net: Bu sunucu, ziyaretçi defteri girişlerinin ve ziyaretçi sayaçlarının saklandığı Redis arka plan programını çalıştırır.

Tüm sunucular aynı işlemci çekirdeği üzerinde çalışır. Buradaki fikir, her mimarinin maksimum performansını değerlendirmektir. Tüm sunucu programları aynı donanım üzerinde test edildiğinden bu, karşılaştırma için bir temel oluşturur. Test kurulumum Digital Ocean'dan kiralanan sanal sunuculardan oluşuyor.

Neyi ölçüyoruz?

Farklı göstergeleri ölçebilirsiniz. Sunucuları farklı paralellik düzeylerinde isteklerle yükleyerek her mimarinin performansını belirli bir yapılandırmada değerlendiriyoruz: yük 20'den 15 eşzamanlı kullanıcıya çıkıyor.

Test sonuçları

Aşağıdaki grafik, farklı mimarilerdeki sunucuların farklı paralellik düzeylerinde performansını göstermektedir. Y ekseni saniyedeki istek sayısıdır, x ekseni ise paralel bağlantılardır.

Linux ağ uygulaması performansı. giriiş

Linux ağ uygulaması performansı. giriiş

Linux ağ uygulaması performansı. giriiş

Aşağıda sonuçları içeren bir tablo bulunmaktadır.

saniye başına istek

paralellik
yinelemeli
çatal
ön çatal
yayın Akışı
ön yayın
anket
epol

20
7
112
2100
1800
2250
1900
2050

50
7
190
2200
1700
2200
2000
2000

100
7
245
2200
1700
2200
2150
2100

200
7
330
2300
1750
2300
2200
2100

300
-
380
2200
1800
2400
2250
2150

400
-
410
2200
1750
2600
2000
2000

500
-
440
2300
1850
2700
1900
2212

600
-
460
2400
1800
2500
1700
2519

700
-
460
2400
1600
2490
1550
2607

800
-
460
2400
1600
2540
1400
2553

900
-
460
2300
1600
2472
1200
2567

1000
-
475
2300
1700
2485
1150
2439

1500
-
490
2400
1550
2620
900
2479

2000
-
350
2400
1400
2396
550
2200

2500
-
280
2100
1300
2453
490
2262

3000
-
280
1900
1250
2502
büyük yayılma
2138

5000
-
büyük yayılma
1600
1100
2519
-
2235

8000
-
-
1200
büyük yayılma
2451
-
2100

10 000
-
-
büyük yayılma
-
2200
-
2200

11 000
-
-
-
-
2200
-
2122

12 000
-
-
-
-
970
-
1958

13 000
-
-
-
-
730
-
1897

14 000
-
-
-
-
590
-
1466

15 000
-
-
-
-
532
-
1281

Grafik ve tablodan 8000'in üzerinde eşzamanlı isteğin üzerinde yalnızca iki oyuncumuzun kaldığı görülebilir: ön çatal ve epoll. Yük arttıkça anket tabanlı bir sunucu, akışlı bir sunucudan daha kötü performans gösterir. İş parçacığı ön oluşturma mimarisi, e-anket yapmaya değer bir rakiptir; bu, Linux çekirdeğinin çok sayıda iş parçacığını ne kadar iyi planladığının bir kanıtıdır.

ZeroHTTPd Kaynak Kodu

ZeroHTTPd Kaynak Kodu burada. Her mimari için ayrı bir dizin bulunmaktadır.

ZeroHTTPd │ ├── 01_iterative │ ├── main.c ├── 02_forking │ ├── main.c ├── 03_preforking │ ├── main.c ├── 04 _ iş parçacığı │ ├── main.c ├── 05_prethreading │ ├── main.c ├── 06_poll │ ├── main.c ├── 07_epoll │ └── main.c ├── Makefile ├── public │ ├── indeks .html │ └── tux .png └── şablonlar └── ziyaretçi defteri └── index.html

Tüm mimariler için yedi dizine ek olarak, üst düzey dizinde iki dizin daha vardır: genel ve şablonlar. İlki index.html dosyasını ve ilk ekran görüntüsündeki resmi içerir. Oraya başka dosya ve klasörler koyabilirsiniz ve ZeroHTTPd bu statik dosyaları sorunsuz bir şekilde sunmalıdır. Tarayıcıdaki yol ortak klasördeki yolla eşleşiyorsa ZeroHTTPd bu dizinde index.html dosyasını arar. Ziyaretçi defterinin içeriği dinamik olarak oluşturulur. Yalnızca bir ana sayfası vardır ve içeriği 'templates/guestbook/index.html' dosyasına dayanmaktadır. ZeroHTTPd, uzantı için kolayca dinamik sayfalar ekler. Buradaki fikir, kullanıcıların bu dizine şablonlar ekleyebilmesi ve ZeroHTTPd'yi gerektiği gibi genişletebilmesidir.

Yedi sunucunun tamamını oluşturmak için şunu çalıştırın: make all üst düzey dizinden - ve tüm yapılar bu dizinde görünecektir. Yürütülebilir dosyalar, başlatıldıkları dizindeki genel ve şablon dizinlerini arar.

Linux API'si

Bu makale serisindeki bilgileri anlamak için Linux API konusunda çok bilgili olmanıza gerek yok. Ancak bu konu hakkında daha fazlasını okumanızı tavsiye ederim, internette birçok referans kaynağı var. Linux API'lerinin çeşitli kategorilerine değinecek olsak da, odak noktamız öncelikle süreçler, iş parçacıkları, olaylar ve ağ yığını üzerinde olacaktır. Linux API ile ilgili kitap ve makalelerin yanı sıra, sistem çağrıları ve kullanılan kütüphane fonksiyonları için de mana okumanızı tavsiye ederim.

Performans ve Ölçeklenebilirlik

Performans ve ölçeklenebilirlik hakkında bir not. Teorik olarak aralarında hiçbir bağlantı yoktur. Birkaç milisaniyelik yanıt süresiyle çok iyi çalışan bir web hizmetiniz olabilir, ancak hiç ölçeklenmiyor. Benzer şekilde, yanıt vermesi birkaç saniye süren, ancak onbinlerce eşzamanlı kullanıcıyı yönetecek şekilde onlarca ölçeklenen, düşük performanslı bir web uygulaması olabilir. Ancak yüksek performans ve ölçeklenebilirliğin birleşimi çok güçlü bir bileşimdir. Yüksek performanslı uygulamalar genellikle kaynakları tasarruflu kullanır ve böylece sunucuda daha fazla eş zamanlı kullanıcıya verimli bir şekilde hizmet vererek maliyetleri azaltır.

CPU ve G/Ç görevleri

Son olarak, hesaplamada her zaman iki olası görev türü vardır: G/Ç ve CPU için. İnternet üzerinden istek alma (ağ G/Ç), dosya sunma (ağ ve disk G/Ç), veritabanıyla iletişim kurma (ağ ve disk G/Ç) tüm G/Ç etkinlikleridir. Bazı veritabanı sorguları biraz CPU yoğun olabilir (sıralama, bir milyon sonucun ortalamasını alma, vb.). Çoğu web uygulaması mümkün olan maksimum G/Ç ile sınırlıdır ve işlemci nadiren tam kapasiteyle kullanılır. Bazı G/Ç görevlerinin çok fazla CPU kullandığını gördüğünüzde, bu büyük olasılıkla zayıf uygulama mimarisinin bir işaretidir. Bu, CPU kaynaklarının süreç yönetimi ve içerik değiştirme için israf edildiği anlamına gelebilir ve bu tamamen yararlı değildir. Görüntü işleme, ses dosyası dönüştürme veya makine öğrenimi gibi bir şey yapıyorsanız uygulama güçlü CPU kaynakları gerektirir. Ancak çoğu uygulama için durum böyle değildir.

Sunucu mimarileri hakkında daha fazla bilgi edinin

  1. Bölüm I: Yinelemeli Mimari
  2. Bölüm II. Çatal sunucular
  3. Bölüm III. Ön çatal sunucuları
  4. Bölüm IV. Yürütme iş parçacıklarını içeren sunucular
  5. Bölüm V. Önceden iş parçacıklı sunucular
  6. Bölüm VI. Pol tabanlı mimari
  7. Bölüm VII. epoll tabanlı mimari

Kaynak: habr.com

Yorum ekle