Foruma hoş geldin 👋, Ziyaretçi

Forum içeriğine ve tüm hizmetlerimize erişim sağlamak için foruma kayıt olmalı ya da giriş yapmalısınız. Foruma üye olmak tamamen ücretsizdir.

`taskset` Komutu ile Kritik Veritabanı Süreçlerini Belirli CPU Çekirdeklerine Sabitleme (CPU Affinity)

devster

Üye
Katılım
14 Mart 2026
Mesajlar
23
Merhaba arkadaşlar, bugün sizlere özellikle yüksek trafikli veritabanı sunucularında performans ve öngörülebilirlik kazandırmak için kullanabileceğiniz çok faydalı bir teknikten bahsedeceğim: CPU affinity (CPU yakınlığı) ile süreç sabitleme. Benim de yoğun MySQL/PostgreSQL sunucularımda sıklıkla başvurduğum bu yöntem, kritik veritabanı iş parçacıklarını belirli CPU çekirdeklerine atayarak, çekirdekler arası geçiş (context switching) maliyetini azaltır ve önbellek (cache) verimliliğini artırır. Bu sayede daha tutarlı bir sorgu süresi elde edersiniz.

🎯 Neden CPU Affinity Kullanmalıyız?

Linux işletim sistemi, varsayılan olarak süreçleri ve iş parçacıklarını mevcut tüm CPU çekirdekleri üzerinde dengeli bir şekilde çalıştırmaya çalışır. Bu genelde iyidir. Ancak, çok yüksek eşzamanlılık (concurrency) olan durumlarda, özellikle de veritabanı gibi sürekli aynı belleğe erişen uygulamalarda, bir iş parçacığının farklı çekirdekler arasında sürekli taşınması performans kaybına yol açabilir. Her taşınmada, o çekirdeğin L1/L2 önbelleği boşalır. `taskset` ile sabitleme yaparak bu kaybı minimize eder, ayrıca kritik işleri belirli çekirdeklere ayırarak diğer çekirdekleri daha az önemli işler için serbest bırakabilirsiniz.

⚙️ Mevcut CPU Topolojisini ve Süreçleri Görüntüleme

İşleme başlamadan önce, sunucunuzdaki CPU çekirdeklerini ve hedef veritabanı sürecinin şu anki CPU affinity'sini kontrol etmelisiniz.

Sunucunuzdaki toplam çekirdek sayısını ve numaralandırmasını görmek için:
Bash:
lscpu | grep -E "^(CPU\(s\)|Core|Socket)"

Veya daha basit bir şekilde, çekirdek listesini görmek için:
Bash:
cat /proc/cpuinfo | grep processor

Şimdi, örneğin MySQL'in ana süreç ID'sini (PID) bulup, hangi çekirdeklerde çalışabildiğine bakalım. PID'yi bulmak için:
Bash:
pgrep mysqld
Veya
Bash:
systemctl show --property MainPID --value mysql

Bulduğunuz PID'yi aşağıdaki komutta kullanın (örneğin PID 1234 olsun):
Bash:
taskset -cp 1234

Çıktı şuna benzer olacaktır: `pid 1234's current affinity list: 0-15`. Bu, sürecin 0'dan 15'e kadar tüm 16 çekirdekte de çalışabileceği anlamına gelir.

🔧 taskset ile Süreç Sabitleme (Mevcut Çalışan Süreç İçin)

Diyelim ki 16 çekirdekli bir sunucunuz var ve MySQL sürecini ilk 8 çekirdeğe (0-7) sabitlemek istiyorsunuz. Yukarıda bulduğumuz PID ile şu komutu kullanırız:
Bash:
taskset -cp 0-7 1234

Bu komut, PID'si 1234 olan sürecin yalnızca 0,1,2,3,4,5,6 ve 7 numaralı CPU çekirdeklerinde çalışmasını zorunlu kılar. Değişikliği hemen doğrulamak için tekrar `taskset -cp 1234` komutunu çalıştırın.

⚠️ Kritik Uyarı ve Strateji Önerileri

Burada çok önemli bir nokta var: Sadece ana `mysqld` sürecini sabitlemek yeterli olmayabilir. MySQL ve PostgreSQL gibi veritabanları, her bir bağlantı veya sorgu için ayrı iş parçacıkları (thread) oluşturur. Bu iş parçacıkları, ana sürecin affinity maskesini miras alır. Yani ana süreci 0-7 çekirdeklerine sabitlediyseniz, tüm bağlantılarınız da sadece bu çekirdeklerde çalışacaktır. Bu bazen istenmeyen bir durum olabilir.

Benim önerim şu stratejilerden birini uygulamanız:
1. Sadece yoğun "I/O thread" veya "write thread" gibi belirli arka plan iş parçacıklarını ayrı çekirdeklere sabitleyebilirsiniz. Ancak bu daha ileri seviye bir konudur.
2. Daha iyi bir yaklaşım, NUMA mimarisi olan sunucularda, veritabanı sürecini ve belleğini aynı NUMA düğümüne sabitlemektir (`numactl` komutu ile). Bu konuya başka bir rehberde değineceğim.
3. Eğer tüm veritabanı iş yükünüzü izole etmek istiyorsanız, ana süreci tüm çekirdeklerde bırakıp, onun yerine cgroups ile CPU kaynak sınırlaması yapmanız daha esnek olabilir.

Ayrıca, /etc/systemd/system/mysql.service.d/override.conf gibi bir systemd override dosyası oluşturarak, servis başlarken otomatik sabitleme yapabilirsiniz. Bu kalıcı bir çözümdür.

🚀 Yeni Bir Süreci Başlatırken Sabitleme

`taskset` komutu, çalışan bir süreci değil de, henüz başlatacağınız bir uygulamayı belirli çekirdeklerde çalıştırmak için de kullanılabilir. Örneğin, bir test komutunu sadece 2 ve 3 numaralı çekirdeklerde çalıştırmak için:
Bash:
taskset -c 2,3 stress --cpu 2 --timeout 30s

💎 Sonuç ve Öneriler

CPU affinity ayarı, özellikle fiziksel sunucularda ve yüksek performans gerektiren ortamlarda son derece faydalı olabilir. Ancak her sihirli değnek gibi, körlemesine uygulanmamalı. Önce sunucunuzdaki mevcut CPU kullanımını (`top`, `htop`, `pidstat`) ve önbellek etkinliğini (`perf`, `cachestat`) izleyin. Eğer çekirdekler arası geçiş oranı çok yüksekse ve veritabanı sorgu sürelerinizde tutarsızlık varsa, bu yöntemi dikkatlice test etmeye başlayabilirsiniz.

Siz bu konfigürasyonu kendi sunucularınızda nasıl yapıyorsunuz? `taskset` yerine `cgroups` veya `numactl` kullanmayı tercih eden var mı? Tecrübe ve sorularınızı aşağıya yazmaktan çekinmeyin. Herkese sorunsuz sunucular dilerim!
 

Tema özelleştirme sistemi

Bu menüden forum temasının bazı alanlarını kendinize özel olarak düzenleye bilirsiniz.

Zevkine göre renk kombinasyonunu belirle

Tam ekran yada dar ekran

Temanızın gövde büyüklüğünü sevkiniz, ihtiyacınıza göre dar yada geniş olarak kulana bilirsiniz.

Geri