โจทย์คืองานอีเลิร์นนิ่งกระทรวงศึกษามีเซิร์ฟเวอร์ห้าตัวให้ใช้รองรับนักเรียนจากทั้งประเทศ จะกระจายโหลดไปยังเซิร์ฟเวอร์แต่ละตัวแต่ไม่มีโหลดบาลานด์ให้ Moodle สามารถกำหนดไดเรคทอรี่ไว้เก็บข้อมูลได้ก็จะใช้ตัวหนึ่งเป็นตัวเก็บข้อมูลสกอร์มข้อมูลจะได้ตรงกัน และใช้ตัวอื่นๆรัน php หาทางเลือกดูมี 3 วิธีคือ
- ให้แต่ละตัวรับไปแต่ละภาค ปัญหาคือเกือบทั้งหมดวิ่งผ่านไอเอสพีไม่กี่ที่ และแยกแทบไม่ได้ว่ามากจากภาคไหน
- ใช้ function random สุ่ม server ดูปรากฎว่าการกระจายค่อนข้างกระจุกอยู่ที่ server ตัวหลังๆ เกือบทุกครั้ง
- ทำให้ระบบจำได้ว่าจ่ายงานครั้งสุดท้ายไปที่ตัวไหนแล้วขยับไปตัวต่อไปเรื่อยๆ เหมือนเราแจกไพ่ การจะทำให้ php จำค่าล่าสุดได้นั้นมีการรักษาตัวแปรไว้ได้ 4 วิธี
- เขียนเป็นไฟล์ อันนี้จะมีปัญหาการเข้าถึงพร้อมกันของแต่ละเทรด(Threads)
- Cookie ใช้ไม่ได้เพราะเก็บไว้ที่เครื่องผู้ใช้คนอื่นเข้ามาก็จะอ่านค่าไม่ได้
- Session ข้อมูลจะเก็บบนเครื่องเซิร์ฟเวอร์แต่ก็เป็นการเก็บข้อมูลของแต่ละคนเหมือน cookie
- เก็บในฐานข้อมูล ใช้ร่วมกันได้ แต่เราต้องการแต่ให้ทำงานได้เร็วที่สุด
12345
DROP
TABLE
IF EXISTS `lastserv`;
CREATE
TABLE
`lastserv` (
`used`
int
(11)
default
NULL
) ENGINE=MEMORY
DEFAULT
CHARSET=utf8 COMMENT=
'จำ server ที่ใช้ล่าสุด'
;
INSERT
INTO
`lastserv`
VALUES
(1);
จะเห็นคำสั่งแปลกๆ ENGINE=MEMORY คือ MySQL จะมีระบบบริหารดาต้าเบสอยู่หลายตัวให้เลือกใช้ให้เหมาะกับงานต่างๆอ่านเพิ่มเติมได้จาก MySQL Storage Engine Architecture ในบรรดาเอ็นจิ้นของ MySQL จะมีเอ็นจิ้น Memory ซึ่งจะเก็บข้อมูลใน ram ทำให้อัตราการเข้าถึงข้อมูลเร็วที่สุดโดยเราสามาถเลือกได้ตอนสร้างตารางให้ระบุ engine ลงไปด้วย
ในส่วนโค้ท php ไม่มีอะไรเป็นพิเศษเพียงมีการออพติไมซ์เพิ่มเล็กน้อยคือ123456789101112131415161718192021222324252627282930<?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'
: {
}
break
;
case
'2'
: {
}
break
;
case
'3'
: {
}
break
;
case
'4'
: {
}
break
;
}