Thursday 31 May 2012

Introduction to Gearman

ก่อนจะทำความเข้าใจกับ Gearman เราควรเริ่มทำความเข้าใจเกี่ยวกับเรื่องการกระจายงานกันก่อน ยกตัวอย่างกรณีของ YouTube ซึ่งในแต่ละวัน มีคน Upload Video ไปที่ YouTube เป็นจำนวนมากมาย  ซึ่งแต่ละ Clip นั้น YouTube ต้องทำการ convert ให้เสร็จเรียบร้อยก่อนจึงจะนำมาสามารถบน web ให้เราดูได้  ถ้าหาก YouTube มี Server เพียงแค่เครื่องเดียว คงไม่สามารถ เพียงพอต่อการให้บริการอย่างแน่นอน ซึ่งจาก ยอดคนใช้งานวันละเป็นล้านคน เราก็คงจินตนาการไม่ออกว่า YouTube มี server ที่คอยให้บริการมากมายแค่ไหน... ?

จากตัวอย่างดังกล่าว จะเห็นได้ว่า YouTube น่าจะมีการกระจายงานไปยัง Server เครื่องต่างจำนวนมาก เพื่อให้ช่วยกัน convert video เพื่อที่จะลดเวลาการรอของ user ลง และสามารถเพียงพอต่อความต้องการใช้งานของ user จำนวนมากด้วย ถ้าหากเรามีพัฒนา Web Application ที่ต้องประมวลผลจำนวนมาก และเราต้องการให้มีการกระจายการทำงานคล้ายๆกับ YouTube เราจะทำอย่างไร ? พัฒนาขึ้นมาเอง ก็อาจจะเป็นตัวเลือกนึง แต่มันคงใช้เวลาไม่น้อยในการพัฒนากว่าที่มันจะ Stable ....ถ้าหากไม่พัฒนาเองแล้วเราจะทำอย่างไร ? ซึ่งคำตอบก็คือ "Gearman" นั่นเอง



 Gearman พัฒนาขึ้นโดยมีวัตถุประสงค์ให้เป็นระบบที่คอยช่วยกระจายการทำงานไปยัง computer เครื่องอื่นๆในระบบ ทำให้สามารถลดระยะเวลาการประมวลผลลง และเป็นการแบ่งเบาภาระงานออกจากเครื่อง server หลัก ซึ่งแทนที่จะต้องรับภาระทำงานเองทั้งหมด ก็เหลือเพียงแต่ทำหน้าที่คอยรับ request ส่วนงานหนักๆก็เพียงแค่ส่งต่อมาให้ Gearman จากนั้น Gearman ก็จะประสานไปยังเครื่องอื่นๆในระบบ (ซึ่งเรียกว่า worker) ให้ช่วยกันทำงานแทน และถ้าหากในอนาคต Web ของเราดังขึ้นไปอีก มีจำนวนคนใช้งานมากขึ้น เราจะทำอย่างไร Application ของเราจะรองรับไหวมั้ย ?  Gearman พัฒนาขึ้นโดยมีการคิดเรื่องของการ Scale เอาไว้ให้เรียบร้อยแล้ว ถ้าหากระบบของเราเติบโตขึ้น เราสามารถที่จะเพิ่ม เครื่องที่ช่วยในการทำงาน (worker) เข้าไปในระบบได้เรื่อยๆ เพราะฉนั้นเราไม่จำเป็นต้องมี server farm ขนาดใหญ่ตั้งแต่ใน วันแรกที่เราเปิดให้บริการ เราสามารถที่จะค่อยๆลงทุนเพิ่ม server ภายหลังตามความเหมาะสม ซึ่งช่วยประหยัดเงินไปได้เยอะทีเดียว

โครงสร้างการทำงานของ Gearman











ในระบบของ
Gearman แบ่งการทำงานออกเป็น 3 ส่วนหลักๆ ได้แก่

1. Client ซึ่งก็คือ Application ของเรา ที่จะคอยรับ request และส่งงานต่อไปให้ Gearman เป็นคนจัดการ)

2. Job Server (ทำหน้าที่รับ Request จาก Client และส่งต่องานไปให้ worker แต่ละเครื่องเพื่อช่วยในการทำงาน โดย Job Server จะคอยดูว่า Worker เครื่องไหนว่างอยู่ แล้วถึงจะส่งงานไปให้)

3. Worker (ทำหน้าที่ในการประมวลผล เมื่อประมวลผลเสร็จก็จะส่ง response กลับไปยัง client โดยผ่านทาง Job Server)

จากในรูป สิ่งที่เราต้องพัฒนาขึ้นมาเองก็คือเฉพาะส่วนที่เป็นสีเขียว ซึ่งในรูปก็คือ client และ worker สำหรับ Job Server นั้นจะมีมาให้เรียบร้อยแล้ว เราไม่ต้องทำอะไร เพียงแค่ start job server (job server service จะมีชื่อว่า gearmand) ขึ้นมา จากนั้นเราก็จะพัฒนาในส่วน client และ worker .ให้สามารถเชื่อมกับ Job Server ได้ โดยอาศัย APIs ที่ทาง Gearman เตรียมไว้ให้

ซึ่งทาง Gearman ได้เตรียม APIs เอาไว้ให้ 2 ส่วน ดังนี้ คือ
1. Client API เป็น API สำหรับเอาไว้พัฒนาในส่วนของ Client
2. Worker API เป็น API สำหรับเอาไว้พัฒนาในส่วนของ Worker


