5 สาเหตุ ที่ทำให้ Code “ช้าเป็นเต่า”

08-มิ.ย.-18

คัมภีร์เทพ IT

เคยไหม ตอนที่คุณ Run Code ในคอมพิวเตอร์ของคุณเอง มันก็ Run ได้รวดเร็วดี แต่หลังจาก Deploy ออกไปแล้ว Code ของคุณกลับ Run ได้ช้า(มาก) ดังนั้น เรามาดู 5 สาเหตุที่อาจทำให้ Code ของคุณช้า พร้อมวิธีแก้ไขกันดีกว่า ซึ่งเขียนโดย  Andrew C. Oliver

1. มี Thread ขนาดใหญ่เพียงตัวเดียว

ใน Frameworks บางตัว (อย่างเช่น Node.js) ที่มีการจัดการเรื่อง Threads ให้อยู่แล้ว คุณควรจะเรียก Nonblocking I/O calls ที่ถูกต้องในเวลาที่เหมาะสม เพื่อให้ code ส่วนหลักของคุณ clean ถ้าไม่ทำเช่นนั้น จะทำให้ระบบของคุณมีปัญหาเกี่ยบกับ Thread ได้

ถ้าคุณมีปัญหานี้ มันทำให้เกิดคำถามได้ เช่น ถ้าคุณกำลังทำ Algorithm สำคัญภายใน JavaScript ที่ run ใน Node.js แล้ว อาจจะต้องถามตัวคุณเองว่า Node.js และ JavaScript ถือเป็นเทคโนโลยีที่เหมาะสมที่จะใช้ในสถานการณ์นี้หรือไม่? แต่ถ้ามันจำเป็นต้องใช้จริงๆ คุณต้องเรียนรู้เกี่ยวกับวิธีที่ Node.js จัดการกับ Concurrency และวิธีหลีกเลี่ยงการ blocking event loop รวมทั้งคุณจำเป็นต้องเรียนรู้วิธี Submit work ไปยัง Workerpool และคุณอาจต้องเรียนรู้ในเรื่อง Threads อีกด้วย

2. Database ของคุณมีปัญหา

สาเหตุ 1. ขาดการทำ  Index: ถ้าคุณใช้งาน SQL Database คุณควรเรียนรู้การทำงานของ Index เช่น ถ้าคุณมีการกำหนด key/value ใน WHERE clause ถึง 3 อย่าง และใช้งานมันซ้ำแล้วซ้ำเล่าล่ะก็ มันควรจะมี Index ตัวอย่างเช่น 

select … from customer c where c.firstname = :fname and c.lastname = :lname and c.state = :state

จากตัวอย่างนี้ ควรมีถึง 3 Index (ซึ่งมีเหตุผลที่จะทำเช่นนั้นด้วย) แต่อย่างไรก็ตาม มันส่งผลลัพธ์ในเรื่องของ Index merge ด้วย หมายถึง ผลลัพธ์ของการค้นหา 3 รายการ ที่จะถูก  merge เข้าด้วยกัน แทนที่จะพิจารณา Index ที่มีทั้ง 3 fields ใน Index เดียวกัน แต่คำเตือนคือ Index มีแนวโน้มที่จะทำให้การ Insert หรือ Update นั้นช้าลงด้วย

สาเหตุ 2. การ Design Schema ผิด: มีครั้งนึงคุณ Andrew ได้ร่วมงานใน Project ใหญ่ที่ใช้ MongoDB ซึ่งลูกค้าได้ Design Schema ออกมาเหมือนกับมันเป็น RDBMS แต่มันก็ไม่สมเหตุสมผลตรงที่ MongoDB ไม่ได้ถูกออกแบบมาให้ Join Table เพื่อทำสิ่งง่ายๆ อย่างเช่น หาเบอร์โทรศัพท์ ถ้าคุณ Design Schema ที่ไม่ดีตั้งแต่แรก Application ของคุณก็จะใช้งานได้ไม่ดีด้วย ใน Application สมัยใหม่ Developer มีส่วนเกี่ยวข้องในการเลือกฐานข้อมูลเป็นอย่างมาก แต่ไม่ใช่ทุก Application จะทำงานได้ดีกับ Database ทุกประเภท

สาเหตุ 3. เปิด Database connection มากเกินไป: ถ้าคุณมี 1 Database connection pool ซึ่งเปิด 100 connections แต่คุณมี 15 application servers ที่เปิดทั้ง 100 connections นั่นหมายถึง คุณกำลังเปิด 1,500 connections พร้อมๆ กันอยู่ ซึ่งทำแบบนี้ที่อาจไม่ส่งผลดีนัก คุณควรมีความรู้เกี่ยวกับเรื่องนี้ รวมทั้งรู้วิธีจำกัดจำนวน Traffic ให้กับ application servers ในช่วงเวลาที่กำหนดได้

ถ้าสาเหตุของปัญหาเกิดจาก Database คุณควรค้นหามันโดยใช้ Database monitoring tools โดยการบันทึก query return times หรือฟังจาก DBA ว่าสาเหตุว่าเกิดจากอะไรบ้าง คุณควรรู้จัก Database ที่คุณกำลังเขียนอยู่ รวมทั้งในแง่ของของ Schema และแนวทางปฏิบัติ เลือก Database ที่เหมาะสมสำหรับงานนั้นๆ

