Giriş
Kurumsal uygulamaların her zaman erişilebilir ve ölçeklenebilir olmasını istiyoruz. Bunun için bilişim sistemini oluşturan her katmanda bu özellikleri sağlamamız gerekir. Bu katmanlardan biri de verileri kalıcı olarak saklamamızı ve gerektiğinde olabildiğince hızlı bir şekilde erişmemizi sağlayan ilişkisel veri tabanı sistemleridir. MySQL açık kaynak kodlu, (Oracle, MariaDB, Percona gibi) firmalardan desteğini alabileceğiniz, yaygın ve çok ölçekli kullanımı olan (Facebook gibi) bir çözüm olarak öne çıkmaktadır. MySQL'de çok sunuculu sistemler kurmak mümkündür. Çok sunuculu sistemler, yineleme (=replication) ya da MySQL kümesi (=cluster) ile kurulabilinir. Her birinin kendine göre kazanımları ve yitimleri bulunmaktadır. Bu yazının konusu, bu tür çok sunuculu MySQL sistemlerine istemcilerden ya da uygulamalardan erişimin yükü dengeleyecek şekilde nasıl sağlanabileceğidir. Bunu temel olarak iki şekilde sağlıyoruz:- MySQL Proxy sunucusunu kullanmak
- Eğer uygulamalar Java uygulaması ise Connector/J JDBC sürücüsü kullanmak
I. MySQL Proxy Kullanımı
İlk çözüm, MySQL sunucularına erişimde, istemci ile sunucu arasında vekil sunucu olarak adlandırdığımız MySQL Proxy sunucusu kullanmaktır. Vekil sunucuya çoğunlukla uygulamaların veritabanına erişiminin günlüğünü tutmak, istemcilerin yaptığı işlemlerin güvenlik amacıyla kaydını tutumak, uygulamanın başarımını ölçmek gibi görevler yükleriz. Asıl işi MySQL sunucusu yapmaktadır. Vekil sunucusu temel olarak istemcilerden gelen istekleri sunucuya yönlendirir. Bunu yaparken kendisine yüklenen sorumluluğu da yerine getirir. Vekile yük dengeleme görevi de verilebilinir. MySQL Proxy'nin en güncel sürümü 0.8.3 alpha'dır ve bu bağlantıdan indirebilirsiniz. Bu sürüm MySQL 5.0 ve sonrasındaki tüm sunucularla çalışmaktadır.MySQL Proxy içinden hazır olarak yük dengeleme betiği çıkmaktadır. MySQL Proxy programlama dili olarak lua'yı kullanır. Dolayısı ile yeni görevler vermek isterseniz lua dilini kullanarak kod yazmanız gerekir.
Kurulumu yaptığımızda kurulum dizininde aşağıdaki dizinler yer almaktadır:
01/15/2013 03:19 PM <DIR> bin
08/06/2012 01:42 PM 18,092 COPYING.txt
01/15/2013 03:19 PM <DIR> include
01/15/2013 03:19 PM <DIR> lib
01/15/2013 03:19 PM <DIR> licenses
08/06/2012 01:42 PM 75,713 README.txt
01/15/2013 03:19 PM <DIR> share
Burada bin dizininde vekil sunucusunu çalıştırmamızı sağlayacak uygulama yer alır: mysql-proxy. share\doc\mysql-proxy dizininde ise hazır kullabileceğimiz lua betikleri yer alıyor:
Directory of c:\opt32\mysql-proxy-0.8.3\share\doc\mysql-proxy
active-queries.lua active-transactions.lua admin-sql.lua
analyze-query.lua auditing.lua commit-obfuscator.lua
histogram.lua load-multi.lua ro-balance.lua
ro-pooling.lua rw-splitting.lua tutorial-basic.lua
tutorial-constants.lua tutorial-inject.lua tutorial-keepalive.lua
tutorial-monitor.lua tutorial-packets.lua tutorial-prep-stmts.lua
tutorial-query-time.lua tutorial-resultset.lua tutorial-rewrite.lua
tutorial-routing.lua tutorial-scramble.lua tutorial-states.lua
tutorial-tokenize.lua tutorial-union.lua tutorial-warnings.lua
xtab.lua
Proxy sunucusunu başlatmak için mysql-proxy.exe uygulamasını başlatmak gerekiyor:
cmd> mysql-proxy.exe --daemon --proxy-backend-addresses=192.168.1.1:3306 --proxy-read-only-backend-addresses=192.168.1.2:3306 --proxy-read-only-backend-addresses=192.168.1.3:3306 --proxy-lua-
script=c:\opt32\mysql-proxy-0.8.3\share\doc\mysql-proxy\rw-splitting.lua
2012-04-15 15:47:40: (critical) plugin proxy 0.8.3 started
Bu örnekte bir usta ve iki yamak MySQL sunucusunun olduğu yineleme mimarisi kullanılmıştır. Usta 192.168.1.1 nolu IP adresini, yamaklar ise 192.168.1.2 ve 192.168.1.3 nolu IP adreslerini dinlemektedir. İstemcilerinden gelen SELECT cümlelerini yamaklara ve INSERT/UPDATE/DELETE isteklerini ise ustaya yönlendiren betik rw-splitting.lua isimli dosyada yer almaktadır. Ustanın IP adresini proxy-backend-addresses parametresi ile yamakların IP adresini ise proxy-read-only-backend-addresses parametresi ile veriyoruz. MySQL Proxy 4400 numaralı portta çalışmaktadır. Şimdi sunucuya MySQL istemcisi üzerinden erişebiliriz:
cmd> mysql -uroot -proot --port 4040
Warning: Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.6.10-log MySQL Community Server (GPL)
Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> status
--------------
mysql Ver 14.14 Distrib 5.6.10, for Win32 (x86)
Connection id: 3
Current database: world
Current user: root@localhost
SSL: Not in use
Using delimiter: ;
Server version: 5.6.10-log MySQL Community Server (GPL)
Protocol version: 10
Connection: localhost via TCP/IP
Server characterset: latin1
Db characterset: latin1
Client characterset: cp850
Conn. characterset: cp850
TCP port: 4040
Uptime: 9 min 24 sec
Threads: 3 Questions: 18 Slow queries: 0 Opens: 70 Flush tables: 1 Open tab
les: 63 Queries per second avg: 0.031
--------------
Proxy sunucusunun SELECT cümlelerini gerçekten yamaklara gönderdiğini test etmek için Sorgu cebini açıp izleyebilirsiniz:
mysql> show status like 'Qcac%';
+-------------------------+---------+
| Variable_name | Value |
+-------------------------+---------+
| Qcache_free_blocks | 1 |
| Qcache_free_memory | 1031288 |
| Qcache_hits | 14 |
| Qcache_inserts | 5 |
| Qcache_lowmem_prunes | 0 |
| Qcache_not_cached | 11 |
| Qcache_queries_in_cache | 4 |
| Qcache_total_blocks | 10 |
+-------------------------+---------+
8 rows in set (0.00 sec)
II. Connector/J Kullanımı
MySQL sunucuna Java uygulamasından bağlanabilmek için JDBC sürücüsü kullanıyoruz. MySQL bize Connector/J ile bu sürücüyü sağlıyor. Bu sürücünün yeteneklerinden biri de yük dengeleme yapabilmesidir. Üstelik sunucuları dinamik olarak eklemek çıkarılabilmek mümkündür. Sunucuların listesini, JDBC URL tanımında virgüllerle ayırarak veriyoruz:jdbc:mysql:loadbalance://192.168.1.1:3306,192.168.1.2:3306,192.168.1.3:3306/world
Bu özelliğin kullanıldığı örnek uygulama kodunu aşağıda bulabilirsiniz:
1: package com.example.test;
2: import java.sql.*;
3: /**
4: *
5: * @author Binnur Kurt
6: */
7: public class TestConnector {
8: public static void main(String[] args)
9: throws ClassNotFoundException,SQLException,InterruptedException {
10: Class.forName("com.mysql.jdbc.Driver");
11: int i = 0;
12: while (i < 1000) {
13: Connection connection = DriverManager.getConnection(
14: "jdbc:mysql:loadbalance://192.168.1.1:3306,192.168.1.2:3306, "+
15: "192.168.1.3:3306/world?"+
16: "loadBalanceConnectionGroup=first&loadBalanceEnableJMX=true",
17: "root", "root");
18: Statement statement = connection.createStatement();
19: ResultSet rs = statement.executeQuery("SELECT * FROM Country limit 10");
20: while (rs.next()) {
21: String code = rs.getString("Code");
22: String name = rs.getString("Name");
23: long population = rs.getLong("Population");
24: System.err.println(name + "\t" + code + "\t" + population);
25: }
26: rs.close();
27: connection.close();
28: Thread.sleep(5000);
29: ++i;
30: }
31: }
32: }
Çok güzel bir paylaşım, kodların görünümü biraz kötü duruyor umarım daha düzgün bir blog sistemine geçersiniz bizde zevkle takip ederiz. Teşekkürler.
ReplyDelete