load balance


โจทย์คืองานอีเลิร์นนิ่งกระทรวงศึกษามีเซิร์ฟเวอร์ห้าตัวให้ใช้รองรับนักเรียนจากทั้งประเทศ จะกระจายโหลดไปยังเซิร์ฟเวอร์แต่ละตัวแต่ไม่มีโหลดบาลานด์ให้ Moodle สามารถกำหนดไดเรคทอรี่ไว้เก็บข้อมูลได้ก็จะใช้ตัวหนึ่งเป็นตัวเก็บข้อมูลสกอร์มข้อมูลจะได้ตรงกัน และใช้ตัวอื่นๆรัน php หาทางเลือกดูมี 3 วิธีคือ

  1. ให้แต่ละตัวรับไปแต่ละภาค ปัญหาคือเกือบทั้งหมดวิ่งผ่านไอเอสพีไม่กี่ที่ และแยกแทบไม่ได้ว่ามากจากภาคไหน
  2. ใช้ function random สุ่ม server ดูปรากฏว่าการกระจายค่อนข้างกระจุกอยู่ที่ server ตัวหลังๆ เกือบทุกครั้ง
  3. ทำให้ระบบจำได้ว่าจ่ายงานครั้งสุดท้ายไปที่ตัวไหนแล้วขยับไปตัวต่อไปเรื่อยๆ เหมือนเราแจกไพ่ การจะทำให้ php จำค่าล่าสุดได้นั้นมีการรักษาตัวแปรไว้ได้ 4 วิธี
    1. เขียนเป็นไฟล์ อันนี้จะมีปัญหาการเข้าถึงพร้อมกันของแต่ละเทรด(Threads)
    2. Cookie ใช้ไม่ได้เพราะเก็บไว้ที่เครื่องผู้ใช้คนอื่นเข้ามาก็จะอ่านค่าไม่ได้
    3. Session ข้อมูลจะเก็บบนเครื่องเซิร์ฟเวอร์แต่ก็เป็นการเก็บข้อมูลของแต่ละคนเหมือน cookie
    4. เก็บในฐานข้อมูล ใช้ร่วมกันได้ แต่เราต้องการแต่ให้ทำงานได้เร็วที่สุด
          DROP TABLE IF EXISTS `lastserv`;
          CREATE TABLE `lastserv` (
          `used` int(11) default NULL
          ) ENGINE=MEMORY  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='จำ server  ที่ใช้ล่าสุด';
          INSERT INTO `lastserv`  VALUES (1);

      จะเห็นคำสั่งแปลกๆ ENGINE=MEMORY คือ MySQL จะมีระบบบริหารดาต้าเบสอยู่หลายตัวให้เลือกใช้ให้เหมาะกับงานต่างๆอ่านเพิ่มเติมได้จาก MySQL Storage Engine Architecture ในบรรดาเอ็นจิ้นของ MySQL จะมีเอ็นจิ้น Memory ซึ่งจะเก็บข้อมูลใน ram ทำให้อัตราการเข้าถึงข้อมูลเร็วที่สุดโดยเราสามาถเลือกได้ตอนสร้างตารางให้ระบุ engine ลงไปด้วย
      ในส่วนโค้ท php ไม่มีอะไรเป็นพิเศษเพียงมีการออพติไมซ์เพิ่มเล็กน้อยคือ

      <?php
      $dsn =  mysql_connect('localhost', 'database user', 'databae password');
      mysql_select_db('database name'  ,$dsn);
      /* การระบุ datasource  จะทำงานได้เร็วขึ้น */
      $sql="SELECT used
      FROM lastserv;";
      $row =  mysql_fetch_assoc(mysql_unbuffered_query($sql ,$dsn));
      /* คิวรี่แบบใช้ข้อมูลเพียงครั้งเดียวทิ้งลดการใช้  memory */
      if($row['used'] == 4){
      	$next = 1;
      }else{
      	$next = $row['used']  + 1;
      }
      $sql="UPDATE lastserv
      SET used= $next LIMIT 1;";
      mysql_unbuffered_query($sql  ,$dsn);
      switch($row['used']){
      	case '1'  : {
      		header('Location:  http://192.168.1.1');
      	}break;
      	case '2'  : {
      		header('Location:  http://192.168.1.2');
      	}break;
      	case '3'  : {
      		header('Location:  http://192.168.1.3');
      	}break;
      	case '4'  : {
      		header('Location:  http://192.168.1.4');
      	}break;
      }

About plusmagic

PHP lover in thailand

Posted on 2010/03/03, in database, MySql, PHP, programming and tagged , , , , , , , , , . Bookmark the permalink. ใส่ความเห็น.

ใส่ความเห็น

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / เปลี่ยนแปลง )

Twitter picture

You are commenting using your Twitter account. Log Out / เปลี่ยนแปลง )

Facebook photo

You are commenting using your Facebook account. Log Out / เปลี่ยนแปลง )

Google+ photo

You are commenting using your Google+ account. Log Out / เปลี่ยนแปลง )

Connecting to %s

%d bloggers like this: