High Performance Web Infrastructure

วันนี้ผมมีเวลาว่าง เลยอยากจะเขียนเล่าเรื่องการออกแบบ
Web Infrastructure ให้รองรับ load สูงๆ ได้ ว่าทำแบบไหนดี
โจทย์ของผมคือเป็น web สำหรับ booking ที่จะมีคนเข้าใช้งานจำนวนมาก
ในตอนเปิดให้ใช้งาน เป้าหมายที่ตั้งไว้คือ 1000 tps/s ++
และต้องไม่ down โดยผมมี physical server อยู่ 3 node

ในการออกแบบ Infrastructure นั้น ไม่มีแบบไหนถูกแบบไหนผิด
อยู่ที่ลักษณะของงานของเรา ว่าต้องการแบบไหน อยู่ที่จินตนาการของเรา
ว่าทำแบบไหนดี การออกแบบระบบ ก็เป็นศิลปะ อย่างหนึ่ง ..

Simply The Best เป็นคำตอบ ที่ผมใช้ออกแบบระบบที่ผมจะใช้งานนี้
เท่าที่ดูลักษณะ web แล้ว จะมีการ Read/Write DB หนักพอๆ กัน ถ้าเราแยก DB
ออกไป ก็จะทำให้เกิด connections จำนวนมากเกิดขึ้นในระบบ
ต้องแยก Read/Write ที่ตัว web app อีกเกิดความยุ่งยาก มากขึ้น
ผมเลยเอา web กับ DB ไว้ในตัวเดียวกันไปเลย แล้วใช้ HAProxy
เป็น Load Balancer round robin แบบ keep-alive
มี vip เป็น Public IP ที่ eth0 และใช้ eth1 เป็น Private IP
ยิงเข้าหา แต่ละ node ที่ต้องแยก interface เพื่อเป็นการกระจาย traffic
DB ที่ใช้ผมเลือกเป็น MariaDB ที่ทำงานได้ performance ดีกว่า MySQL
และใช้ Galera Cluster เป็นตัว sync data ของ DB แต่ละ node เข้าหากัน
ทำให้ ทุก node มี data ที่เหมือนกัน node ใด node นึง down ไป
ทุก node ก็จะยังทำงานได้สมบูรณ์ ถ้าเราต้องการเพิ่ม node เข้ามา
ก็สามารถทำได้ง่าย แค่ on ขึ้นมา Galera Cluster ก็จะทำการ sync data ให้

ในส่วนของ Web Server ผมใช้ Apache 2.2.22 ที่มากับตัว Debain Wheezy
มีการ tuning ค่าต่างๆ พอสมควรให้เหมาะกับการใช้งาน ตรงนี้เดี๋ยวผมมาเล่าอีกที
ที่เลือกใช้ apache เพราะ มีความยืดหยุ่นสูง ทำงานได้ดีกับ code ทุกรูปแบบ
ส่วน code เป็น PHP กระจายไปทุก node เก็บไว้ที่ local disk ของแต่ละ node
และใช้ APC เป็น opcode cache อีกระดับนึง

ปัญหาที่เจอ มีดังนี้
– auto increment จะไม่เรียงกัน เท่าไร มีกระโดดบ้าง แต่ก็รับได้
– HAProxy 1.5.4 default จะเก็บ log ทำให้ ถ้า log ใหญ่ๆ จะหนักได้
– เวลาแก้ code ต้อง up ทุก node

ผลที่ออกมา หลังจากใช้งานจริง พบว่า รองรับการใช้งานได้ดีมาก
รับ load จำนวนมหาศาล และ users ได้จำนวนมากพร้อมๆ กัน
ส่วนรายละเอียดการ tuning ผมจะขอแยกอธิบาย ในตอนต่อไป
เพราะว่า เยอะพอสมควร ..

Web Infrastructure

Web Infrastructure

