คลังเก็บบล็อก

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;
      }

mysql ใครบอกว่ารับงานหนักๆ ไม่ได้


เคยไปรับงานลูกค้าซึ่งเป็นองค์กรรัฐกึ่งเอกชนแหน่งหนึ่ง โดยมีความต้องการขัดใจโปรแกรมเมอร์อย่างหนึ่งคือย้ายจาก mysql เป็น microsoft sql server ซึ่งทำให้การ query ซับซ้อนขึ้นมาก โดยเหตุผลของทางลูกค้าคือไม่มั่นใจว่าจะรองรับข้อมูลจำนวนมากได้ ผมจำได้ว่าแม้แต่ google ที่มีข้อมูลมหาศาลยังใช้ mysql แต่ขณะนั้นไม่มีหลักฐานที่จะแย้งลูกค้าได้ จำใจต้อมยอมรับเงื่อนไขไป

จนวันนี้ได้อ่านเจอว่าระบบเว็บที่มีคนใช้งานติดอันดับต้นๆ ของโลกอย่าง youtube เจ้าของคือ google ใช้ mysql เป็น database ลองเข้าไปอ่าน YouTube Architecture จะเห็นว่าถ้ามี knowleage และการจัดการที่ถูกต้องคนจำนวนน้อยตัวหลักแค่ 10 คน โปรแกรม opensource ก็ไม่น้อยหน้าระบบที่ขายอยู่เป็นหลักแสน หลักล้าน

%d bloggers like this: