Doküman

Linux HAProxy ile MySQL yük dengeleme

HAProxy, HTTP ve TCP sunucularını yük dengeleyebilen açık kaynaklı bir yazılımdır. Bu yazıda MySQL için yük dengelemesinin nasıl yapıldığını okuyacaksınız. Yük dengeleme, tüm arka uçlara hem okumayı hem de yazmayı içerdiğinden, tüm MySQL sunucularınızın Master-Master çoğaltmasını gerçekleştirecek şekilde yapılandırılması gerekir

Bu yazıda aşağıdaki üç sunucu kullanılacaktır:

Yük Dengeleyici Ana Bilgisayar Adı: haproxy İşletim Sistemi: Ubuntu Özel IP: 10.0.0.100

Düğüm 1 Ana Bilgisayar Adı: mysql-1 İşletim Sistemi: Debian 7 Özel IP: 10.0.0.1

Düğüm 2 Ana Bilgisayar Adı: mysql-2 İşletim Sistemi: Debian 7 Özel IP: 10.0.0.2

Devam etmeden önce, tüm MySQL sunucularının çalışır durumda olduğundan ve veritabanı yazma işlemlerini düzgün bir şekilde çoğalttığından emin olun.

MySQL Sunucularını Hazırlama


HAProxy için iki ek kullanıcı oluşturarak MySQL sunucularını hazırlamamız gerekiyor. İlk kullanıcı, bir sunucunun durumunu kontrol etmek için HAProxy tarafından kullanılacaktır.

root@mysql-1# mysql -u root -p -e "INSERT INTO mysql.user (Host,User) values ('10.0.0.100','haproxy_check'); FLUSH PRIVILEGES;"

HAProxy’den MySQL kümesine erişirken root ayrıcalıklarına sahip bir MySQL kullanıcısına ihtiyaç vardır. Tüm sunuculardaki varsayılan kök kullanıcının yalnızca yerel olarak oturum açmasına izin verilir. Bu, root kullanıcıya ek ayrıcalıklar verilerek düzeltilebilirken, root ayrıcalıklarına sahip ayrı bir kullanıcıya sahip olmak daha iyidir.

root@mysql-1# mysql -u root -p -e "GRANT ALL PRIVILEGES ON *.* TO 'haproxy_root'@'10.0.0.100' IDENTIFIED BY 'password' WITH GRANT OPTION; FLUSH PRIVILEGES"

haproxy_root ve password’ü kendi güvenli değerlerinizle değiştirin . Değişiklikler diğerlerine kopyalanacağından, bu sorguları bir MySQL yöneticisinde yürütmek yeterlidir.

MySQL İstemcisini Kurulumu


Bağlantıyı test etmek için MySQL istemcisinin HAProxy sunucusuna yüklenmesi gerekir.

root@haproxy# apt-get install mysql-client

Şimdi haproxy_root kullanıcısı olarak masterlerden birinde bir sorgu yürütmeyi deneyin .

root@haproxy# mysql -h 10.0.0.1 -u haproxy_root -p -e "SHOW DATABASES"

Bu, MySQL veritabanlarının bir listesini göstermelidir.

HAProxy’yi Yükleme


HAProxy sunucusunda paketi kurun.

root@haproxy# apt-get install haproxy

HAProxy’nin init betiği tarafından başlatılmasını etkinleştirin.

root@haproxy# sed -i "s/ENABLED=0/ENABLED=1/" /etc/default/haproxy

Bu değişikliğin düzgün yapılıp yapılmadığını kontrol etmek için HAProxy’nin init betiğini herhangi bir parametre olmadan çalıştırın.

root@haproxy:~# service haproxy
Usage: /etc/init.d/haproxy {start|stop|reload|restart|status}

HAProxy’yi Yapılandırma


Orijinal yapılandırma dosyasını yeniden adlandırın

mv /etc/haproxy/haproxy.cfg{,.original}

Yeni bir tane oluşturun ve düzenleyin

nano /etc/haproxy/haproxy.cfg

İlk blok, genel ve varsayılan konfigürasyon bloğudur.

global
    log 127.0.0.1 local0 notice
    user haproxy
    group haproxy

defaults
    log global
    retries 2
    timeout connect 3000
    timeout server 5000
    timeout client 5000

HAProxy’ye 127.0.0.1’e günlük mesajları göndermesini söylediğimiz için rsyslog’u onu dinleyecek şekilde yapılandırmamız gerekiyor.

Ana yapılandırma bölümüne geçiyoruz.

listen mysql-cluster
    bind 127.0.0.1:3306
    mode tcp
    option mysql-check user haproxy_check
    balance roundrobin
    server mysql-1 10.0.0.1:3306 check
    server mysql-2 10.0.0.2:3306 check

HTTP yük dengelemenin aksine HAProxy’nin MySQL için belirli bir “modu” yoktur, bu nedenle tcp kullanıyoruz . HAProxy’yi yalnızca geri döngü adresini dinleyecek şekilde ayarladık (uygulamanın aynı sunucuda olduğunu varsayarak), ancak uygulamanız farklı bir sunucuda bulunuyorsa onu 0.0.0.0 veya özel IP adresinde dinletin.

Yük dengeleme istatistiklerini görmek için bir yapılandırma bloğuna daha ihtiyacımız var. Bu tamamen isteğe bağlıdır ve istatistik istemiyorsanız atlanabilir.

listen 0.0.0.0:8080
    mode http
    stats enable
    stats uri /
    stats realm Strictly\ Private
    stats auth A_Username:YourPassword
    stats auth Another_User:passwd

“stats auth” bölümündeki kullanıcı adlarını ve şifreleri değiştirin. Bu, HAProxy’nin HTTP istekleri için 8080 numaralı bağlantı noktasını dinlemesini sağlar ve istatistikler HTTP Temel Kimlik Doğrulaması ile korunur. Böylece istatistiklere adresinden erişebilirsiniz.

http://<Public IP of Load Balancer>:8080/

Yapılandırmayı tamamladığınızda HAProxy hizmetini başlatın.

service haproxy start

HAProxy’yi sorgulamak için mysql istemcisini kullanın.

root@haproxy# mysql -h 127.0.0.1 -u haproxy_root -p -e "SHOW DATABASES"

Geridöngü IP adresiyle birlikte “-h” seçeneği bulunmalıdır.

Yük Dengeleme ve Yük Devretme Testi


Yük dengelemenin çalışıp çalışmadığını kontrol etmek için server_id değişkenini iki veya daha fazla sorgulayın.

root@haproxy# mysql -h 127.0.0.1 -u haproxy_root -p -e "show variables like 'server_id'"
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id     | 1     |
+---------------+-------+
root@haproxy# mysql -h 127.0.0.1 -u haproxy_root -p -e "show variables like 'server_id'"
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id     | 2     |
+---------------+-------+

Bu , eşit ağırlıklarla döngüsel yük dengelemeyi gösterir, şimdi mysql-2 için ağırlığı değiştireceğiz ve sonuçları göreceğiz.

nano /etc/haproxy/haproxy.cfg

server mysql-2 10.0.0.2:3306 check weight 2

Bu değişikliği uygulamak için yeniden yükleyin.

service haproxy reload

server_id için birden çok kez sorgulayın .

root@haproxy:~# for i in `seq 1 6`
do
mysql -h 127.0.0.1 -u haproxy_root -ppassword -e "show variables like 'server_id'"
done

+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id     | 1     |
+---------------+-------+
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id     | 2     |
+---------------+-------+
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id     | 2     |
+---------------+-------+
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id     | 1     |
+---------------+-------+
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id     | 2     |
+---------------+-------+
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id     | 2     |
+---------------+-------+

Şimdi yük dengeleme , isteklerin üçte biri mysql-1’e ve üçte ikisi mysql-2’ye gidecek şekilde 1:2 oranında çalışıyor.

MySQL-1 sunucusundaki servisi durdurun

root@mysql-1# service mysql stop

veya aynı sunucudaki ağ arabirimini pasif hale getirin

root@mysql-1# ifconfig eth1 down

Sonucu görmek için şimdi “değişkenleri göster” sorgusunu deneyin. Aşağıdaki günlük girişleri, HAProxy’nin hatayı ne zaman ve nasıl algıladığını gösterecektir.

tail /var/log/haproxy/haproxy.log

Nov 15 00:08:51 localhost haproxy[1671]: Server mysql-cluster/mysql-1 is DOWN, reason: Layer4 timeout, check duration: 2002ms. 1 active and 0 backup servers left. 0 sessions active, 0 requeued, 0 remaining in queue.

Yük Devretme Aralığını Azaltma


Bir MySQL sunucusu çöktüğünde HAProxy’nin bu hatayı algılaması ve kümeden kaldırması biraz zaman alır. Bu bölümde bu zamanı nasıl kontrol edeceğimizi göreceğiz. İlk önce bu değeri nasıl ölçeceğimizi görelim. Bunun bir yolu iptables kullanarak MySQL bağlantı noktasını belirli bir süre engellemek, ardından kuralı kaldırmak ve günlüğü kontrol etmektir.

root@mysql-1:~# ifconfig eth1 down &&
date &&
sleep 20 &&
ifconfig eth1 up &&
date

Fri Nov 15 00:37:09 IST 2013
Fri Nov 15 00:37:29 IST 2013

3306 numaralı bağlantı noktası 20 saniyeliğine bloke edildi, şimdi günlük dosyasına bakacağız.

root@haproxy:~# tail /var/log/haproxy.log
Nov 15 16:49:38 localhost haproxy[1275]: Server mysql-cluster/mysql-1 is DOWN, reason: Layer4 connection problem, info: "Connection refused", check duration: 0ms. 1 active and 0 backup servers left. 0 sessions active, 0 requeued, 0 remaining in queue.
Nov 15 16:49:56 localhost haproxy[1275]: Server mysql-cluster/mysql-1 is UP, reason: Layer7 check passed, code: 0, info: "5.5.31-0+wheezy1-log", check duration: 1ms. 2 active and 0 backup servers online. 0 sessions requeued, 0 total in queue.

Bir arızanın algılanması 6 saniye (16:49:38 ve 16:49:32 arasındaki fark) ve sunucuya ulaşılabileceğinin algılanması 4 saniye (16:49:56 ve 16:49:52 arasındaki fark) sürdü. Bu, sunucu parametrelerinin yükselmesi, düşmesi ve arası tarafından belirlenir.

rise parametresi , bir sunucunun çalışır durumda olarak bildirilmesi için geçmesi gereken kontrollerin sayısını ayarlar . Varsayılan 2’dir.

fall parametresi , bir sunucunun ölü olarak bildirilmesi için geçmesi gereken kontrollerin sayısını ayarlar . Varsayılan 3’tür.

inter parametresi bu kontroller arasındaki aralığı ayarlar . Varsayılan 2000 milisaniyedir.

Bu bilgiyi bir araya getiren bir sunucu, ölü olarak kabul edilebilmesi için 2 saniye aralıklarla gerçekleştirilen 3 sürekli kontrolde başarısız olmalıdır. Yani yukarıdaki örneğimizde aşağıdakiler olurdu.

16:49:32 - Port 3306 on mysql-1 was blocked
16:49:34 - Check - Failed - Failure No. 1
16:49:36 - Check - Failed - Failure No. 2
16:49:38 - Check - Failed - Failure No. 3 (server removed and event logged)

Ve güvenlik duvarı kuralı kaldırıldığında.

16:49:52 - Firewall rule removed port 3306 accessible
16:49:54 - Check - Passed - Success No. 1
16:49:56 - Check - Passed - Success No. 2 (server added to cluster and event logged)

Aşağıdaki ayarlar, test aralığını 1 saniyeye indirecek ve ayrıca düşme testi sayısını da azaltacaktır.

nano /etc/haproxy/haproxy.cfg

server mysql-1 10.0.0.1:3306 check fall 2 inter 1000
server mysql-2 10.0.0.2:3306 check fall 2 inter 1000

Bazen, özellikle çok sayıda MySQL sunucunuz varsa , özel ağı çok fazla “test” paketiyle doldurmak istemeyebilirsiniz . Bu gibi durumlarda fastinter ve downinter parametreleri kullanışlı olacaktır.

fastinter parametresi, bir sunucu açıldığında veya sunucu kapandığındaki kontroller arasındaki aralığı ayarlar .

