Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Ruby

การปรับขนาด Ruby บน Rails เพื่อการเติบโตของผู้ใช้จำนวนมาก

วันนี้เราจะเจาะลึกกลยุทธ์บางอย่างที่คุณสามารถใช้เพื่อปรับขนาดแอปพลิเคชัน Ruby on Rails ให้มีฐานผู้ใช้จำนวนมาก

วิธีหนึ่งที่ชัดเจนในการปรับขนาดแอปพลิเคชันคือการทุ่มเงินให้กับพวกเขามากขึ้น และมันทำงานได้ดีอย่างน่าอัศจรรย์ — เพิ่มเซิร์ฟเวอร์อีกสองสามตัว อัปเกรดเซิร์ฟเวอร์ฐานข้อมูลของคุณ และ voila ปัญหาด้านประสิทธิภาพมากมายก็แค่ poof !

แต่บ่อยครั้งก็สามารถปรับขนาดแอปพลิเคชันได้โดยไม่ต้องเพิ่มเซิร์ฟเวอร์เพิ่มเติม นั่นคือสิ่งที่เราจะพูดคุยในวันนี้

ไปกันเลย!

ใช้ AppSignal สำหรับแอปพลิเคชัน Rails ของคุณ

ก่อนที่เราจะเจาะลึกเรื่องการปรับขนาดและการเพิ่มประสิทธิภาพ คุณต้องระบุ ถ้า ก่อน คุณต้องดำเนินการนี้ ปัญหาคอขวดในแอปพลิเคชันของคุณคืออะไร และทรัพยากรใดที่สามารถปรับขนาดได้

วิธีง่ายๆ วิธีหนึ่งในการทำเช่นนี้คือใช้การตรวจสอบประสิทธิภาพของ AppSignal และหน่วยวัดสำหรับ Ruby

แดชบอร์ดประสิทธิภาพช่วยให้คุณระบุการดำเนินการของตัวควบคุมและงานเบื้องหลังที่แน่นอนได้ซึ่งโดยเฉลี่ยจะช้า

ตัวอย่างเช่น นี่คือลักษณะของแดชบอร์ดประสิทธิภาพสำหรับ ActiveRecord:

การปรับขนาด Ruby บน Rails เพื่อการเติบโตของผู้ใช้จำนวนมาก

นี่เป็นจุดเริ่มต้นที่ดีในการปรับขนาด ไม่ว่าคุณจะตัดสินใจเพิ่มเซิร์ฟเวอร์หรือเพิ่มประสิทธิภาพการทำงานผ่านโค้ดก็ตาม

ตอนนี้เรามาดูหนึ่งในเทคนิคที่ง่ายที่สุดที่คุณสามารถใช้เพื่อปรับขนาดแอป Rails ของคุณ นั่นก็คือ การแคช

การแคชใน Ruby on Rails

การแคชช่วยให้คุณหยุดการคำนวณสิ่งเดิมซ้ำแล้วซ้ำอีก

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

มาดูทรัพยากรที่เป็นไปได้ทั้งหมดที่สามารถแคชได้

การแคชมุมมอง

บางครั้งการแสดงผลมุมมองอาจเป็นการดำเนินการที่มีราคาแพง โดยเฉพาะอย่างยิ่งเมื่อมุมมองนั้นมีข้อมูลจำนวนมากที่จะแสดงผล แม้ว่าการดำเนินการจะไม่แพง แต่การใช้มุมมองที่แสดงผลล่วงหน้าจะทำให้คุณได้รับประสิทธิภาพอย่างมาก แทนที่จะแสดงผลมุมมองเดียวกันนั้นล้านครั้ง

Rails รองรับสิ่งนี้ทันทีโดยใช้ 01 ดูผู้ช่วย ตัวอย่างเช่น นี่คือวิธีที่สามารถแคชแต่ละโพสต์เมื่อแสดงรายการ:

 

ด้วยเหตุนี้ Rails จะแคชแต่ละโพสต์โดยอัตโนมัติภายใต้คีย์เฉพาะซึ่งขึ้นอยู่กับเนื้อหา HTML ของเทมเพลต รหัสโพสต์ และการประทับเวลาอัปเดต

หากต้องการอ่านเพิ่มเติมเกี่ยวกับเทคนิคนี้ โปรดดูโพสต์ การแคชแฟรกเมนต์ในการแคชคอลเลกชัน Rails และ Rails

สิ่งหนึ่งที่ควรจำไว้ก็คือคีย์แคชไม่มีเนื้อหาเทมเพลตที่ซ้อนกัน ดังนั้นหากคุณซ้อนการเรียกแคชลึกกว่าหนึ่งระดับ อาจมีผลลัพธ์เก่า อ่านเพิ่มเติมเกี่ยวกับสิ่งนี้ในการแคชตุ๊กตารัสเซียใน Rails

