NodeJS ตอนที่ 2 [V8 และ Non Blocking I/O]

Google V8

V8 เป็น Engine ที่สร้างโดย Google ด้วยภาษา C++ ใช้คอมไฟล์ JavaScript ให้เป็น Byte Code ซึ่งช่วยให้ JavaScript ทำงานได้เร็วขึ้นมาก

เมื่อเรา Complie NodeJS จะเป็น Byte code อยู่ในหน่วยความจำ ซึ่งคอมพิวเตอร์เข้าใจทำให้ทำงานได้เร็ว

การคอมไพล์เราได้ลองทำในตอนที่ 1 ดังนี้

node ch1_hello.js

เมื่อเราดำเนินการทำตามคำสั่ง ดังกล่าว ชุดคำสั่ง byte code นั้นจะถูกสร้างเป็น process ไว้ในหน่วยความจำ

 

processเมื่อคอมไพล์เสร็จ หากเราลบไฟล์ ch1_hello.js ออก โปรแกรมที่รันอยู่ก็ยังสามารถทำงานได้ เพราะอยู่ในหน่วยความจำแล้ว

ในส่วนรายละเอียดการทำงานเชิงลึกของ V8 Engine คงไม่ได้กล่าวถึงเพราะคงมีน้อยคนนักที่จะลงไปศึกษาระดับสถาปัตยกรรม ส่วนใหญ่ก็ศึกษาเพื่อเขียนโปรแกรมเป็นหลัก หากใครสนใจสามารถศึกษาเพิ่มเติมได้ที่ https://developers.google.com/v8/?hl=th

Blocking I/O

สำหรับพื้นฐานการทำงานของคอมเตอร์นั้น มีอยู่ 3 ส่วนหลักๆ คือ

  • Input การป้อนข้อมูลจากอุปกรณ์ต่างๆ เช่น คีย์บอร์ด เมาส์ ปากกา เว็บแคม
  • Central Processing หน่วยประมวลผลกลาง หน่วยความจำ
  • Output อุปกรณ์แสดงผล เช่น จอ เครื่องพิมพ์

com_architect

รูปที่ 1 พื้นฐานสถาปัตยกรรมคอมพิวเตอร์

คำว่า I/O ก็มาจาก Input / Output ก็คือการไหลของข้อมูลตั้งแต่ Input ไป Output สิ่งที่ผู้ดูแลระบบสนใจจาก I/O ได้แก่

  • มีการส่งข้อมูลขนาดเท่าไร
  • ใช้ความเร็วเท่าไร
  • มีข้อผิดพลาดหรือไม่

เมื่อเราพูดถึงคำว่า Blocking I/O ก็คืออาการที่ข้อมูลระหว่าง I/O เกิดการบล็อคขึ้น มันคืออะไร เราจะมาค่อยๆทำความเข้าใจกัน

หากย้อนกลับไปดูรูป 1 ตั้งแต่เส้นทางของข้อมูลที่เข้ามาตั้งแต่ Input จนออกไป Output ได้ อุปกรณ์ที่มักจะคอขวดมากที่สุดก็คือ Harddisk เพราะเราเก็บข้อมูลใน Harddisk และเรียกใช้ข้อมูลจาก Software หรือไฟล์ต่างๆอยู่เสมอ หากใช้ Disk ที่อ่านช้าก็มีโอกาสเจออาการ Blocking I/O สูง

อาการ Blocking I/O เป็นอย่างไร ?

ถ้าเราเล่นเกมส์ หรือ โปรแกรมที่ใช้ทรัพยากรเครื่องสูง อ่านดิสต์หนัก ในจังหวะที่เราใจร้อน ทำการเปลี่ยนหน้าต่างไปยังอีกโปรแกรม แล้วหน้าจอใหม่ยังโผล่มา แล้วหน้าต่างเดิมก็ยังไม่ย่อหรือสลับไปด้านหลังสักที อาการประมาณนั้นแหละที่เรียกว่า Blocking I/O

ในการเขียนโปรแกรมก่อนที่จะมี Asynchronouse

เราเขียนโปรแกรมด้วยการทำงานเป็นลำดับ เช่น

  • functionA();
  • functionB();
  • functionC();

การเขียนโปรแกรมแบบนี้จะทำคำสั่งตามลำดับ A , B , C

หากเขียนโปรแกรมกับเทคโนโลยีประเภท Non Blocking I/O ก็จะใช้หลักการเขียนโปรแกรมแบบ Asynchronous

ซึ่งการเขียนโปรแกรมเรียงคำสั่งเป็นลำดับ แต่อาจจะไม่เสร็จตามลำดับก็เป็นได้ B อาจจะเสร็จก่อน C และ A

ซึ่งการเขียนโปรแกรมแบบ Asynchronous จะทำให้คำสั่งถ้ดมาจาก A คือ B และ C ไม่ถูกบล็อก เมื่อเรียก A ก็ไล่มา B และ C ส่วนอันไหนจะเสร็จก่อนก็อยู่ที่ปลายตอบกับอันไหนก่อน ซึ่งรายละเอียดเราจะมาศึกษาภายหลัง

NodeJS Blocking I/O

จากที่เคยทำโหลดเทส และดูผลจากหลายๆเว็บ การทำงานของ NodeJS จะรับชุดคำสั่งมาเก็บไว้ก่อน และจะตวรจสอบ I/O ว่าพร้อมรับการทำงานของชุดคำสั่งนั้นๆหรือไม่ ถ้าไม่พร้อมก็จะวนลูปไปก่อน เมื่อถึงรอบมาตรวจสอบ I/O และทำคำสั่งนั่นๆ ก็จะทำให้ Node สามารถรับชุดคำสั่งจากภายนอกได้มากกว่าเทคโนโลยีที่เป็น Blocking I/O และระบบก็เพิ่มความสเถียรขึ้น ล้มยาก เพราะไม่ส่งชุดคำสั่งไปยังอุปกรณ์ที่ยังไม่พร้อม

รูปที่ 2 โครงสร้างสถาปัตยกรรมของ NodeJS

หากเปรียบเทียบ NodeJS กับชีวิตประจำวัน ก็คล้ายๆ Couter Service ที่อาจจะมีพนักงานเท่าเดิม แต่ปรับเปลี่ยนวิธีการทำงาน ให้มีการรับบัตรคิวก่อน ทำให้สามารถรับผู้มาใช้บริการได้มากขึ้นกว่าการรอให้เสร็จทีละคน

พบกับตอนที่ 3 JavaScript Basic for Node และการเขียนโมดูล เร็วๆนี้