Performance Tactics

“คนส่วนใหญ่ศึกษาเทคโนโลยีก่อนแก้ปัญหา, architect ที่ดีเลือก design principle, tactic และ pattern เพื่อใช้แก้ปัญหา แล้วค่อยศึกษาเทคโนโลยี…”

ใครๆ ก็อยากให้ระบบทำงานเร็ว ตอบสนองเร็ว ตัวชี้วัดหลักๆ ของ performance มีหลายตัว อาทิ response time (เวลาตอบสนอง), latency time (เวลาหน่วง), throughput (ปริมาณงานที่เสร็จ), miss rate (อัตรางานที่พลาด), jitter (ความคลาดเคลื่อนเล็กๆ น้อยๆ)

หากมองในมุม outside-in ผู้ใช้หรือระบบภายนอกต้องการ performance อย่างไรจากระบบของเรา… ก็ความเร็วไง หากมองในมุม inside-out ทีมพัฒนาจะทำอย่างไรให้ระบบมี performance… ก็ให้ระบบประมวลผลให้เร็วๆ และใช้ทรัพยากรให้มีประสิทธิภาพ…

หากอยากให้ระบบทำงานเร็ว จงจำไว้ว่าให้ออกแบบระบบก่อน ไม่ใช่ซื้อของก่อน!!! และไม่ใช่เขียนโปรแกรมก่อน แล้วค่อยมาจูนทีหลัง โดยเฉพาะมาจูนเอาช่วงท้ายโครงการ หรือหลังเริ่มใช้งานสักพักจนเจอปัญหาระบบช้า มันสายไปแล้ว สายเกินเยียวยา สายเกินที่จะแก้ไขด้วย ‘ดีไซน์’ และสุดท้ายที่องค์กรจำนวนมากจบโศกนาฎกรรมนี้ด้วยการแก้ด้วย ‘เงิน’ เป็นวิถีปฏิบัติแบบทุนนิยมจริงๆ

ผมเห็นระบบในองค์กรจำนวนมาก พอช้าหน่อยเวนเดอร์ก็สมคบคิดกับผู้บริหาร จะแบบเต็มใจหรือไม่นั่นอีกเรื่อง แล้วจบด้วยการแก้ด้วยเงิน อัพเกรด infrastructure อัพเกรดเครื่อง อัพเกรดเน็ตเวิร์ก เพิ่มเครื่อง และเดี๋ยวนี้ไลเซนส์ซอฟต์แวร์หลายระบบมันแพงยิ่งกว่าเครื่องเซิร์ฟเวอร์เสียอีก หลายองค์กรก็เสร็จเวนเดอร์ ไว้ใจเวนเดอร์มากไปหน่อยเลยโดนวางยา หลายกรณีก็เกิดจากการขาดทักษะความรู้ด้าน performance ของทีมพัฒนาเองด้วย

ควรออกแบบสถาปัตยกรรมซอฟต์แวร์หรือระบบไอทีเสียก่อน เอาแนวคิด Test-Driven Development (TDD) มาใช้ ออกแบบได้โซลูชั่นแล้วก็รีบทำ prototype หรือทำ test จะได้รู้ว่าช้าหรือเร็ว หากช้าจะได้รีบแก้แต่เนิ่นๆ ไม่ใช่เขียนโค้ดไปเยอะแล้ว หรือเริ่มใช้งานไปเป็นเดือนๆ แล้วค่อยมาแก้ แล้วจะมีใครจะมีกะจิตกะใจอยากกลับไปแก้ดีไซน์กันบ้างล่ะ?

ปัญหา performance จริงๆ ไม่ใช่เริ่มที่งานออกแบบ แต่มันเริ่มตั้งแต่ requirement โน่นเลย requirement นี่ตัวดี เก็บ performance requirement ไม่ง่าย ยากมากและจุกจิก ยิ่งระบบขนาดใหญ่ access resource เยอะๆ หลากหลาย ยิ่งเก็บยาก และการจะทำให้ system performance ดี ควรวิเคราะห์ business performance (หาได้จากการวิเคราะห์ business process) ก่อน และหาก business performance ไม่ดี ก็ต้องจูนกันตั้งแต่ business performance โน่น ไม่งั้นต่อให้ system performance ดีอย่างไร แต่ business ไม่ปรับตัวก็แก้ไม่หายขาด

การจัดการด้าน performance ยังต้องอาศัยทักษะด้านเศรษฐศาสตร์ด้วย การเข้าใจ demand (ความต้องการใช้ทรัพยากร) และ supply (การจัดสรรทรัพยากร) แต่ประเด็นคือ แล้วตอนต้นของการออกแบบหรือเก็บ requirement จะทราบได้อย่างไรว่าระบบมันต้องการใช้ทรัพยากรอะไร? และ เท่าไหร่? นั่นคือต้องเก็บ performance requirement เป็นไงครับ แล้วรีบออกแบบหาโซลูชั่น แล้วต้องใช้ TDD เข้าช่วย เพื่อรีบ test ตั้งแต่เนิ่นๆ สำหรับ performance test ที่ทำๆ กันส่วนมาก มักได้ผลทดสอบออกมาฟลุ้กๆ คือ ทดสอบผ่าน แต่พอเอาเข้าจริงใช้งานจริงดันช้า และพาระบบร่วงจนล่ม กลายเป็น performance ร่วงจนไปฉุดเอา availability ร่วงไปด้วย ที่ฟลุ้กทดสอบผ่าน สาเหตุหลักๆ คือ จำลอง test data และ test environment ผิด ซึ่งทั้ง 2 สิ่งนี้สำคัญ ถ้าไม่จำลองให้ใกล้เคียงสถานการณ์จริง ก็ test ไปก็เท่านั้น แล้วยิ่งเป็นโครงการจัดซื้อ/จัดจ้าง โดยให้เวนเดอร์เป็นคน test แล้วใครจะหน้าโง่คิด test case ยากๆ ให้ตัวเอง test ไม่ผ่านกันล่ะ… ขณะที่บ้านเรามีคนมีความเข้าใจและมีทักษะออกแบบ test case และทำ test กันจริงๆ น้อยมาก

การแก้ปัญด้าน performance เป็นสิ่งที่สนุกมาก จุกจิก หยุมหยิม ตัวเลขเยอะ คำนวณเยอะ เทคนิคจัดจ้าน และต้องรู้ลึกมาก ทั้งซอฟต์แวร์ ฮาร์ดแวร์ เน็ตเวิร์ก… แต่ไม่ใช่แก้คนเดียว เพราะปัญหาด้าน performance ต้องร่วมกันแก้ ทั้งภาคธุรกิจ ไอที (ทั้งซอฟต์แวร์ ฮาร์ดแวร์ เน็ตเวิร์ก) โดยมี architect คุมภาพรวม

ก่อนจะเข้า performance tactic ฝากไว้นิดหนึ่งครับว่า… จงเริ่มแก้ปัญหาด้วยการใช้ design principle, tactic และ pattern ก่อน อย่าเริ่มด้วยเทคโนโลยีก่อนเด็ดขาด อย่ามักง่ายด้วยการรีบคิดถึงเทคโนโลยี เพราะโลกนี้มีเทคโนโลยีมากมาย เปลี่ยนก็เร็ว แต่ design principle, tactic และ patttern ใช้ได้ชั่วนาตาปี เพราะมันไม่ค่อยขึ้นกับเทคโนโลยีและภาษาโปรแกรม หากใช้พวกนี้คล่องเมื่อไหร่ เจอระบบอะไรก็ไม่ต้องกลัว เพราะมันปรับประยุกต์กับระบบประเภทต่างๆ ได้ หลายคนที่ผมเจอหรือที่มาเรียนกับผมหรือเป็นลูกค้าผมมักสงสัยว่าแก้ด้วยวิธีการเหล่านี้มันช้า… แก้ด้วยเทคโนโลยีเร็วกว่า… ใช่… ถูกนิดหนึ่ง แต่… หากเราใช้ design principle, tactic และ pattern ชำนาญเมื่อไร จะแก้ปัญหาได้เร็วมาก แถมเราไม่จำเป็นต้องรู้จักทุกเทคโนโลยี ทุกภาษาโปรแกรม ด้วยซ้ำ…