วันนี้ มีเวลานิดหน่อย ก็เลยมาเล่าถึงเรื่อง Web Infrastructure กัน ว่าแต่ละระบบ
เรียงจากขนาดเล็ก มาจนถึงขนาดใหญ่ มีวิิธีการวาง Infrastructure และแนวคิด
ในการวางระบบต่างกันอย่างไรบ้าง เพื่อที่จะให้รองรับกับจำนวนผู้ใช้งานได้ตาม
ที่ต้องการ ในที่นี้ ผมแบ่งออกเป็นย่อยๆ ประมาณ 6 ระดับครับ มาดูกันเลย  ..

1. จะมี service ทุกอย่างรวมกันอยู่ในเครื่องเดียว ทั้ง web server, DB และอื่นๆ
ใน 1 เครื่อง อาจจะมีจำนวนหลายเว็บ แบบนี้ก็ประเภท web hosting ต่างๆ

2. เมื่อมีคนเข้าเยอะขึ้น เครื่องเดียวทำงานไม่ไหว ก็ต้องมีการแยก web server กับ DB
ออกจากกัน เพื่อให้ทำงานได้มีประสิทธิภาพ รองรับจำนวนผู้ใช้งานได้มากขึ้น การแยก
web server ออกจาก DB นั้น ไม่ได้เกี่ยวกับเรื่อง security หลายๆ คนเข้าใจผิด คิดว่า
การแยกออกจากกันเพื่อเรื่องนี้ แต่จริงๆ แล้วเพื่อ performance อย่างเดียวจริงๆ

3. เมื่อระบบแบบที่ 2 รองรับไม่ไหว เราก็ต้องเพิ่มเครื่อง caching มาช่วยจัดการกับ
static file เช่นพวก jpg, gif, png, html เพื่อทำให้ web server ทำงานได้เบาลง
พวก caching ที่นิยมใช้งานก็เป็นพวก varnish, squid, nginx และพวก lighthttpd
อื่นๆ ที่เก่งในเรื่องการทำงานกับ static file แทน apache2 ที่ทำงานหนักกว่า ..

4. เมื่อเรามี caching มาช่วย web server แล้ว ปัญหาที่ตามมาอีกก็คือ ทางฝั่ง DB บ้าง
ก็จะเริ่มหนัก เราก็เลยต้องมีวิธีการแบ่ง Read/Write ออกจากกัน โดยที่ data ต้องเหมือนกัน
ในกรณีที่ใช้ MySQL เราก็จะทำ MySQL Replication แยก Read/Write ออกจากกัน
เพราะว่าส่วนใหญ่แล้ว จะเป็น Read ประมาณ 90%  Write ประมาณ  10% เท่านั้น ในกรณีนี้
ถ้าเครื่องเดียว ยังไม่เพียงพอกับการ Read เราก็สามารถเพิ่ม MySQL Slave เข้าไปได้
ให้เพียงพอกับจำนวน Read ที่เราต้องการ

5. ในเมื่อโครงสร้างเดิมๆ 1-4 ไม่สามารถรองรับกับจำนวนคนใช้งานได้แล้ว เราก็จำเป็นต้อง
มี LB (Load Balancer)  เข้ามาช่วยเป็นตัวจัดการกระจาย load ให้ระบบของเราให้เท่าๆ กัน
LB มีให้เลือกใช้งานมากมาย ทั้งที่เป็น S/W และ H/W ถ้ามีทุนมากหน่อย ก็เลือกแบบ H/W
ก็จะทำให้การจัดการทำได้ง่ายขึ้น แต่ถ้าต้องการประหยัด S/W LB หลายๆ ตัวก็ทำได้ดี
ในโครงสร้างรูปที่ 5 เราจะใช้ LB มาแบ่ง load ระหว่าง caching 2 ตัว ที่อยู่หน้า web server
เมื่อตัวใดตัวนึงมีปัญหา ระบบก็จะยังใช้งานได้ปกติ ในส่วนของ web server เองก็เช่นกัน เรามี
LB มาเป็นตัวช่วยกระจาย load โดยที่ web server ทุกตัวจะ mount file จาก NFS กลาง
ทำให้ทุกเครื่องมี data ที่เหมือนกัน เมื่อเครื่องใดเครื่องนึง มีปัญหาระบบก็ยังจะทำงานต่อไปได้
ส่วน DB ก็ใช้วิธีการแยก Read/Write เหมือนกับระบบที่ 4