Downinter parametresi, bir sunucu kapandığındaki test aralığını ayarlar .

Bu açıklama kafa karıştırıcı olabilir, bu yüzden bir örnekle göreceğiz.

nano /etc/haproxy/haproxy.cfg

server mysql-1 10.0.0.1:3306 check fastinter 1000
server mysql-2 10.0.0.2:3306 check fastinter 1000

“inter” parametresini belirtmediğimiz için varsayılan olarak 2000ms’dir. Bu konfigürasyonla HAProxy’yi yeniden başlatacağız ve testi tekrar yapacağız.

root@mysql-1:~# iptables -A INPUT -p tcp --dport 3306 -j REJECT &&
date &&
sleep 20 &&
iptables -D INPUT -p tcp --dport 3306 -j REJECT &&
date
Fri Nov 15 17:18:48 IST 2013
Fri Nov 15 17:19:08 IST 2013

HAProxy günlük dosyasını kontrol edin.

root@haproxy:~# tail /var/log/haproxy.log
Nov 15 17:18:52 localhost haproxy[1353]: Server mysql-cluster/mysql-1 is DOWN, reason: Layer4 connection problem, info: "Connection refused", check duration: 0ms. 1 active and 0 backup servers left. 0 sessions active, 0 requeued, 0 remaining in queue.
Nov 15 17:19:11 localhost haproxy[1353]: Server mysql-cluster/mysql-1 is UP, reason: Layer7 check passed, code: 0, info: "5.5.31-0+wheezy1-log", check duration: 1ms. 2 active and 0 backup servers online. 0 sessions requeued, 0 total in queue.

Şimdi bir arızayı algılamak yalnızca 4 saniye (önceki 6’ya kıyasla) ve sunucunun çalıştığını algılamak için 3 saniye (4’e kıyasla) sürdü. Perde arkasında yaşananlar bunlar.

17:18:48 - Port 3306 blocked
17:18:50 - Check - Failed - Failure No. 1
17:18:51 - Check - Failed - Failure No. 2
17:18:52 - Check - Failed - Failure No. 3 (server removed and event logged)

Ve bağlantı noktasının engeli kaldırıldığında.

17:19:08 - Firewall rule removed
17:19:10 - Check - Passed - Success No. 1
17:19:11 - Check - Passed - Success No. 2 (server added to cluster and event logged)

İlk önce port blok olayı (17:18:48) ile ilk kontrol (17:18:50) arasındaki aralığa dikkat edin, bu 2 saniyedir (“inter” aralık). Ardından Test 1 <-> Test 2 ve Test 2 <-> Test 3 arasındaki aralığa dikkat edin, sadece 1 saniyedir (“fastinter” aralığı). Aynı aralıklar, sunucu DOWN’dan UP’a geçtiğinde fark edilebilir. Yani “fastinter” bu kontroller arasındaki aralığı kontrol eder.

Peki downinter nedir? Bir sunucu DOWN olarak bildirildiğinde HAProxy, her 2 saniyede bir (veya inter’de belirtilen aralıkta) kontrol etmeye devam eder. Gereksiz ağ kaynaklarını kullandığınızı düşünüyorsanız, downinter’ı 5000 olarak ayarlamak HAProxy’nin bir AŞAĞI sunucusunu yalnızca 5 saniyede bir kontrol etmesini sağlayacaktır.

Önemli


Daha önce yaptığımız testler paketleri REDDETmişti, yani HAProxy mysql-1’e bir SYN paketi göndererek bir bağlantı başlattığında bir RST paketi aldı (SYN + ACK yerine). Bu nedenle günlük girişinde “Bağlantı reddedildi” yazıyor. Bu durumda sadece düşüş, inter ve fastinter değerleri devreye girer.

Bunun yerine HAProxy, SYN gönderdikten sonra hiçbir şey almadıysa, bağlantı zaman aşımına uğrar. Bu durumda yukarıda belirtilen parametrelere ek olarak “timeout” süresi devreye girer. Bu durum gerçekleşebilir eğer

  • iptables DROP olarak ayarlanırsa
  • özel arayüz çalışmıyorsa
  • özel ağ altyapısında bir sorun varsa

Yazının orijinalini buradan okuyabilirsiniz.