ทดลอง Hello World กับ Gearman









เราจะมาเริ่มจากการพัฒนา
Client และ Worker แบบง่ายๆกันก่อน เพื่อให้เข้าใจการทำงานของ Gearman ในภาพรวม สำหรับในที่นี้เราจะสร้าง Application สำหรับ reverse string ที่เราส่งเข้าไป อย่างเช่น ถ้าเราส่ง "Hello World" เข้าไป ก็จะให้ระบบทำการประมวลผล แล้วส่ง "dlroW olleH" กลับมาให้เรา

Client ที่เรากำลังจะพัฒนาขึ้นมานั้น จะทำหน้าส่งงานไปยัง job server และรอการประมวลผล สำหรับในส่วนของ coding นั้น ในที่นี้เราจะพัฒนาขึ้นมาด้วย PHP โดยอาศัย APIs ที่ Gearman เตรียมไว้ให้ (Gearman เตรียม APIs ไว้ให้สำหรับหลายๆภาษา แต่ในที่นี้เราจะลองเริ่มทดลองกับ PHP กันก่อน)


Client Code
$client= new GearmanClient();
$client->addServer('127.0.0.1');
print $client->do("reverse", "Hello World!");

ใน
code ส่วนของ client ที่เราพัฒนา จะเริ่มจากการสร้าง instance ของ class GearManClient ขึ้นมาก่อน จากนั้นในบรรทัดต่อมา เราจะทำการเรียกใช้งาน method ที่มีชื่อว่า addServer('127.0.0.1')  ซึ่งในที่นี้ ให้ระบุ IP Address ของ Job Server เข้าไป เราสามารถ add Job Server ได้มากกว่า 1 เครื่อง (ป้องกัน ในกรณีที่ Job Server เครื่องใดเครื่องหนึ่งมีปัญหา) แต่ในตัวอย่างนี้เราลองเริ่มจากการ add แค่เครื่องเดียวกันดูก่อน ในบรรทัดต่อมาเราสั่งให้ Client เรียกใช้งาน function ที่มีชื่อว่า "reverse" และในที่นี่เรายังส่ง data ชนิด string คำว่า "Hello World" ไปให้ด้วยใน parameter ตัวที่ 2 (สำหรับในส่วนของชื่อ Function และ Argument นั้นเราะตั้งชื่อเป็นอะไรก็ได้ แล้วแต่เรา สำหรับในที่นี้เราตั้งชื่อว่า reverse)

Worker Code
$worker= new GearmanWorker();
$worker->addServer('127.0.0.1');
$worker->addFunction("reverse", "my_reverse_function");
while ($worker->work());
function my_reverse_function($job)
{
    return strrev($job->workload());
}

ในส่วนของ
Worker Code นั้น เราจะเริ่มจากการสร้าง instance ของ Gearman Worker ขึ้นมาก่อน จากนั้นเราก็ทำการเรียก method ที่มีชื่อว่า addServer('127.0.0.1') เพื่อทำการ add Job Server ที่ IP Address 127.0.0.1 บรรทัดต่อมาเป็นการตั้งชื่อ function ของงานที่ worker นี้รับผิดชอบ (จะตั้งเป็นอะไรก็ได้ แล้วแต่เรา แต่เวลาเรียกใช้งานจาก client ชื่อต้องเหมือนกัน) ในที่นี้เราจะตั้งว่า "reverse" เพื่อในเหมือนกับใน client ที่เราได้พัฒนาขึ้น ส่วน parameter ตัวถัดมานั้นหมายถึงชื่อของ PHP Function ที่จะถูก Excecute เมื่อมีการเรียกใช้งาน function "reverse" บรรทัดต่อมาเป็นการเข้าสู่ worker loop ซึ่งจะทำให้ worker อยู่ในสภาวะพร้อมรับคำสั่งจาก Job Server

จาก code ทั้งหมดข้างต้น เมื่อ client ถูกเรียกใช้งาน จะมีการส่งงานที่มีชื่อว่า "reverse" พร้อมทั้ง data (string คำว่า "Hello World") ไปยัง Job Server เมื่อ Job Server ได้รับ Request ก็จะทำค้นหาเครื่องที่มีความสามารถในการทำงานที่มีชื่อว่า "reverse" ที่ยังว่างงานอยู่ จากนั้นก็จะส่งงานดังกล่าวไปให้ จากนั้น worker ที่ได้รับงาน ก็จะทำการประมวลผลตามคำสั่ง เมื่อประมวลผลเสร็จก็จะส่งผลลัพธ์กลับไปที่ Server จากนั้น Server ก็จะส่งผลลัพธ์ต่อไปยัง Client อีกทีหนึ่ง

ทั้งหมดนี้เป็นเพียงแค่ตัวอย่างบางส่วนของการใช้งาน
  Gearman ยังมีความสามารถ อีกหลายๆอย่าง อาทิเช่น การใช้งานในรูปแบบ Asynchronous (ฝั่ง client เมื่อส่งงานไปที่ Job Server แล้ว สามารถ switch ไปทำงานอย่างอื่นต่อได้ทันที ไม่ต้องรอผลลัพธ์) ซึ่งทั้งหมดนี้คุณสามารถศึกษาเพิ่มเติมได้จาก web ของ Gearman

source: http://gearman.org

1 comment:

  1. ยกตัวอย่างเห็นภาพเลยค่ะ เข้าใจง่ายขึ้นเลย ^^

    ReplyDelete