การตอบกลับแคช

นอกเหนือจากการแคชมุมมอง/แฟรกเมนต์แล้ว คุณยังสามารถเลือกที่จะแคชการตอบสนองแบบเต็มของ 15 คำขอ สิ่งนี้ได้รับการสนับสนุนผ่าน 28 และ 30 ส่วนหัวที่ส่งมาจากเบราว์เซอร์

เมื่อ 47 มีส่วนหัวอยู่ในคำขอ เซิร์ฟเวอร์สามารถส่งคืน 50 ตอบกลับโดยไม่มีเนื้อหาหากไม่มีการเปลี่ยนแปลงการตอบสนอง 68 ที่คำนวณโดยเซิร์ฟเวอร์ ถูกเปรียบเทียบกับค่าภายในส่วนหัวนั้น

ในทำนองเดียวกัน หาก 78 ส่วนหัวปรากฏโดยไม่มี 83 เซิร์ฟเวอร์สามารถส่งคืน 91 ตอบกลับโดยไม่มีเนื้อหา (ตราบใดที่การตอบกลับไม่มีการเปลี่ยนแปลงนับตั้งแต่วันนั้น)

Rails มีวิธีง่ายๆ ในการดำเนินการนี้ภายในการทำงานของคอนโทรลเลอร์ คุณสามารถเขียน:

 

Rails จะส่งส่วนหัวที่จำเป็นทั้งหมดเพื่อรองรับการแคช จัดการส่วนหัวที่เข้ามา และตอบกลับด้วย 304 เมื่อข้อมูลไม่มีการเปลี่ยนแปลง เซิร์ฟเวอร์สามารถข้ามการเรนเดอร์มุมมองแบบเต็มอีกครั้งได้ เว้นแต่จะมีการเปลี่ยนแปลง คุณสามารถอ่านเพิ่มเติมเกี่ยวกับการกำหนดค่าขั้นสูงสำหรับกลยุทธ์นี้ได้ในการแคชฝั่งไคลเอ็นต์ใน Rails:คำขอ GET แบบมีเงื่อนไข

ค่าการแคช

สุดท้ายนี้ ยังสามารถแคชค่าดิบได้ (อะไรก็ตามที่สามารถทำให้เป็นอนุกรมไปยังที่เก็บแคชได้) โดยปกติแล้วจะมีประโยชน์ในการแคชผลลัพธ์ของการดำเนินการที่ใช้ทรัพยากรมากหรือช้า และหลีกเลี่ยงการดำเนินการเหล่านั้นอีก

การระบุค่าที่จะได้ประโยชน์จากแคชนี้จะขึ้นอยู่กับแอปพลิเคชันเป็นอย่างมาก แต่โดยปกติแล้ว การดูเหตุการณ์ที่ช้าที่สุดสามารถช่วยชี้แนะทิศทางที่ถูกต้องให้คุณได้

สุดท้ายนี้ เมื่อคุณระบุสิ่งที่ควรแคช API ที่ Rails จัดเตรียมไว้ให้นั้นใช้งานง่ายมาก:

 

โค้ดด้านบนจะเป็น 101 เพียงครั้งเดียว จากนั้นแคชค่าภายใต้ 119 ที่สำคัญ ครั้งถัดไปที่มีการเรียกรหัสเดียวกัน Rails จะตรวจสอบก่อนว่าเรามีค่าแคชอยู่แล้วหรือไม่ และใช้ค่านั้นแทนการทริกเกอร์ 123 อีกครั้ง

ส่วนที่สำคัญที่สุดของกลยุทธ์การแคชนี้คือการคำนวณคีย์แคชที่ดีซึ่งขึ้นอยู่กับอินพุตทั้งหมดที่ใช้ในการคำนวณของค่า นี่เป็นเพื่อให้แน่ใจว่าเราจะไม่ใช้ค่าเก่าอีกต่อไป

ร้านค้าแคช

ตอนนี้เรารู้แล้วว่าต้องแคชอะไรและเทคนิคที่ Rails มีให้เพื่อจัดเก็บสิ่งต่าง ๆ ในแคช คำถามเชิงตรรกะถัดไปคือ เราจะแคชข้อมูลนี้ที่ไหน Rails มาพร้อมกับอะแดปเตอร์เก็บแคชในตัวหลายตัว ที่เก็บแคชที่ได้รับความนิยมมากที่สุดสำหรับกรณีการใช้งานจริงคือ Redis และ Memcached มีตัวเลือกอื่นๆ อีกสองสามตัวเลือกเช่นกัน — ที่เก็บไฟล์และที่เก็บหน่วยความจำ การอภิปรายแบบเต็มของร้านค้าเหล่านี้สามารถพบได้ในร้านค้าแคชในตัวของโพสต์ Rails:ภาพรวม