คนส่วนใหญ่ศึกษาเทคโนโลยีก่อนแก้ปัญหา, architect ที่ดีเลือก design principle, tactic และ pattern เพื่อใช้แก้ปัญหา แล้วค่อยศึกษาเทคโนโลยี… เพื่อเลือกเทคโนโลยีที่เหมาะสมโดยใช้ design principle, tactic และ pattern เป็นกรอบ ทำให้ไม่ต้องศึกษาเทคโนโลยีเลอะเทอะมากเกินจำเป็น… อ้าวแล้วคนที่ศึกษาเทคโนโลยีก่อนล่ะ? เขาศึกษามามากพอครอบคลุมกับทุกปัญหาที่จะเจอในอนาคตหรือเปล่า? พวกเขาเห็นอนาคตได้หรือ? คนส่วนมากศึกษาเทคโนโลยีโดยเอาอัตตาตัวเองเป็นที่ตั้งกันทั้งนั้น เช่น ความชอบความสนใจส่วนตัว ความคุ้นเคยกับลักษณะงานที่ทำบ่อยๆ ฯลฯ

มาเริ่มกัน…

ปัจจัยที่มีผลต่อค่า response time:

  • Resource Consumption คือ การบริโภค resource ประเภทต่างๆ ที่ได้กล่าวถึงไปแล้วก่อนหน้านี้
  • Blocked Time คือ ช่วงเวลาที่อยู่ในสถานะถูกบล็อกจากการใช้ resource เนื่องจาก
    • Resource Contention คือ เกิดการแย่งกันเข้าใช้ resource ซึ่งโดยปกติหากยิ่งมี event มากจนทำให้เกิดการแย่งกันเข้าใช้ resource มาก ก็เป็นไปได้ที่ latency ก็จะมากด้วยเช่นกัน ทั้งนี้ทั้งนั้นก็ขึ้นกับการจัดการ scheduling ที่ใช้ด้วย
    • Resource Unavailable คือ เกิดจาก resource ไม่ว่าง ซึ่งการประมวลผลจะดำเนินต่อไม่ได้ หากไม่สามารถเข้าใช้ resource ที่ต้องการได้ โดย resource ไม่ว่างอาจเกิดจาก resource offline หรือคอมโพเน้นต์/อะไหล่/อุปกรณ์เกิดข้อผิดพลาด หรืออาจเกิดจากสาเหตุอื่น ดังนั้นจะต้องสามารถระบุให้ได้ว่า resource ใดที่ไม่ว่างบ้าง อยู่ที่ไหนบ้าง เพราะจะส่งผลต่อ latency โดยรวมทีเดียว
    • Dependency on other computation คือ เกิดจากการประมวลผลที่ต้องหยุดรอผลลัพธ์จากการประมวลผลส่วนอื่น เช่นในการประมวลผลแบบ synchronous หรือเช่น การอ่านข้อมูลจาก 2 แหล่งในแบบ sequential ซึ่งจะทำให้มีค่า latency สูงกว่าการอ่านแบบ parallel

 

Resource Demand คือ การจัดการกับความต้องการใช้ resource แบ่งออกเป็น 2 กลุ่ม คือ Reduce Latency และ Manage Demand

Reduce Latency ด้วยการลดเวลาหน่วง/เวลาแฝง/เวลาดีเลย์ (latency) ได้แก่

Increase Computational Efficiency

  • Increase Computational Efficiency คือ การเพิ่มความสามารถในการประมวลให้สูงขึ้น อาทิ
    • ใช้กับอัลกอริธึม อาทิ ส่วนใดสำคัญมากใช้ resource หนัก ก็ออกแบบอัลกอริธีมให้ดีๆ
    • ใช้กับ resource ที่เกี่ยวกับการประมวลผล เช่น ซีพียู หรือกับฮาร์ดิสก์ เช่น ความเร็วรอบ

Reduce Computational Overhead

  • Reduce Computational Overhead คือ  ลดโอเวอร์เฮดในการประมวลผลลง เนื่องจากหากไม่มีการความต้องการใช้ resource การประมวลผลก็จะน้อยเอง ดังนั้นจุดใดที่จะสามารถลดโอเวอร์เฮดในการประมวลผลลงได้ก็จะช่วยให้ performance ดีขึ้น อาทิ
    • มีระบบหนึ่งมีอ็อบเจ็คต์ต้อง call กันภายในเครื่องเดียวกัน ก็ใช้ local call แทนที่จะใช้ remote call
    • มีระบบหนึ่งใช้ Java ต้องการเก็บค่าในแบบไม่ต้องการแชร์ลง list แทนที่จะเก็บลงอ็อบเจ็คต์ชนิด Vector ที่ต้องเปลืองการจัดการเกี่ยวกับ synchronization ก็มาใช้อ็อบเจ็คต์ชนิด ArrayList แทน
    • การ call กันระหว่างคอมโพเน้นต์ แทนที่จะให้ call กันผ่านตัวกลาง (เช่นผ่าน adapter/façade/proxy) ก็ให้ call กันตรงๆ แบบไม่ผ่านตัวกลาง ซึ่งช่วยลด latency ลงได้ (แต่อาจเกิดปัญหาด้าน modifiability ได้ ซึ่งกรณีนี้ถือเป็นกรณีอมตะนิรันดร์การณ์ทางด้าน tradeoff ระหว่าง modifiability กับ performance)

Reduce Latency ด้วยการจัดการ Event ได้แก่

Manage Event Rate

  • Manage Event Rate คือ การจัดการอัตราของ event ที่จะถูกประมวลผล เพราะหาก event ลดลง ก็อาจทำให้การใช้ resource ลดลง ซึ่งจะทำได้อาจต้องมีการ monitor อัตราของ event เพื่อติดตามสถานะ อาทิ
    • จัดการการเข้าจังหวะ(synchronization) ระหว่างแต่ละ event ให้เป็นระเบียบ จะได้เกิดความคล่องตัว ไม่แย่ง ไม่ชนกัน
    • ลดจำนวน event ที่จะเข้าถึง resource ลง เช่น ใช้ filter เพื่อตรวจสอบหรือกรอง request ที่เข้ามา หาก request ไหนไม่ผ่านเกณฑ์ก็จะได้ reject/cancel request ซึ่งจะทำให้จำนวน event ลดลงได้
    • คอนฟิกฯ ให้ระบบรับ request ได้คราวละไม่เกิน 10,000 request หากเกินก็ให้ reject กลับไป  หรือ block request ก่อน เช่นด้วยการเก็บลง buffer พักไว้ก่อน  พอมี request ใดประมวลผลเสร็จค่อย schedule เอา request จากใน buffer เข้าไปประมวลผล

Control Frequency of Sampling

  • Control Frequency of Sampling คือ การควบคุมความถี่ของ request ที่จะเข้าใช้ resource อาทิ
    • request ที่เข้าสู่ระบบให้เอามาจัดเก็บเข้าคิวก่อน แล้วค่อยๆ ดึงเอาไปประมวลผล เพื่อควบคุมความถี่ เช่น การจัดการด้าน message queue server, mail server ซึ่งมีข้อดีต่อด้าน reliability
    • มีราว 20 หน้าจอที่การแสดงผลต้องดึงข้อมูลจังหวัดทั้งหมดมาแสดงบนฟอร์ม วันหนึ่งมีการแสดงผล 20 หน้าจอนี้ประมาณ 100,000 ครั้ง เพื่อลดการประมวลผลการ query ข้อมูล 100,000 ครั้ง ก็ query ข้อมูลมาเก็บไว้ใน cache แทน ทำให้ประมวลผลเหลือแค่ 1 ครั้งเท่านั้น
  • เทคนิคนี้เป็น tradeoff เช่นกรณีความถี่ต่ำมาก request ก็จะรอกันนาน แต่ใช้ I/O ต่ำ, กรณีความถี่สูงก็จะเปลือง I/O และใช้ซีพียูสูงในการประมวลผล scheduling

 

Manage Demand ด้วยการจัดการความต้องการใช้ resource ได้แก่

Bound Execution Times

  • Bound Execution Times คือ การควบคุมเวลาในการใช้ resource อาทิ
    • จำกัดเวลาการใช้ resource
    • ใช้ resource เสร็จแล้วให้รีบ release/disconnect เร็วๆ

Bound Queue Sizes

  • Bound Queue Sizes คือ การควบคุมขนาดคิวที่จัดเก็บ request เพื่อรอถูกดึงไปประมวลผล อาทิ
    • กำหนดขนาดคิวให้เหมาะสมกับอัตราของ event, การประมวลผล และ resource ที่มี/ว่าง
    • การจัดการให้คิวขยายได้ เช่น ขยายอัตโนมัติ, ขยายแบบ manual รวมถึงกำหนด เกณฑ์การขยาย

 

Resource Management คือ การบริหารจัดการทรัพยากร ประกอบด้วย tactic ที่สำคัญได้แก่

Introduce Concurrency

  • Introduce Concurrency คือ การจัดการการเข้าถึง resource ให้เป็นแบบ concurrency หรือ parallel แทนที่จะเป็นแบบ sequential ซึ่งจะทำให้ลด blocked time ลงได้ อาทิ
    • สร้าง thread หลายๆ thread จาก process แล้วให้แต่ละ thread จัดการ(binding + handle) กับ event ที่เกิดขึ้น เพียงแค่นี้ก็เกิด concurrency แล้ว แต่ควรมีการจัดการ load balance ในการที่ thread จะเข้าใช้ resource ด้วย

Maintain Multiple Copies of Either Data or Computations

  • Maintain Multiple Copies of Either Data or Computations คือ การจัดการกับสำเนา (replica) ข้อมูล หรือการประมวลผลหลายๆ สำเนา อาทิ
    • ในระบบแบบ client/server ไคลเอ็นต์ที่กระจายยังที่ต่างๆ ก็คือสำเนาของการประมวลผล ซึ่งช่วยลด contention ลงได้ ซึ่งจุดประสงค์ของการทำสำเนาคือช่วยลด contention นั่นเอง
    • การทำ caching เป็นการทำสำเนาข้อมูล และหากแยกเป็นส่วนๆ ก็ช่วยลด contention ลงได้เช่นกัน
    • หากต้องการจัดการ consistent ของข้อมูลระหว่างใน resource จริงกับใน cache ต้องจัดการ synchronize เพิ่มเติม เพื่อรักษาความถูกต้องและสอดคล้องของข้อมูล

Increase Available Resources

  • Increase Available Resources คือ การทำให้ resource ว่างมากขึ้น หรือใช้ resource ให้เสร็จเร็วขึ้น จะทำให้ช่วยลด latency ลงได้ อาทิ
    • ใช้ซีพียูหรือตัวประมวลผลที่เร็วขึ้น, เพิ่มซีพียูหรือตัวประมวลผล, เพิ่มหน่วยความจำ, เพิ่มแบนด์วิธของเน็ตเวิร์ก หรือทำให้เน็ตเวิร์กเร็วขึ้น
    • ต้องดูเรื่องค่าใช้จ่ายประกอบด้วย หากเพิ่ม resource ให้มากขึ้นจะกระทบต่อค่าใช้จ่ายทันที แม้ว่า resource ที่เพิ่มขึ้น ช่วยให้ลด latency ลงได้ก็ตาม

 