6. เมื่อโครงสร้างแบบที่ 5 เริ่มรองรับไม่ไหว เราก็ต้องมีวิธีวางแผนกันใหม่ สิ่งที่ดีที่สุด ก็คือ
การแยก static กับ dynamic ออกจากกัน แล้วก็เอาเรื่องของ memory เข้ามาช่วย นอกนั้น
ส่วนอื่นๆ ก็คล้ายๆ กับโครงสร้างแบบที่ 5

เอาไว้เท่านี้ก่อนละกันครับ เดี๋ยววันหลังมาเขียนเพิ่มเติมครับ งานเข้าละ  🙂

MySQL Replication Error 1236

สวัสดีครับ วันนี้มีเรื่องเกี่ยวกับ MySQL Replication Error มาเล่าให้ฟังครับ
ผมเองก็เพิ่งเคยเจอเหมือนกัน วิธีแก้ไขทำได้ยากมาก ปัญหาคือเกิดจาก
เครื่อง Master อาจจะมีการ shutdown โดยไม่ได้ stop MySQL ก่อน จึงทำให้
bin-log เกิดความไม่สมบูรณ์ โดยสามารถดูที่ Error Log ของ MySQL จะมี
ข้อความประมาณนี้ ที่เครื่อง Slave

100605 16:51:56 [Note] Slave I/O thread: connected to master ‘slaveuser@192.168.13.10:3306’,  replication started in log ‘mysql-bin.000429’ at position 57053329

100605 16:51:56 [ERROR] Error reading packet from server: Client requested master to start replication from impossible position ( server_errno=1236)

100605 16:51:56 [ERROR] Got fatal error 1236: ‘Client requested master to start replication from impossible position’ from master when reading data from binary log

100605 16:51:56 [Note] Slave I/O thread exiting, read up to log ‘mysql-bin.000429′, position 57053329

ผมพยามจะ STOP/START Slave แล้ว แต่ว่าก็ไม่ช่วยให้อาการดีขึ้น
ทางเดียวที่ควรจะทำคือ ให้เริ่ม Replication ใหม่ โดยใช้ bin-log อันดับถัดไป
ที่ position 0 อย่างในตัวอย่าง ผมก็จะเริ่มที่  mysql-bin.000430 position 0
โดยมีขั้นตอนต่างๆ ดังนี้คือ

mysql> STOP SLAVE;
mysql> change master to MASTER_HOST=’192.168.13.10′, MASTER_USER=’slaveuser’, MASTER_PASSWORD=’xxxxxx’, MASTER_LOG_FILE=’mysql-bin.000430′, MASTER_LOG_POS=0;
mysql> START SLAVE;

จากนั้นทำการสั่ง SHOW SLAVE STATUS\G; ก็จะพบว่าเครื่อง Slave
สามารถกลับมา replication กับเครื่อง Master ได้เหมือนเดิม ..

* คำเตือน ห้ามใช้วิธีการ STOP SLAVE; RESET SLAVE; START SLAVE;
โดยเด็ดขาด เพราะนั่นหมายความว่าจะต้องทำการ sync bin-log ตั้งแต่
bin-log แรกสุดที่เครื่อง Master เก็บไว้ 🙂

* เพิ่มเติม ควรทำการ purge bin-log บ่อยๆ เพื่อเป็นการลดพื้นที่การใช้ดิส
โดยใช้คำสั่ง ดังต่อไปนี้ หรือจะตั้ง cronjob ไว้ก็ได้คร้บ
mysql> PURGE BINARY LOGS BEFORE DATE_SUB( NOW( ), INTERVAL 7 DAY);