ที่เก็บไฟล์และหน่วยความจำอาจเหมาะอย่างยิ่งสำหรับการพัฒนาเพื่อให้สิ่งต่าง ๆ ทำงานได้รวดเร็ว อย่างไรก็ตาม โดยปกติแล้วสิ่งเหล่านี้ไม่เหมาะกับการใช้งานจริง โดยเฉพาะอย่างยิ่งหากคุณทำงานในการตั้งค่าแบบกระจายที่มีเซิร์ฟเวอร์หลายเครื่อง ทั้ง Redis และ memcached เหมาะสำหรับการใช้งานจริง โดยปกติแล้วคุณจะใช้อันไหนขึ้นอยู่กับแอปพลิเคชัน

ผู้ปฏิบัติงานพื้นหลังใน Ruby on Rails

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

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

ตัวอย่างการใช้งาน

ในการรันงานที่กำหนดเอง Rails จัดเตรียมเฟรมเวิร์กงานที่ใช้งานอยู่ มาดูกันว่าเราจะใช้มันเพื่อย้ายตรรกะการกรองที่ซับซ้อนมากไปยังงานเบื้องหลังได้อย่างไร ขั้นแรก มาสร้างงานพื้นหลังของเรากัน:

 

เราสามารถรันงานนี้ได้จากคอนโทรลเลอร์ดังนี้:

 

เราจำเป็นต้องแสดงตัวบ่งชี้การโหลดบนเทมเพลตของเราในขณะที่เรารองานของเราในการคำนวณข้อมูลและส่งมอบผลลัพธ์

แต่เราจะเอาผลงานของเรามาสู่มุมมองได้อย่างไร? Turbo ทำให้เรื่องนี้ง่ายมาก ตัวอย่างเช่น ภายในมุมมอง เราสามารถสมัครรับเหตุการณ์เทอร์โบสตรีมในช่องการแจ้งเตือนเฉพาะได้โดยใช้ 132 .

ใช้สิ่งนี้ มาเขียนเทมเพลตของเรา:

 
 

เนื่องจากข้อมูลไม่ได้ถูกกำหนดไว้ในการดำเนินการเริ่มต้นของคอนโทรลเลอร์ เราจะเรนเดอร์เฉพาะตัวบ่งชี้การโหลดเท่านั้น ตอนนี้เรามาส่งมอบผลลัพธ์จากงานของเรา:

 

ส่วนสำคัญที่นี่คือ 147 วิธีการ ใช้ Turbo::StreamsChannel ออกอากาศเหตุการณ์การแทนที่ไปที่ 151 สตรีมการแจ้งเตือนที่เราสมัครรับข้อมูลจากมุมมองของเรา

นั่นคือทุกสิ่งที่เราต้องการเพื่อย้ายการดำเนินการที่ซับซ้อนจากคอนโทรลเลอร์ไปยังงานเบื้องหลัง ข้อได้เปรียบหลักของการย้ายงานไปยังเบื้องหลังก็คือผู้ปฏิบัติงานในเบื้องหลังสามารถปรับขนาดได้อย่างอิสระจากเว็บเซิร์ฟเวอร์ สิ่งนี้ทำให้ทรัพยากรบนเว็บเซิร์ฟเวอร์มีอิสระมากขึ้น สำหรับผู้ใช้ อินเทอร์เฟซดังกล่าวยังให้ความรู้สึกตอบสนองมากกว่ามาก เนื่องจากเราสามารถตอบสนองได้อย่างรวดเร็วและให้ผลลัพธ์ทีละน้อย

หมายเหตุ :หากคุณต้องการความช่วยเหลือในการตัดสินใจเลือกระหว่างคนทำงานเบื้องหลัง โปรดอ่าน งานล่าช้า กับ Sidekiq:ไหนดีกว่ากัน

การปรับขนาดฐานข้อมูลในแอปพลิเคชัน Ruby on Rails ของคุณ

ทรัพยากรที่ปรับขนาดได้สุดท้ายที่เราจะกล่าวถึงในโพสต์นี้คือฐานข้อมูล ฐานข้อมูลเป็นแกนหลักของแอปพลิเคชันส่วนใหญ่ เมื่อข้อมูลและจำนวนเซิร์ฟเวอร์ที่เข้าถึงข้อมูลนั้นเพิ่มขึ้น ฐานข้อมูลก็เริ่มรู้สึกถึงภาระ

วิธีที่ง่ายที่สุดในการปรับขนาดฐานข้อมูลคือการเพิ่มพลังการประมวลผลและหน่วยความจำให้กับเซิร์ฟเวอร์ฐานข้อมูล การดำเนินการนี้กับฐานข้อมูลมักจะเป็นการดำเนินการที่ช้ามาก ซึ่งต่างจากการปรับขนาดเว็บเซิร์ฟเวอร์ โดยเฉพาะอย่างยิ่งหากคุณมีพื้นที่จัดเก็บข้อมูลสูง