Resource Arbitration คือ การตัดสินคัดเลือกว่าใครจะได้เข้าใช้ resource

  • ต้องมีการจัดการ scheduling ไม่ว่าจะกับส่วนประมวลผล(ซีพียู), buffer, เน็ตเวิร์ก
  • สิ่งที่จะต้องพิจารณาคือ เลือกใช้ scheduling strategy ที่เหมาะสมกับ ลักษณะการใช้ resource
  • Scheduling policy มี 2 ส่วนคือ: การ assign priority และ dispatch
  • เกณฑ์สำคัญที่ต้องพิจารณาต่อการจัดการ scheduling อาทิ
    • การใช้ resource อย่างเหมาะสม
    • ความสำคัญของ request
    • การลดจำนวนการใช้ resource
    • การลด latency
    • การเพิ่ม throughput
    • request ต่างๆ ต้องได้ใช้ resource อย่างเป็นธรรม
    • ฯลฯ
  • นอกจากนี้ต้องคำนึงถึงเรื่อง preemption (การถือครอง resource) ว่าการใช้ resource เป็นแบบ preempt หรือ non-preempt เนื่องจากแบบ preempt สามารถเกิดขึ้นได้ทุกเมื่อ อาทิ เกิดเวลาไหนก็ได้, เกิดในบางสถานการณ์ที่เฉพาะเจาะจง   แต่ในช่วงการประมวลผลไม่สามารถเกิด preempt ได้

First-In/First-Out (FIFO)

  • First-In/First-Out (FIFO) คือ การจัดการคิวนั่นเอง ปัญหาที่เกิดขึ้นได้อาทิ
    • หากระดับความสำคัญ (priority) ของแต่ละ request ไม่เท่ากัน
    • หาก request ที่ถูกเลือกใช้เวลาประมวลผลนาน ทำให้ request ในคิวต้องรอนาน

Fixed Priority Scheduling

  • Fixed Priority Scheduling คือ การกำหนด priority ให้แต่ละ request ตามความเหมาะสม แล้วเลือก request ไปตาม priority ของแต่ละ request  การจัดการกับ priority โดยทั่วไป อาทิ
    • Semantic importance คือ การกำหนด priority แบบ static ให้กับ stream โดยกำหนด priority ตามระดับความสำคัญของงานที่ทำให้เกิด stream
    • Deadline monotonic คือ การกำหนด priority แบบ static โดยกำหนด priority ที่สูงๆ ให้กับ stream ที่มี deadline ที่สั้นก่อน
    • Rate monotonic คือ การกำหนด priority แบบ static ให้กับ stream ที่เข้ามาแบบ periodic โดยกำหนด priority ให้กับ stream ที่มี periodic ที่สั้นก่อน

Dynamic Priority Scheduling

  • Dynamic Priority Scheduling คือ การกำหนด priority แบบไดนามิก อาทิ
    • Round robin คือ การจัดลำดับ request แล้วกำหนด priority ให้ request แล้ว dispatch request ให้เข้าใช้ resource เป็นลำดับสลับวนไปเรื่อยๆ โดยการกำหนดค่า priority จะใช้ช่วงเวลาที่แน่นอน
    • Earliest deadline first คือ การกำหนด priority ให้ request ที่ใกล้จะ deadline ก่อน

Static Scheduling

  • Static Scheduling คือ การจัดการ scheduling แบบวนรอบ (cyclic) ณ จุดที่เกิด preempt โดยจัดลำดับการเลือก request ให้เข้าใช้ resource เป็นแบบ offline (หมายถึง ณ ขณะนั้นไม่ได้ connect กับ resource อยู่)

ใส่ความเห็น

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