PHP+APC

สวัสดีครับ มิตรรักแฟน Blog ทั้งหลาย ไม่ได้ Update มาหลายวันครับ
เพราะว่าวุ่น ๆ อยู่กับงาน ที่ต้อง Optimize Server กันสุด ๆ ครับ
เพราะว่า Web Server ที่มีอยู่ เริ่มรับกับ Traffic มหาศาลไม่ไหว ..
ในเมื่อไม่มีเครื่องเข้ามาช่วย เราก็ต้องรีดพลังมันออกมาสุด ๆ ละกันครับ
สิ่งที่ทำได้ตอนนี้ก็คือ ทำให้มันรองรับ Traffic มหาศาลได้ อย่างดี
– Tuning Server PHP+APC ช่วยได้มาก ๆ ครับ ลด Load ได้ 50%
– Tuning+Optimize Query เทพ
– Design DB ใหม่ ให้มีประสิทธิภาพมากกว่าเดิม
– Tuning Infra Network พยายามลด Hob ให้เหนือน้อยที่สุด
– Tuning Code
System Admin ไปตัดผม อิอิ
– อันนี้ไม่บอกเป็นความลับ อิอิ

ระบบใหญ่ ๆ ต้องละเอียดพอสมควรครับ ทำอะไรชุ่ย ๆ เอาไม่อยู่ 🙂

Hosting, Web Hosting

แนะนำ Web Hosting คุณภาพสูง Uptime 99.99%
Support PHP, MySQL http://www.packetlove.com

วันนี้ผมมี Web Hosting คุณภาพ ราคาไม่แพง มาแนะนำครับ
Server เป็นเครื่อง Brand name Dell 860 ทุกเครื่องครับ
มี Control Panel DirectAdmin (DA) ที่ทำให้ท่านจัดการ
กับ Web Site ของท่านได้ง่าย ๆ ผ่านระบบที่มีคุณภาพ ..
Server ทำงานบนพื้นฐานของ Unix (FreeBSD) สามารถใช้
PHP, Perl, MySQL, FFMPEG ได้โดยทุกอย่าง Update ตลอด
มี Engineer ดูแลตลอด 24/7 ทำให้มั่นใจได้ว่าเว็บของท่าน
จะไม่มีวันเกิดปัญหาแม้นเพียงเสี้ยวนาที ทีมงานเค้าเจ๋งจริง ๆ ครับ
บรรยายสรรพคุณมาซะยืดยาว ถ้าต้องการเช่า Web Hosting
ดี ๆ มีคุณภาพ มีความรับผิดชอบ มี Backup ทุกวัน ที่นี่เลยครับ
URL : http://www.packetlove.com

MySQL SphinxSE and PHP Sphinx Extension

Sphinx a full-text search engine