ตัวเลือกที่สองในการปรับขนาดฐานข้อมูลคือการปรับขนาดในแนวนอนโดยใช้หลายฐานข้อมูลหรือโดยการแบ่งฐานข้อมูลของคุณ ตรวจสอบฐานข้อมูลหลายรายการที่มี Active Record เพื่อดูรายละเอียดเพิ่มเติมเกี่ยวกับเรื่องนี้

แต่เราจะมุ่งเน้นไปที่การเพิ่มประสิทธิภาพฐานข้อมูลของคุณโดยดูที่ PostgreSQL แทน

ค้นหาคำค้นหาที่ใช้เวลานานใน PostgreSQL

ขั้นแรก เราต้องระบุข้อความค้นหาที่ใช้เวลานานที่สุดของเรา วิธีที่เราสามารถทำได้คือการสืบค้น 166 ตารางที่มีสถิติเกี่ยวกับคำสั่ง SQL ทั้งหมดที่ดำเนินการบนเซิร์ฟเวอร์ มาดูกันว่าเราจะค้นหาคำค้นหา 100 อันดับแรกที่มีเวลาทำงานสูงสุดได้อย่างไร:

 

ซึ่งจะส่งคืนแบบสอบถาม จำนวนการโทร และเวลาดำเนินการโดยเฉลี่ยของแบบสอบถามเหล่านี้ พยายามค้นหาอันที่คุณคิดว่าเร็วกว่าและวิเคราะห์ว่าทำไมมันถึงช้า

คุณยังสามารถเรียกใช้ 177 ได้ หรือ 186 ในการสืบค้นเพื่อดูแผนการสืบค้นและรายละเอียดการดำเนินการจริงตามลำดับ

สิ่งสำคัญที่สุดประการหนึ่งที่ต้องระวังในผลลัพธ์คือ 198 ซึ่งบ่งชี้ว่า Postgres ต้องผ่านบันทึกทั้งหมดตามลำดับเพื่อเรียกใช้แบบสอบถาม หากสิ่งนี้เกิดขึ้น ให้ลองข้ามการสแกนตามลำดับนั้นโดยการเพิ่มดัชนีลงในคอลัมน์ที่คุณกรองไว้

ตารางที่มีการสแกนตามลำดับมากที่สุด

แบบสอบถามที่มีประโยชน์อีกประการหนึ่งที่ฉันชอบเรียกใช้คือการค้นหาจำนวนการสแกนตามลำดับทั้งหมดที่รันกับตาราง:

 

หากคุณเห็นตารางที่มีขนาดใหญ่มาก (มีจำนวนแถวสูง) และค่าการนับสูงจากผลลัพธ์นี้ แสดงว่าคุณกำลังประสบปัญหา ลองตรวจสอบคำค้นหาทั้งหมดเทียบกับตารางนั้น ค้นหาคำค้นหาที่สามารถเรียกใช้การสแกนตามลำดับ และเพิ่มดัชนีเพื่อสรุปรายละเอียด

การใช้ดัชนี

คุณยังสามารถค้นหาสถิติเกี่ยวกับการใช้ดัชนีได้โดยการเรียกใช้แบบสอบถามนี้:

 

ซึ่งจะส่งกลับเปอร์เซ็นต์ของการใช้ดัชนีสำหรับแต่ละตาราง ตัวเลขที่ต่ำหมายความว่าคุณขาดดัชนีบางส่วนในตารางนั้น

สรุป

ในโพสต์นี้ เราได้สำรวจกลยุทธ์ต่างๆ เพื่อปรับขนาดแอปพลิเคชัน Ruby on Rails ของคุณ รวมถึงแคชและผู้ทำงานเบื้องหลัง นอกจากนี้เรายังดูการเพิ่มประสิทธิภาพฐานข้อมูล PostgreSQL ของคุณอีกด้วย

Rails ทำให้การเพิ่มประสิทธิภาพหลายชั้นให้กับแอปพลิเคชันของคุณเป็นเรื่องง่ายมาก

ข้อพิจารณาที่สำคัญที่สุดเกี่ยวกับความสามารถในการปรับขยายได้คือการระบุปัญหาคอขวดในแอปพลิเคชันก่อนที่เราจะดำเนินการแก้ไขได้ เครื่องมือตรวจสอบประสิทธิภาพที่ดีสามารถช่วยได้ หากคุณต้องการ โปรดดู AppSignal สำหรับ Ruby

ขอให้สนุกกับการเขียนโค้ด!

ปล. หากคุณต้องการอ่านโพสต์ Ruby Magic ทันทีที่เผยแพร่ สมัครรับจดหมายข่าว Ruby Magic ของเราและไม่พลาดแม้แต่โพสต์เดียว!