3. กำหนดขนาด Memory ที่ไม่เหมาะสม

Business Software สมัยใหม่ส่วนใหญ่ มักทำงานบน Stack-based Virtual Machine ตอนนี้เราไม่ได้พูดถึง VMware หรือ Docker แต่เป็นบางอย่างที่คล้ายกับ Java Virtual Machine (JVM) ถ้าเราไม่ต้องเจาะลึกในรายละเอียดเกี่ยวกับการทำงานภายในของ VMs เกือบจะทั้งหมดของพวกมัน จำเป็นต้องใช้ Memory จำนวนหนึ่งที่เรียกว่า heap นอกจากนี้มันยังใช้ memory ประเภทอื่นๆ ด้วยทุกครั้งที่มีการใช้ Threads เมื่อพื้นว่างที่ใน heap เหลือน้อยลง VM เหล่านี้จะเริ่มใช้เวลามากขึ้นเกี่ยวกับการจัดการพื้นที่ heap ซึ่งมีผลทำให้ application ทำงานช้าลงเรื่อยๆ ใน JVM คุณสามารถเปิด garbage-collection logging ได้ ซึ่งมันจะแสดงว่ามี collections ที่กำลัง run อยู่มากแค่ไหน นอกจากนี้คุณยังสามารถเพิ่ม heap size ได้ แต่ต้องทำอย่างระมัดระวังหน่อย

หลายคนคิดว่า Heap เป็นเพียงชนิดของ Memory แต่มันยังมี -xss stack size option ของ JVM ด้วย Threads แต่ละชุดจะได้รับ stack memory ที่แน่นอน และถ้าเมื่อไหร่เกิดเหตุการณ์ที่ memory ไม่มีที่ว่างเหลือ ดังด้านล่าง 

System Memory – (heap + otherstuff + (numthreads * numstack)) i<= 0 

แล้วคุณใช้ Thread อื่น คุณจะได้ out of memory exception ออกมา ขึ้นอยู่กับชนิดของ Library ที่คุณกำลังเรียกใช้อยู่ ซึ่งอาจเป็น thread pool ที่ไม่ expand หรือ database connection pool ที่ไม่ expand ซึ่งทั้งคู่จะมีลักษณะคล้ายกันคือ ทำงานได้ช้าลง แต่ข่าวดีก็คือ เรื่องนี้จะแสดงให้เห็นใน Log

4. กำหนดขนาด Threads และ Connection pools ไม่ถูกต้อง

ถ้าคุณมี Users เข้าใช้งานพร้อมกัน 1,000 รายกับ 5 database connections ใน pool คุณอาจต้องเจอ Wait condition ใน pool นั้น หากคุณมี 100 HTTP Thread และตั้ง TCP backlog ไว้ที่ 5 แล้ว หลังจากมี 105 คนพยายาม Connect คุณจะเห็นข้อความ “connection refused” แต่ก่อนหน้านั้นสิ่งต่างๆ จะช้าไปหมด นอกจากนี้ Software บางตัวยังมี "accept" Threads อยู่เป็นจำนวนหนึ่งซึ่งปกติจะใช้ "ตอบรับ request และส่งต่อไปให้ Thread ตัวอื่นทำงานต่อ" โดยทั่วไปแล้ว อาจจะมี thread ประเภทนี้อยู่ 1 หรือ 2 ตัว ใน application ที่จริงก็ไม่มีกฏที่ตายตัวสำหรับจำนวนที่เหมาะสม แต่มันเป็นเหตุผลเกี่ยวกับเรื่องของสัดส่วน ถ้าคุณยังจำข้อ 3 ได้ ขณะที่ทำสิ่งเหล่านี้เพราะคุณสามารถโดนจำกัดด้วย constrain อื่นได้อีก

5. ไม่ได้กำหนด Limits และ File handles ที่เหมาะสม

ในระบบปฏิบัติการ (OS) ส่วนใหญ่จะมี Limit เกี่ยวกับจำนวน Threads และ File ที่ Users ของระบบปฏิบัติการนั้นสามารถเปิดได้ เพราะถ้าคุณ ใช้จำนวน file หรือ thread จนถึง limit ดังกล่าว ทุกอย่างจะเริ่มช้าลงก่อนที่มันจะ Fail ดังนั้น คุณควรจะดูใน Log ซึ่งจะมี Tools ที่จะแสดงให้เห็นว่า มีไฟล์ไหนที่ถูกล๊อคหรือถูกจัดการ ในขณะที่มันถูกใช้งานอยู่

ที่มา:  https://www.infoworld.com/

 

 

รับตำแหน่งงานไอทีใหม่ๆ ด้วยบริการ IT Job Alert

 

อัพเดทบทความจากคนวงในสายไอทีทาง LINE ก่อนใคร
อย่าลืมแอดไลน์ @techstarth เป็นเพื่อนนะคะ

เพิ่มเพื่อน

 

บทความที่เกี่ยวข้อง