ตอนนี้ Server นิ่งแล้ว ก็เลยมีเวลามาทำ R&D เกี่ยวกับระบบ Search
เพื่่อนตั้ม (http://www.thaiajax.com) โปเกม่อนเทพ แนะนำ
ว่าให้เอา Sphinx มาช่วย ก็เลยต้องเป็นหน้าที่ผม ที่ต้องทำ Server
ให้ Support หาข้อมูลได้น้อยมากเกี่ยวกับตัว Sphinx ยิ่งในไทย
เท่าที่เห็น ยังไม่มีเลย เพราะคงไม่ต้องใช้ถึงขนาดนี้ ระบบไม่ใหญ่ ..
นั่งงมอยู่นานเหมือนกัน เพราะไม่เคยใช้ หาอ่าน Doc ของเว็บ Sphinx
ก็มีให้อ่านน้อยมาก ๆ แต่เว็บอื่น ๆ มีอยู่พอสมควร ..

ตอนนี้เรื่องการใช้งานการปรับแต่งอะไร ก็กำลัง test กันอยู่ ผมเอา
วิธีการ config มาให้เพื่อน ๆ ที่สนใจได้อ่านกันละกัน เพราะว่ากว่าที่
ผมจะ config ได้ ก็ใช้เวลาพอสมควรเหมือนกัน เลยเอามาแบ่งปัน ..

Install MySQL SphinxSE CentOS 5.2

yum -y install bison patch automake libtool

wget http://www.sphinxsearch.com/downloads/sphinx-0.9.8.tar.gz
wget http://dev.mysql.com/get/Downloads/MySQL-5.0/mysql-5.0.67.tar.gz/from/http://mysql.thaiweb.net/
tar xfz sphinx*
tar xfz mysql*

cd mysql*
patch -p1 < ../sphinx-0.9.8/mysqlse/sphinx.5.0.37.diff
BUILD/autorun.sh
mkdir sql/sphinx
cp ../sphinx-0.9.8/mysqlse/* sql/sphinx
./configure –prefix=/usr/local/mysql –with-sphinx-storage-engine
make
make install

cp support-files/mysql.server /etc/init.d/
/etc/init.d/mysql.server start

mysql> SHOW ENGINES;
+————+———+—————————————————————-+
| Engine | Support | Comment |
+————+———+—————————————————————-+
| MyISAM | DEFAULT | Default engine as of MySQL 3.23 with great performance |
| MEMORY | YES | Hash based, stored in memory, useful for temporary tables |
| InnoDB | YES | Supports transactions, row-level locking, and foreign keys |
| BerkeleyDB | NO | Supports transactions and page-level locking |
| BLACKHOLE | NO | /dev/null storage engine (anything you write to it disappears) |
| EXAMPLE | NO | Example storage engine |
| ARCHIVE | NO | Archive storage engine |
| CSV | NO | CSV storage engine |
| SPHINX | YES | Sphinx storage engine 0.9.8 |
| ndbcluster | NO | Clustered, fault-tolerant, memory-based tables |
| FEDERATED | NO | Federated MySQL storage engine |
| MRG_MYISAM | YES | Collection of identical MyISAM tables |
| ISAM | NO | Obsolete storage engine |
+————+———+—————————————————————-+
13 rows in set (0.00 sec)

Install Sphinx

cd ../sphinx*
./configure --prefix=/usr/local/sphinx --with-mysql
make
make install

cd api/libsphinxclient
chmod +x buildconf.sh
./buildconf.sh
./configure
make
make install

Install PHP Sphinx extension
http://pecl.php.net/package/sphinx


cd ../../../
wget http://th.php.net/get/php-5.2.6.tar.gz/from/this/mirror
wget http://pecl.php.net/get/sphinx-0.2.0.tgz

tar xfz php-5.2.6.tar.gz
tar xfz sphinx-0.2.0.tgz
mv sphinx-0.2.0 php-5.2.6/ext/sphinx
rm configure
./buildconf –force
./configure –with-apxs2=/usr/local/apache/bin/apxs –with-mysql=/usr/local/mysql –enable-force-cgi-redirect –with-gettext –with-zlib-dir=/usr/local/zlib –enable-mbstring –with-curl=/usr/local/lib –with-sphinx
make
make install

ทำนี้ก็เป็นอันเรียบร้อยแล้วครับ สำหรับ MySQL+SphinxSE
และ PHP Sphinx Extension

Sun MySQL Tour MySQL Day in Thailand

Agenda

8.30am
Registration
9.00am
Welcome Speech: Synergy with Sun and MySQL by Dr. Thanachart Numnonda, Business Development Director, Software Practice, Sun Microsystems (Thailand) Ltd.
9.20am
Maximizing Scalability for the Web Economy by Daniel Saito, Senior Manager, Database Group, APAC, Sun Microsystems
10.05am
MySQL HA Solution by David Axmark, Co-founder of MySQL
10.50am
Coffee Break
11.05am
The Value of the AMD Opteron™ Processor in Today’s Database Environments by Mr. Kittinut Warithasuwan, Channel Sales Manager, AMD Thailand
11.35am
MySQL Experience Sharing in Thai IT Environment by Dr. Thanachart Numnonda, Business Development Director, Software Practice, Sun Microsystems
12.05pm
Q&A
12.20pm
End

วันนี้มีโอกาสได้ไปงาน MySQL Day ที่จัดขึ้นเป็นครั้งแรกในประเทศไทย
โดย Sun microsystems Thailand งานนี้ ผู้บรรยายแต่ละคน คือ
ผู้ก่อตั้ง MySQL และผู้บริหารระดับสูงของ Sun ทำให้ได้ความรู้มาก ๆ
แล้วก็ได้พบกับ คนของ MySQL ที่ตอบคำถามต่าง ๆ ได้จริง ๆ ซึ่งก็มี
Dr. Thanachart Numnonda, Business Development Director,
Software Practice, Sun Microsystems (Thailand) Ltd.
Daniel Saito, Senior Manager, Database Group, APAC,
Sun Microsystems และ David Axmark, Co-founder of MySQL
แล้วก็อีกท่านหนึ่งคือพี่บิ๊ก ผมกับพี่บิ๊ก เจอกันที่ True มาแล้วหลายครั้ง
เพราะว่าพี่เค้าเข้ามาคุยงานกับทางผมอยู่ เป็นคนนึงที่เก่งมาก ๆ สามารถ
ปรึกษาในเรื่องต่าง ๆ ได้ เพิ่งรู้วันนี้เหมือนกัน ว่าเป็นรุ่นพี่ ที่วิศวะ ลาดกระบัง
น่าภูมิใจ รุ่น 28 ห่างกับผม 11 ปี เอง แต่ดูพี่เค้ายังหน้าเด็ก ๆ อยู่เลย ..

หลังจากเลิกงานได้เป็นแขก VIP ร่วมรับประทานอาหารกับ ทาง Sun
เพราะได้ connection จากพี่อัท ได้คุยกันแบบตัวต่อตัว กับทาง
ผู้พัฒนา MySQL คือ David Axmark อยากรู้อะไร ก็ถามได้เลยตรงนั้น
จากนั้นผม, พี่อัท, พี่วิน, พี่เจน ก็ไปนั่งเล่น TK Park Central World กัน
ผมเพิ่งเคยมานั่งจริง ๆ จัง ๆ ก็วันนี้แหละ หญิงน่ารักเพียบ มานั่งอ่านหนังสือ
จากนั้นเราก็ไปนั่งร้าน Mc กัน หาอะไรกินหน่อย เพราะว่าตอนกลางวัน
ที่ทาง Sun ชวนรับประทานอาหาร มัวแต่คุยกัน ไม่ค่อยได้กินอะไร เท่าไร
จากนั้นก็แยกย้ายกันกลับ เพราะว่าผมงานเข้า ต้องรีบเข้ามาที่ True ..

สรุปงานนี้เป็นงานที่ดีมาก ๆ ต้องขอบคุณทาง Sun ที่จัดอะไรดี ๆ แบบนี้
และเห็นความสำคัญของกลุ่มผู้ใช้ ผมว่าเป็นสิ่งที่ดี ที่ทาง Sun จะเปิดตัว
MySQL Enterprise ในไทย พวกที่เป็น commercial จะได้วางใจ หันมา
ใช้ MySQL ใน product ที่สำคัญกันมากขึ้น เพราะ MySQL ทั้งเร็ว ทั้งดี
ค่าใช้จ่ายก็ต่ำกว่า Database ตัวอื่น ๆ ทำงานได้หลากหลายกว่าด้วย ..
พวก MySQL Community ก็จะได้มีโอกาส ได้รับความรู้ และรับงาน
พวกนี้ได้ด้วย ในอนาคต เพราะเมื่อหันมาใช้งานกันมากขึ้น ก็ต้องการคน
ที่มีความรู้ ความสามารถ เกี่ยวกับ MySQL มา Support มากขึ้น ..