Tips on Improving Performance of phpFox:: Part 1 Being a SysAdmin , I'm always researching for ways to make my systems FASTER! I just love speed, and so it's no surprise that I've been digging into the phpfox code to see what can be done to stretch phpfox's performance without breaking things up. Let's get started. 1. Hosting *most* of the static files on different server for load balancing. I had posted a feature request here asking the phpfox development team to implement a feature to host static files on CDN or on a different server for load balancing purposes (see tracker : http://www.phpfox.com/tracker/view/8615/ ). Actually , for those who've been curious enough, you may have discovered that this was possible to accomplish without even doing editing the core files , assuming editing /include/setting/common.sett.php doesn't count as touching the core files. Here's how to do this : Let's call the secondary server used for load-balancing purposes ServerB and the main server where phpFox is install serverA. 1. Copy the following folders from serverA to serverB : modules , include , theme ,static You don't need to make any modifications on any files. just copy them as they are. 2. Edit this file /include/setting/common.sett.php on serverA . What we are doing here is to configure ServerB to be used for serving static content (css, js ) . We shall modify the following entries : $_CONF['core.url_static2'] = $_CONF['core.path'] . 'static/'; $_CONF['core.url_static'] = $cdnRootUrl . '/static/'; For simplicity sake , Use the following common.sett.php and change the line below to reflect serverB $cdnRootUrl = 'http://ServerB.com/' ; Here's how it should look like after editing. <?php /** * [PHPFOX_HEADER] * * @copyright [PHPFOX_COPYRIGHT] * @author Raymond Benc * @package Phpfox * @version $Id: common.sett.php 2880 2011-08-23 10:31:43Z Miguel_Espinoza $ */ defined('PHPFOX') or exit('NO DICE!'); $_CONF['core.http'] = 'https://'; $_CONF['core.https'] = 'http://'; //Server to host static content $cdnRootUrl = 'http://ServerB.com/' ; $_CONF['core.path'] = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' ? 'https' : 'http') . '://' . $_CONF['core.host'] . $_CONF['core.folder']; $_CONF['core.spath'] = $_CONF['core.path'] ; $_CONF['core.dir_file'] = PHPFOX_DIR . 'file' . PHPFOX_DS; $_CONF['core.url_file'] = $_CONF['core.path'] . 'file/'; $_CONF['core.url_file2'] = $cdnRootUrl . '/file/' ; $_CONF['core.dir_cache'] = $_CONF['core.dir_file'] . 'cache' . PHPFOX_DS; $_CONF['core.url_module'] = $_CONF['core.path'] . 'module/'; /* /file/ directories */ $_CONF['core.dir_pic'] = $_CONF['core.dir_file'] . 'pic' . PHPFOX_DS; $_CONF['core.url_pic'] = $_CONF['core.url_file'] . 'pic/'; $_CONF['core.dir_attachment'] = $_CONF['core.dir_file'] . 'attachment' . PHPFOX_DS; $_CONF['core.url_attachment'] = $_CONF['core.url_file'] . 'attachment/'; $_CONF['core.dir_emoticon'] = $_CONF['core.dir_pic'] . 'emoticon' . PHPFOX_DS; $_CONF['core.url_emoticon'] = $_CONF['core.url_pic'] . 'emoticon/'; $_CONF['core.dir_user'] = $_CONF['core.dir_pic'] . 'user' . PHPFOX_DS; $_CONF['core.url_user'] = $_CONF['core.url_pic'] . 'user/'; $_CONF['photo.dir_photo'] = $_CONF['core.dir_pic'] . 'photo' . PHPFOX_DS; $_CONF['photo.url_photo'] = $_CONF['core.url_pic'] . 'photo/'; $_CONF['poll.dir_image'] = $_CONF['core.dir_pic'] . 'poll' . PHPFOX_DS; $_CONF['poll.url_image'] = $_CONF['core.url_pic'] . 'poll/'; $_CONF['quiz.dir_image'] = $_CONF['core.dir_pic'] . 'quiz' . PHPFOX_DS; $_CONF['quiz.url_image'] = $_CONF['core.url_pic'] . 'quiz/'; $_CONF['egift.dir_egift'] = $_CONF['core.dir_pic'] . 'egift' . PHPFOX_DS; $_CONF['egift.url_egift'] = $_CONF['core.url_pic'] . 'egift/'; $_CONF['marketplace.dir_image'] = $_CONF['core.dir_pic'] . 'marketplace' . PHPFOX_DS; $_CONF['marketplace.url_image'] = $_CONF['core.url_pic'] . 'marketplace/'; $_CONF['app.dir_image'] = $_CONF['core.dir_pic'] . 'app' . PHPFOX_DS; $_CONF['app.url_image'] = $_CONF['core.url_pic'] . 'app/'; $_CONF['event.dir_image'] = $_CONF['core.dir_pic'] . 'event' . PHPFOX_DS; $_CONF['event.url_image'] = $_CONF['core.url_pic'] . 'event/'; $_CONF['pages.dir_image'] = $_CONF['core.dir_pic'] . 'pages' . PHPFOX_DS; $_CONF['pages.url_image'] = $_CONF['core.url_pic'] . 'pages/'; $_CONF['group.dir_image'] = $_CONF['core.dir_pic'] . 'group' . PHPFOX_DS; $_CONF['group.url_image'] = $_CONF['core.url_pic'] . 'group/'; $_CONF['share.dir_image'] = $_CONF['core.dir_pic'] . 'bookmark' . PHPFOX_DS; $_CONF['share.url_image'] = $_CONF['core.url_pic'] . 'bookmark/'; $_CONF['music.dir'] = $_CONF['core.dir_file'] . 'music' . PHPFOX_DS; $_CONF['music.url'] = $_CONF['core.url_file'] . 'music/'; $_CONF['music.dir_image'] = $_CONF['core.dir_pic'] . 'music' . PHPFOX_DS; $_CONF['music.url_image'] = $_CONF['core.url_pic'] . 'music/'; $_CONF['video.dir'] = $_CONF['core.dir_file'] . 'video' . PHPFOX_DS; $_CONF['video.url'] = $_CONF['core.url_file'] . 'video/'; $_CONF['video.dir_image'] = $_CONF['core.dir_pic'] . 'video' . PHPFOX_DS; $_CONF['video.url_image'] = $_CONF['core.url_pic'] . 'video/'; $_CONF['ad.dir_image'] = $_CONF['core.dir_pic'] . 'ad' . PHPFOX_DS; $_CONF['ad.url_image'] = $_CONF['core.url_pic'] . 'ad/'; $_CONF['subscribe.dir_image'] = $_CONF['core.dir_pic'] . 'subscribe' . PHPFOX_DS; $_CONF['subscribe.url_image'] = $_CONF['core.url_pic'] . 'subscribe/'; $_CONF['css.dir_cache'] = $_CONF['core.dir_file'] . 'css' . PHPFOX_DS; $_CONF['css.url_cache'] = $_CONF['core.url_file'] . 'css/'; $_CONF['chat.dir_cache'] = $_CONF['core.dir_file'] . 'chat' . PHPFOX_DS; $_CONF['chat.url_cache'] = $_CONF['core.url_file'] . 'chat/'; $_CONF['core.dir_watermark'] = $_CONF['core.dir_pic'] . 'watermark' . PHPFOX_DS; $_CONF['core.url_watermark'] = $_CONF['core.url_pic'] . 'watermark/'; $_CONF['core.dir_icon'] = $_CONF['core.dir_pic'] . 'icon' . PHPFOX_DS; $_CONF['core.url_icon'] = $_CONF['core.url_pic'] . 'icon/'; /* Static URLS */ $_CONF['core.dir_static'] = PHPFOX_DIR . 'static/'; $_CONF['core.url_static2'] = $_CONF['core.path'] . 'static/'; $_CONF['core.url_static'] = $cdnRootUrl . '/static/'; $_CONF['core.url_static_script'] = $_CONF['core.url_static2'] . 'jscript/'; $_CONF['core.url_static_css'] = $_CONF['core.url_static'] . 'style/'; $_CONF['core.url_static_image'] = $_CONF['core.url_static'] . 'image/'; $_CONF['core.url_misc'] = $_CONF['core.url_static_image'] . 'misc/'; // Name of the thumbnail directory $_CONF['core.url_thumb'] = 'thumb/'; ?> Explanation : The line $_CONF['core.url_static'] = $cdnRootUrl . '/static/'; has been changed to point to the serverB. The line $_CONF['core.url_static_script'] = $_CONF['core.url_static2'] . 'jscript/'; will still point to the the main server ,serverA , due to some javascript problems if serverB is used to server files in the /static/jscript/ directory. *****Important**** You MUST enable PHP support on serverB IF you enable gzip compression. To get maximum performance using this setup , I would recommend enabling php on serverB , so that gzip feature can be used. Enable CSS and JS Caching&Compression in the adminCP . This way 90+% of your JS and CSS from modules and core will all be compressed into 2 files (1 for CSS and the other for JS ). This would be a a huge performance gain. Save the file , clear the cache and the test it out. View the page HTML source to verify that files are actually being server from serverB. P.S The reason for copying the /include directory is so that the file /static/gzip.php can use the phpFox server settings . 2. Memcache vs File cache I won't go into details on how to install and configure memcached as it's beyond the scope of this tutorial. I'm just going to share my experience here. I'd been using memcached instead of the default file cache before hoping the performance would be better. But I didn't get any performance gain or at least i didn't notice any. In fact , I found out my system became even slower . Reverting to file-based caching made my site load quicker . After doing some research on this anomaly , I came up with the conclusion that memcached server , being hosted on another server , must have been suffering from I/O latency especially as many cache records were being read (I had over 100K cache entries in memcached sometimes, thus ,if it took 1ms to get a record, it'd take 1000 x 1ms = 1000ms to get 1000 records. ). Thus, *In My Setup* it's still faster executing mysql queries and using file-based caching instead of memcached. This may NOT be true for everyone. I'm suspecting that memcached PHP binaries may not have been optimized properly and/or the memcached server implementation maybe be faulty. These are all speculations . I'd thus advise anyone using memcached to carry out some preliminary tests before making deployment. I hope this tutorial has been informative to you. Feel free to share your feedback. Storing Images, Videos & Songs on Separate Servers (Phpfox CDN) Requires: phpFox v3.1.0 or higher This article will guide you how to store images, videos and songs being uploaded by your end-users on a separate server or multiple servers. This is to emulate services such as Amazon S3 or a traditional CDN When you download our product you will find the folder: tools/cdn/ In that folder you will find 2 files: phpfox-cdn.php phpfox-cdn-setting.php.new These files must be placed on the server that will receive the images, videos and songs we are sending from your phpFox site. In this article our phpFox domain will be "www.mainsite.com ". The server that we will upload content to will be called "www.uploadserver1.com ". Lets begin... 1) Access your upload server www.uploadserver1.com via FTP and upload the following 2 files: phpfox-cdn.php phpfox-cdn-setting.php.new 2) Make a directory called file on your upload server phpfox-cdn-setting.php.new and give it full write permission (usually 0777 on most servers). 3) Rename the file phpfox-cdn-setting.php.new to phpfox-cdn-setting.php and then open that file. 4) Look for: PHP: define('CDN_KEY', ''); and replace that with: PHP: define('CDN_KEY', 'abc123'); In this example the key I created is abc123. Make sure to use that key now. You can change this in the future. Save and close that file. 5) Via FTP, log onto your main site www.mainsite.com and rename the file: include/setting/cdn.sett.php.new to include/setting/cdn.sett.php 6) Open the file: include/setting/cdn.sett.php 7) Look for: PHP: $aServers = array(); and replace with: PHP: $aServers = array( array( 'upload' => 'http://www.uploadserver1.com/', 'file' => 'http://www.uploadserver1.com/file/', 'key' => 'abc123' ) ); 8) Log into your Admin Control Panel and go to: Settings >> Manage Settings >> CDN (Content Delivery Network) 9) For the setting CDN Service select phpfox. 10) For the setting Enable CDN (Beta) select True. That's it! Now that everything is setup, lets look over step 7 again. This is where we edited the CDN config file and added the following: PHP: $aServers = array( array( 'upload' => 'http://www.uploadserver1.com/', 'file' => 'http://www.uploadserver1.com/file/', 'key' => 'abc123' ) ); You can add as many servers here as you want, each with their own unique key. The key you add here must match the key on the upload server. So if we wanted to add more sites this variable could look like: PHP: $aServers = array( array( 'upload' => 'http://www.uploadserver1.com/', 'file' => 'http://www.uploadserver1.com/file/', 'key' => 'abc123' ), array( 'upload' => 'http://www.uploadserver2.com/', 'file' => 'http://www.uploadserver2.com/file/', 'key' => 'abc1234' ), array( 'upload' => 'http://www.uploadserver3.com/', 'file' => 'http://www.uploadserver3.com/file/', 'key' => 'abc12345' ) ); การทา Replicate MySQL MySQL เป็ นฐานข้อมูลที่ได้รับความนิยมอย่างมากในปัจจุบนั อาจทางานได้ดี มีเสถียรภาพ มีขนาดเล็ก ติดตั้งง่าย หาเอกสารอ้างอิงง่าย อีกทั้งยังถูกจับคูก่ บั PHP ชนิดที่เรี ยกกันว่า ซี้ ป๊ ึ ก กันเลยทีเดียว หมายถึงคาสัง่ ต่างๆ ของ PHP จะมีสามารถเรี ยกใช้ความสามารถของ MySQL ได้อย่างเด็มประสิทธิภาพทีเดียว ยิง่ หากได้ใช้ phpmyadmin อีกยิ่งเข้ากันเป็ นปี่ เป็ นขลุย่ แถมหาก Run อยูบ่ น Apache อีก โอ้ว เข้าแก๊ง แต่ยงั ขาดหัวหน้าแก๊งไปได้ไม่ได้ นัน่ คือ Linux โอ อย่างนี้ตอ้ งเรี ยกว่า มาเป็ นทีม อาจเรี ยกได้ว่าเป็ น Dream Team หรื อทีมในฝันของนักพัฒนาเว็บแอพพลิเคชัน่ เลยทีเดียว ซึ่ งทีมนี้มีชื่อเล่น ว่า LAMP (Linux, Apache MySQL, PHP) *ขออภัย นอกเรื่ องอีกแล้ว MySQL สามารถทางานได้ท้งั ระบบปฏิบตั ิการ Windows, Linux, Solaris, FreeBSD ทั้งแบบ 32 และ 64 Bit ซึ่ งปัจจุบนั ที่กาลังเขียนอยูน่ ้ ี Version 5.1.20 Beta Replicate MySQL ล่ะคืออะไร เกี่ยวข้องกันอย่างไร … หลายท่านรู้จกั การ Backup ข้อมูล หากท่านรู้จกั การทา Mirror Disk นัน่ แหละ ความหมายเดียวกัน … ฐานข้อมูลนั้นมีความสาคัญอย่างยิ่ง เนื่องจากเว็บแอพลิเคชัน่ นั้นใช้ฐานข้อมูลเก็บข้อมูลทุกสิ่งทุก ๆ อย่าง ฐานข้อมูลก็ไม่ได้ถูกโหลดเข้า Memory ได้ท้งั หมด ก็ยงั คงต้องใช้ Disk ซึ่ งเจ้า Disk นี่แหละ ที่ชอบสร้างปัญหาให้กบั ระบบงานอยูบ่ ่อยครั้ง หากข้อมูลที่สาคัญ เช่น ข้อมูลด้านการเงิน ข้อมูลการขายหน้าร้าน เกิดเรี ยกใช้งานไม่ได้ หรื อหายไป ย่อมเกิดความเสี ยหายให้กบั หน่วยงาน เป็ นอย่างมาก จะดีไหมหากเรามีขอ้ มูลสารองไว้ยงั Disk อีกก้อน หรื อ Server อีกตัว เพื่อเป็ นการลดความเสี่ ยงสาหรับการสูญเสี ยข้อมูล เพราะฉะนั้น เรามาลองทา Replicate MySQL กัน สิ่ งที่ท่านต้องมีการ 1. 2. เครื่ องคอมพิวเตอร์ จานวน 2 เครื่ อง หรื อมากกว่า เครื่ องแรกเรี ยกว่า Master เครื่ องถัดไปเรี ยกว่า Slave. ทั้ง 2 เครื่ องลง Program MySQL โดยที่สามารถ Download ได้ที่ http://dev.mysql.com/downloads/mysql/5.1.html ฿าพรวมของการทา Replicate MySQL Pdf:replicate-mysql.pdf ภาพที่ 1 ภาพรวมของการทา Replicate MySQL ขั้นตอนที่ 1. หากต้องการ Replicate Master ที่มีขอ้ มูลอยูแ่ ล้ว จะต้อง Dump ข้อมูลออกมาเพื่อทาให้ Slave มีขอ้ มูลที่เท่าเทียมกันเสี ยก่อน ขั้นตอนที่ 2. สร้าง User ขึ้นมาเพื่อทาหน้าที่สาหรับทาหน้าที่ Replicate เท่านั้นในฝั่ง Master โดยใช้คาสัง่ mysql> GRANT REPLICATION SLAVE ON *.* -> TO 'repl'@'%.192.168.0.20' IDENTIFIED BY 'slavepass'; * โดยที่ให้สิทธิ์ให้การ Replicate จาก User ที่ชื่อว่า repl และรหัสผ่าน slavepass ที่มาจากเครื่ อง IP 192.168.0.20 เท่านั้น ขั้นตอนที่ 3. ฝั่ง Master เข้าไปแก้ไขไฟล์ my.ini ที่ C:Program FilesMySQLMySQL Server 5.1>my.ini โดยเพิ่มด้านล้างหัวข้อ [mysqld] ดังนี้ # —————————— log-bin=mysql-bin server-id=1 innodb_flush_log_at_trx_commit=1 sync_binlog=1 # ——————————โดยที่ : log-bin=mysql-bin # Binary Log server-id=1 # ลาดับ Server master กาหนด =1 innodb_flush_log_at_trx_commit=1 #สาหรับผูใ้ ช้ฐานข้อมูลที่เป็ น InnoDB จาเ็็ป็นจะต้องให้ Master #commit งานให้เรี ยบร้อยก่อน ถึงจะทาการ Replicate ไปให้ Slave sync_binlog=1 # ทาการ Sync Log สาหรับ InnoDB และหากเกิด Master Crash จะไม่ทาให้ Slave Sync ข้อมูลซ้ า ในกรณี ที่ Master ฟื้ นกลับมาอีกครั้ง ขั้นตอนที่ 4. ฝั่ง Slave ให้เข้าไปแก้ไขไฟล์ my.ini ที่ C:Program FilesMySQLMySQL Server 5.1>my.ini เช่นเดียวกับฝั่ง Master โดยเพิ่มด้านล้างหัวข้อ [mysqld] ดังนี้ #————————————————server-id=2 master-host=192.168.0.10 master-port=3306 master-user=repl master-password-slavepass master-connect-retry=30 replicate-wild-do-table= %.% report-host=192.168.0.20 #————————————————โดยที่ server-id=2 # ลาดับ Slave หากมี Slave มากกว่า 1 ตัวสามารถกาหนด Server-id ได้จนถึง (2 ยกกาลัง 32) -1 เครื่ อง master-host=192.168.0.10 # หมายเลข IP เครื่ อง Master master-port=3306 # กาหนด Port master-user=repl # ชื่อ User สาหรับการ Replicate master-password-slavepass # Password master-connect-retry=30 # หากติดต่อ Master ไ็่ ม่ได้ จะติดต่อซ้ าภายใน replicate-wild-do-table= %.% #กาหนดฐานข้อมูลที่ตอ้ งการ Replicate %.% หมายถึง Database ทุกตัว ขั้นตอนที่ 5. เมื่อ Master และ Slave มีขอ้ มูลเท่ากันแล้ว ดังในขั้นตอนที่ 1 ให้สร้างจุด Check Point เพื่อให้เป็ นจุดเริ่ มต้นสาหรับการ Replicate โดยใช้คาสัง่ mysql> FLUSH TABLES WITH READ LOCK; ให้เรี ยกดูสถานะการทางาน เพื่อดู Binary Log name และ Offset ของ Master ดังนี้ ภาพการเรี ยกดู BinaryLog Name และ Offset ของ Master Binary Log Name : mysql-bin.00004 Offset : 106 ขั้นตอนที่ 6. กาหนดฝั่ง Client ให้ติดต่อกับฐานข้อมูล mysql> CHANGE MASTER TO -> MASTER_HOST='192,168.0.10', -> MASTER_USER='repl', -> MASTER_PASSWORD='slavepass', -> MASTER_LOG_FILE='mysql-bin.00004‘, -> MASTER_LOG_POS=106; และเริ่ มต้น Replicate โดยใช้คาสัง่ mysql> START SLAVE; เพียงเท่านี้ Slave ก็จะเริ่ ม Replicate ข้อมูลจาก Master แล้วครับ สรุป การ Replicate นั้นเป็ นเพียงการพอจะรับประกันได้ว่า ข้อมูลจะไม่สูญหาย แต่ไม่ได้หมายความถึงการแบ่งการทางานเช่น การทา Load Balance หรื อแม้กระทัง่ หาก Server มีปัญหา ไม่ใช่หมายความว่า Slave จะสามารถทางานได้ทนั ที ซึ่ งหากต้องการทาเช่นนั้นจะมีตอ้ งการเช็คสถานะการทางานของตัว Master และ Slave ที่ส่วนใหญ่จะเรี ยกกันว่า สาย heartbeat สาหรับคอยตรวจสอบสถานะซึ่ งกันและกัน ซึ่ งพอจะมี Software OpenSource เช่น Ultra Monky ในการทา Load Balance (แต่ดูเหมือนจะหยุดพัฒนาไปแล้วนะ) สามารถเข้าไปดูรายละเอียดได้ที่ Ultra Monky : http://www.ultramonkey.org/ แต่หากต้องการทาทุกสิ่ งทุกอย่าง เช่น Replicate, Load Balance ทาง MySQL เองก็มีเทคโนโลยี Cluster ที่เหมาะสาหรับระบบที่ตอ้ งการเสถียรภาพสูง (ซึ่ งต้องแลกมาด้วยการใช้ Server อีกหลายตัว) โดยขั้นต่า ต้องใช้อย่างน้อย 4 ตัว สาหรับการทา Cluster แต่รับประกันความเสถียร และประสิ ทธิภาพ โดยสามารถดูเอกสารประกอบได้ที่ MySQL Cluster : http://dev.mysql.com/doc/refman/5.1/en/mysql-cluster.html ขอบพระคุณที่สนใจอ่ าน เอกสารอ้ างอิง MySQL : http://dev.mysql.com/doc/refman/5.1/en/replication.html ที่มา: cattelecom.com Computer NetworkView my profile การทดสอบ Web Server Load Balance ด้ วย HA Proxy + MySQL Cluster การทดสอบ Web Server Load Balance ด้ วย HA Proxy + MySQL Cluster Mar 2012 Feb 2012 ยินดีต้อนรับเข้ าสู่ exteen Jan 2012 Dec 2011 Nov 2011 more การทดสอบ Web Server Load Balance ด้ วย HA Proxy + MySQL Cluster posted on 22 Sep 2009 21:20 by networkg5 สาหรับการทา Web Server Load Balance ในครัง้ นี ้ใช้ Software HA Proxy ติดตังบน ้ Load Balancer ซึง่ ทาหน้ าที่รับการเชื่อมต่อจาก Client แล้ วทาการแจก request ไปให้ กบั Web Server ต่างๆเพื่อไม่ให้ เครื่องใดเครื่องหนึ่งรับ load มากเกินไป ส่วน MySQL Cluster มีหลักการทางานคือ สร้ าง MySQL Cluster Node 2 เครื่องให้ มีการ replicate ข้ อมูล ในฐานข้ อมูลระหว่างกัน โดยมี MySQL Cluster Management Server คอยตรวจสอบการทางานของ Cluster Node ต่างๆ ซึง่ การทดสอบนี ้มีการ set ระบบโดยสร้ าง Virtual Machine บน VMWare Workstation version 6.0 ดังนี ้ Host Name lbl1 mysql1 mysql2 IP Address 192.168.1.103/24 192.168.1.101/24 192.168.1.102/24 OS Ubuntu 8.10 Ubuntu 8.10 Ubuntu 8.10 การติดตังแยกออกเป็ ้ น 2 ส่วนคือ 1. สร้ าง MySQL Cluster 2. ติดตัง้ Web Load Balance โดยใช้ HA-Proxy Duty Software Load Balancer HA Proxy 1.2 MySQL Cluster Management Server MySQL 5 Apache Web Server Apache 2 MySQL Cluster Node MySQL 5 Apache Web Server Apache 2 MySQL Cluster Node MySQL 5 Part 1 : สร้ าง MySQL Cluster การทา MySQL Cluster ในการทดสอบนี ้จะใช้ เครื่อง 3 เครื่องโดยแบ่งเป็ น 1) MySQL Cluster Management Server 1 เครื่อง ทาหน้ าที่เก็บค่า configuration และตรวจสอบสถานะของCluster Node ต่างๆ (Host Name: lb1 , IP Address: 192.168.1.103 ) 2) Cluster Node 2 เครื่อง ทาหน้ าที่เก็บข้ อมูลของ MySQL Server ซึง่ จะมีการ replicate ข้ อมูลกันระหว่างCluster Node (Host Name: mysql1 , IP Address: 192.168.1.101 ) (Host Name: mysql2 , IP Address: 192.168.1.102 ) เริ่ มจากการสร้ าง MySQL Cluster Management Server (lb1)ทาการติดตัง้ #apt-get update #apt-get install mysql-server ทาการ สร้ าง cluster configuration file โดย #mkdir /var/lib/mysql-cluster #cd /var/lib/mysql-cluster #vi config.ini [NDBD DEFAULT] NoOfReplicas=2 [MYSQLD DEFAULT] [NDB_MGMD DEFAULT] [TCP DEFAULT] # Section for the cluster management node [NDB_MGMD] # IP address of the management node (this system) id=1 HostName=192.168.1.103 # Section for the storage nodes [NDBD] # IP address of the first storage node id=2 HostName=192.168.1.101 DataDir= /var/lib/mysql-cluster MySQL ดังนี ้ [NDBD] # IP address of the second storage node id=3 HostName=192.168.1.102 DataDir=/var/lib/mysql-cluster # one [MYSQLD] per storage node [MYSQLD] id=21 Hostname=192.168.1.101 [MYSQLD] id=31 Hostname=192.168.1.102 ทาการ start cluster management server โดย #ndb_mgmd -f /var/lib/mysql-cluster/config.ini ทาให้ start cluster management server อัตโนมัติทกุ ครัง้ ที่ boot เครื่องโดย #echo 'ndb_mgmd -f /var/lib/mysql-cluster/config.ini' > /etc/init.d/ndb_mgmd #chmod 755 /etc/init.d/ndb_mgmd #update-rc.d ndb_mgmd defaults จากนันสร้ ้ าง Cluster Node(mysql1 และ mysql2)ทาการติดตัง้ MySQL ที่เครื่องดังนี ้ #groupadd mysql#useradd –g mysql mysql#apt-get update#apt-get install mysql-server ทาการ config file mysql โดย #vi /etc/mysql/my.cnf [mysqld] ndbcluster # IP address of the cluster management node connectstring=192.168.1.103 node ndb-connectstring=192.168.1.103 ทาการ สร้ าง data directory และ start service MySQL Server โดย #mkdir /var/lib/mysql-cluster #cd /var/lib/mysql-cluster ndb[mysql_cluster] # IP address of the cluster management #ndbd –-initial #/etc/init.d/mysql.server start ทาให้ start cluster node อัตโนมัติทกุ ครัง้ ที่ boot เครื่อง โดย #echo 'ndbd' > /etc/init.d/ndbd #chmod 755 /etc/init.d/ndbd #update-rc.d ndbd defaults เราสามารถดูสถานะการทางานของ Cluster ได้ จาก MySQL Cluster Management Server โดย จากนันท ้ าการทดสอบการ replicate ของข้ อมูลระหว่าง Cluster Node ทังสองเครื ้ ่องโดยสร้ างฐานข้ อมูล และตารางแบบ ndbcluster และทดลอง insert ข้ อมูล บน Cluster Node :mysql1 ทดลอง query ข้ อมูลบน Cluster Node:mysql2 จะพบว่า Cluster Node ทังสองมี ้ ข้อมูลเหมือนกัน จากนันท ้ าการทดสอบโดยให้ process ndbd บน Cluster Node:mysql1หยุดการทางาน แล้ วดูสถานะการทางานของ Cluster จะพบว่า Cluster Node:mysql1แสดงสถานะว่า not connectทาการทดสอบว่ามีการ replicate ข้ อมูลระหว่างกันหรือไม่ โดยการแก้ ไขค่าในฐานข้ อมูล ทดลอง query ข้ อมูลบน Cluster Node:mysql1 จะพบว่าข้ อมูลในตาราง test2 ถูกแก้ ไขเหมือนกัน Part 2 : ติดตัง้ Web Load Balance โดยใช้ HA-Proxy การทา Web Load Balanceในการทดสอบนี ้จะใช้ เครื่อง 3 เครื่องโดยแบ่งเป็ น 1) Load Balancer 1 เครื่อง ทาหน้ าที่รับ request จากเครื่อง Client และส่งต่อ request ไปให้ Web Serverต่างๆ (Host Name: lb1 2) , IP Address: 192.168.1.103 ) Apache Web Server 2 เครื่ อง ติดต่อกับเครื่ อง Client โดยผ่าน Load Balancer (Host Name: mysql1 , IP Address: 192.168.1.101 ) (Host Name: mysql2 , IP Address: 192.168.1.102 ) อันดับแรกทาการสร้ าง Web Server โดยเราจะทาการติดตัง้ Apache บนเครื่ อง mysql1 และ mysql2 โดยทัง้ 2เครื่ องทาเหมือนกันดังนี ้ #apt-get install apache2 ทาการแก้ ไข configuration #vi /etc/apache2/apache2.conf [...] #LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined […] เนื่องจาก haproxy จะตรวจสอบสถานะของ node จาก check.txt ดังนันจึ ้ งไม่จาเป็ นต้ องเก็บ log ของ check.txt #vi /etc/apache2/sites-available/default [...] SetEnvIf Request_URI "^/check\.txt$" dontlog CustomLog /var/log/apache2/access.log combined env=!dontlog [...] สร้ างไฟล์ check.txt #touch /var/www/check.txt สร้ างไฟล์ index.html ดังนี ้ #echo “Test Page Server X” > /var/www/index.html โดยแทนที่ X ด้ วยหมายเลขของเครื่อง Serverแล้ ว restart apache2 ด้ วยคาสัง่ #/etc/init.d/apache2 restart ทาการติดตัง้ HA Proxy เพื่อให้ เครื่อง lb1 ทาหน้ าที่เป็ น Web Load Balancer โดย #apt-get install haproxy จากนันท ้ าการปรับแต่งค่าการทางานของ haproxy ดังนี ้ #vi /etc/haproxy/haproxy.cfg global log 127.0.0.1 local0 127.0.0.1 local1 notice loghost local0 info 4096 haproxy haproxy enable auth admin:pass tlognull 3 2000 0.0.0.0:80 http enable auth admin:admin roundrobin log #log maxconn #debug #quiet user group defaults log global mode http option httplog stats stats option don retries redispatch maxconn contimeout 5000 clitimeout 50000 srvtimeout 50000 listen webfarm mode stats stats balance cookie PHPSESSIONID prefix httpclose forwardfor httpchk HEAD /check.txt HTTP/1.0 server webA 192.168.1.101:80 cookie A check check option option option server webB 192.168.1.102:80 cookie B ทาการ start haproxy #/etc/init.d/haproxy start หลังจากนันทดสอบการท ้ างานของ haproxyโดย ลองเข้ าเว็บไซต์ http://192.168.1.103 จากเครื่อง client แล้ วเราสามารถดูผลว่า HTML Page ถูกส่งมาจาก Web Server เครื่องไหน ทดลองเข้ าเว็บไซต์ http://192.168.1.103 จะพบว่าหน้ า HTML ส่งมาจากWeb Server เครื่องที่ 2 หลังจากกด Reload (เป็ นการ request ครัง้ ที2่ ) จะพบว่าหน้ า HTML ส่งมาจาก Web Server เครื่องที่ 1 ซึง่ เป็ นไปตามหลักการทางานแบบ Round Robin ที่เราได้ กาหนดไว้ ใน HAProxy นอกจากนี ้สามารถดูสถิติการทางานของ haproxy ได้ ที่ http://192.168.1.103/haproxy?stats จากการลองจับpacket ด้ วย WireShark พบว่า Load Balancer (192.168.1.130) จะมีการตรวจสอบเป็ นระยะๆว่ายังสามารถเชื่อมต่อแต่ละ Web Server( 192.168.1.101 , 192.168.102) ได้ หรือไม่ โดย Load Balancer จะส่ง HTTP HEAD/check.txt HTTP/1.0 ไปให้ แต่ละ Web Server และเครื่อง Web Serverจะตอบกลับด้ วย HTTP HTTP/1.1 200 OK เมื่อ Client ทาการเปิ ดเว็บไซต์ http://192.168.1.103 จะมีการส่งข้ อมูลกันผ่าน Load Balancer ดังนี ้ อ้ างอิง : - http://www.howtoforge.com/setting-up-a-high-availability-load-balancer-with-haproxy-keepalived-on-debian-lenny-p2 - http://www.howtoforge.com/loadbalanced_mysql_cluster_debian - http://haproxy.1wt.eu/ - http://www.oknation.net/blog/itlabour/2009/03/25/entry-3