การเปิดความคิด
คุณสรุปได้อย่างไรว่าบางส่วนของระบบจะดีขึ้นในภาษาอื่น? คุณกำลังมีปัญหาเรื่องประสิทธิภาพหรือไม่? ปัญหาเหล่านั้นรุนแรงเพียงใด? ถ้าสามารถเร็วกว่าจำเป็นหรือไม่ที่จะเร็วกว่า?
อะซิงโครนัสเธรดเดียว
มีคำถามหลายข้อและแหล่งข้อมูลบนเว็บอื่น ๆ ที่จัดการกับความแตกต่างข้อดีและข้อเสียของการซิงโครนัสแบบเธรดเดี่ยวกับการเกิดพร้อมกันแบบหลายเธรด เป็นเรื่องที่น่าสนใจที่จะอ่านว่าNode.js เป็นอย่างไรแบบอะซิงโครนัสแบบเธรดเดียวเมื่อ I / O เป็นคอขวดที่สำคัญและมีการร้องขอจำนวนมากที่ให้บริการในครั้งเดียว
Twisted, Tornado, และโมเดลอะซิงโครนัสอื่น ๆ ใช้ประโยชน์จากเธรดเดี่ยวได้อย่างยอดเยี่ยม เนื่องจากการเขียนโปรแกรมเว็บจำนวนมากมี I / O จำนวนมาก (เครือข่ายฐานข้อมูล ฯลฯ ) เวลาที่ใช้ในการรอการโทรทางไกลจึงเพิ่มขึ้นอย่างมาก นั่นคือเวลาที่สามารถใช้ในการทำสิ่งอื่น ๆ เช่นเริ่มการเรียกฐานข้อมูลอื่น ๆ การแสดงผลหน้าเว็บและการสร้างข้อมูล การใช้เธรดเดี่ยวนั้นสูงมาก
หนึ่งในผลประโยชน์ที่ยิ่งใหญ่ที่สุดของ asynchrony เดียวด้ายคือการใช้มากหน่วยความจำน้อย ในการดำเนินการหลายเธรดแต่ละเธรดต้องการหน่วยความจำสำรองจำนวนหนึ่ง เมื่อจำนวนเธรดเพิ่มขึ้นจำนวนหน่วยความจำที่ต้องการจึงมีอยู่สำหรับเธรดเท่านั้น เนื่องจากหน่วยความจำมี จำกัด จึงหมายความว่ามีขอบเขตของจำนวนเธรดที่สามารถสร้างได้ในแต่ละครั้ง
ตัวอย่าง
ในกรณีของเว็บเซิร์ฟเวอร์การแกล้งทำเป็นคำขอแต่ละครั้งจะได้รับเธรดของตัวเอง ต้องมีหน่วยความจำ 1MB สำหรับแต่ละเธรดและเว็บเซิร์ฟเวอร์มี RAM 2GB เว็บเซิร์ฟเวอร์นี้จะสามารถประมวลผลคำขอ (ประมาณ) 2000 ครั้งได้ตลอดเวลาก่อนที่จะมีหน่วยความจำไม่เพียงพอที่จะดำเนินการต่อไป
หากการโหลดของคุณสูงกว่านี้อย่างมากคำขอจะใช้เวลานานมาก (เมื่อรอให้คำขอเก่าเสร็จสมบูรณ์) หรือคุณจะต้องเพิ่มเซิร์ฟเวอร์ลงในคลัสเตอร์เพื่อขยายจำนวนคำขอที่เกิดขึ้นพร้อมกัน .
การทำงานพร้อมกันแบบหลายเธรด
การเกิดขึ้นพร้อมกันแบบหลายเธรดอาศัยการดำเนินงานหลายอย่างพร้อมกันแทน นั่นหมายความว่าหากเธรดถูกบล็อกรอการเรียกฐานข้อมูลเพื่อส่งคืนคำขออื่น ๆ สามารถประมวลผลได้ในเวลาเดียวกัน การใช้เธรดต่ำ แต่จำนวนเธรดที่ดำเนินการมีขนาดใหญ่กว่ามาก
โค้ดหลายเธรดก็ยากกว่าที่จะให้เหตุผล มีปัญหาเกี่ยวกับการล็อคการซิงโครไนซ์และปัญหาอื่น ๆ ที่เกิดขึ้นพร้อมกัน อะซิงโครนัสแบบเธรดเดี่ยวไม่ประสบปัญหาเดียวกัน
อย่างไรก็ตามรหัสหลายเธรดนั้นมีประสิทธิภาพมากกว่าสำหรับงานที่ต้องใช้ CPU มาก หากไม่มีโอกาสสำหรับเธรดที่จะ "ให้ผลตอบแทน" - เช่นเดียวกับการโทรผ่านเครือข่ายซึ่งปกติจะปิดกั้น - โมเดลเธรดเดี่ยวจะไม่ได้เกิดขึ้นพร้อมกันใด ๆ
ทั้งสองอยู่ร่วมกันได้
แน่นอนว่ามีการทับซ้อนกันระหว่างสองคน พวกเขาไม่ได้เป็นพิเศษร่วมกัน ตัวอย่างเช่นโค้ดหลายเธรดสามารถเขียนในลักษณะที่ไม่บล็อกเพื่อใช้ประโยชน์จากเธรดแต่ละชุดได้ดียิ่งขึ้น
บรรทัดล่าง
ยังมีอีกหลายประเด็นที่ต้องพิจารณา แต่ฉันชอบคิดเกี่ยวกับสองสิ่งนี้:
- หากโปรแกรมของคุณถูกผูกไว้กับ I / Oดังนั้นการซิงโครไนซ์เธรดเดี่ยวอาจทำงานได้ค่อนข้างดี
- หากโปรแกรมของคุณเชื่อมโยงกับ CPUระบบมัลติเธรดก็น่าจะดีที่สุด
ในกรณีเฉพาะของคุณคุณต้องพิจารณาว่างานอะซิงโครนัสชนิดใดที่เสร็จสมบูรณ์และความถี่ที่งานเหล่านั้นเกิดขึ้น
- พวกเขาจะเกิดขึ้นกับทุกคำขอหรือไม่ ถ้าเป็นเช่นนั้นหน่วยความจำอาจจะกลายเป็นปัญหาเมื่อจำนวนคำขอเพิ่มขึ้น
- สั่งงานเหล่านี้หรือไม่ถ้าเป็นเช่นนั้นคุณจะต้องพิจารณาการซิงโครไนซ์หากใช้หลายเธรด
- งานเหล่านี้มี CPU มากหรือไม่ ถ้าเป็นเช่นนั้นเธรดเดี่ยวสามารถติดตามการโหลดได้หรือไม่?
ไม่มีคำตอบง่ายๆ คุณต้องพิจารณาว่ากรณีการใช้งานของคุณคืออะไรและออกแบบให้เหมาะสม บางครั้งแบบจำลองเธรดเดี่ยวแบบอะซิงโครนัสจะดีกว่า ในบางครั้งจำเป็นต้องใช้จำนวนเธรดเพื่อให้ได้การประมวลผลแบบขนานจำนวนมาก
ข้อควรพิจารณาอื่น ๆ
มีปัญหาอื่น ๆ ที่คุณต้องพิจารณาอีกด้วยแทนที่จะเป็นรูปแบบการทำงานพร้อมกันที่คุณเลือก คุณรู้จัก Erlang หรือ Clojure ไหม คุณคิดว่าคุณสามารถเขียนโค้ดหลายเธรดที่ปลอดภัยในภาษาใดภาษาหนึ่งเหล่านี้เช่นที่คุณปรับปรุงประสิทธิภาพของแอปพลิเคชันของคุณหรือไม่? มันจะใช้เวลานานในการเพิ่มความเร็วในภาษาเหล่านี้และภาษาที่คุณเรียนรู้จะเป็นประโยชน์กับคุณในอนาคตหรือไม่
แล้วปัญหาเกี่ยวกับการสื่อสารระหว่างระบบทั้งสองนี้ล่ะ? มันจะซับซ้อนเกินกว่าที่จะรักษาระบบแยกกันสองระบบพร้อมกันหรือไม่? ระบบ Erlang จะรับงานจาก Django ได้อย่างไร Erlang จะสื่อสารผลลัพธ์เหล่านั้นกลับไปที่ Django อย่างไร ประสิทธิภาพมีความสำคัญเพียงพอสำหรับปัญหาที่ความซับซ้อนที่เพิ่มเข้ามามีค่าหรือไม่?
ความคิดสุดท้าย
ฉันพบเสมอว่า Django รวดเร็วพอและถูกใช้โดยไซต์ที่ถูกค้ามนุษย์จำนวนมาก มีการปรับประสิทธิภาพให้เหมาะสมหลายประการที่คุณสามารถทำได้เพื่อเพิ่มจำนวนคำขอพร้อมกันและเวลาตอบสนอง เป็นที่ยอมรับว่าฉันยังไม่ได้ทำอะไรกับ Celery ในตอนนี้ดังนั้นการเพิ่มประสิทธิภาพตามปกติอาจไม่สามารถแก้ไขปัญหาใด ๆ ที่คุณอาจมีกับงานแบบอะซิงโครนัสเหล่านี้
แน่นอนว่ายังมีข้อเสนอแนะในการทิ้งปัญหาฮาร์ดแวร์เพิ่มเติม ต้นทุนของการจัดเตรียมเซิร์ฟเวอร์ใหม่ราคาถูกกว่าต้นทุนการพัฒนาและบำรุงรักษาระบบย่อยใหม่ทั้งหมดหรือไม่?
ฉันได้ถามคำถามมากเกินไปในตอนนี้ แต่นั่นเป็นความตั้งใจของฉัน คำตอบนั้นจะไม่ง่ายหากไม่มีการวิเคราะห์และรายละเอียดเพิ่มเติม ความสามารถในการวิเคราะห์ปัญหาเกิดขึ้นได้เมื่อรู้ถึงคำถามที่ถาม แต่หวังว่าฉันจะช่วยได้
ความรู้สึกของฉันบอกว่าการเขียนภาษาอื่นไม่จำเป็น ความซับซ้อนและค่าใช้จ่ายอาจจะมากเกินไป
แก้ไข
ตอบสนองต่อการติดตาม
การติดตามของคุณนำเสนอกรณีการใช้งานที่น่าสนใจมาก
1. Django ทำงานนอกคำขอ HTTP
ตัวอย่างแรกของคุณเกี่ยวข้องกับการอ่านแท็ก NFC จากนั้นทำการสืบค้นฐานข้อมูล ฉันไม่คิดว่าการเขียนส่วนนี้ในภาษาอื่นจะเป็นประโยชน์กับคุณเพียงเพราะการสืบค้นฐานข้อมูลหรือเซิร์ฟเวอร์ LDAP กำลังถูกผูกมัดโดยเครือข่าย I / O (และประสิทธิภาพของฐานข้อมูลที่อาจเกิดขึ้น) ในทางกลับกันจำนวนของคำร้องขอที่เกิดขึ้นพร้อมกันจะถูกผูกไว้กับเซิร์ฟเวอร์เนื่องจากแต่ละคำสั่งการจัดการจะถูกเรียกใช้เป็นกระบวนการของตัวเอง จะมีเวลาการตั้งค่าและการฉีกขาดที่ส่งผลต่อประสิทธิภาพเนื่องจากคุณไม่ได้ส่งข้อความไปยังกระบวนการที่กำลังทำงานอยู่ อย่างไรก็ตามคุณจะสามารถส่งคำขอได้หลายรายการพร้อมกันเนื่องจากแต่ละรายการจะเป็นกระบวนการแยก
สำหรับกรณีนี้ฉันเห็นช่องทางสองทางที่คุณสามารถตรวจสอบได้:
- ตรวจสอบให้แน่ใจว่าฐานข้อมูลของคุณสามารถจัดการแบบสอบถามหลายรายการพร้อมกันด้วยการรวมการเชื่อมต่อ (ตัวอย่างเช่น Oracle ต้องการให้คุณกำหนดค่า Django ตามลำดับ
'OPTIONS': {'threaded':True}
) อาจมีตัวเลือกการกำหนดค่าที่คล้ายกันในระดับฐานข้อมูลหรือระดับ Django ที่คุณสามารถปรับแต่งสำหรับฐานข้อมูลของคุณเอง ไม่ว่าคุณจะเขียนคำสืบค้นฐานข้อมูลในภาษาใดคุณจะต้องรอให้ข้อมูลนี้กลับมาก่อนจึงจะสามารถติดไฟ LED ได้ ประสิทธิภาพของรหัสการสืบค้นสามารถสร้างความแตกต่างได้และ Django ORM นั้นไม่เร็วนัก ( แต่มักเร็วพอ)
- ลดเวลาการตั้งค่า / การย่อขนาด มีกระบวนการที่ทำงานอยู่ตลอดเวลาและส่งข้อความถึงมัน (แก้ไขให้ฉันถ้าฉันผิด แต่นี่คือสิ่งที่คำถามดั้งเดิมของคุณกำลังจดจ่ออยู่) กระบวนการนี้เขียนใน Python / Django หรือภาษา / กรอบงานอื่นครอบคลุมอยู่ด้านบนหรือไม่ ฉันไม่ชอบแนวคิดของการใช้คำสั่งการจัดการบ่อยครั้ง เป็นไปได้ไหมที่จะมีโค้ดขนาดเล็กทำงานอยู่ตลอดเวลาซึ่งส่งข้อความจากเครื่องอ่าน NFC ไปยังคิวข้อความซึ่ง Celery อ่านแล้วส่งต่อไปยัง Django หรือไม่ การตั้งค่าและการลดขนาดของโปรแกรมขนาดเล็กแม้ว่าจะเขียนใน Python (แต่ไม่ใช่ Django!) ก็ควรจะดีกว่าการเริ่มต้นและหยุดโปรแกรม Django (พร้อมระบบย่อยทั้งหมด)
ฉันไม่แน่ใจว่าคุณใช้เว็บเซิร์ฟเวอร์ใดสำหรับ Django mod_wsgi
สำหรับ Apache ให้คุณกำหนดจำนวนกระบวนการและเธรดภายในกระบวนการที่ให้บริการร้องขอ โปรดปรับแต่งการกำหนดค่าที่เกี่ยวข้องของเว็บเซิร์ฟเวอร์ของคุณเพื่อปรับจำนวนคำขอที่สามารถให้บริการได้
2. “ Message-through” พร้อมสัญญาณ Django
กรณีใช้งานครั้งที่สองของคุณก็น่าสนใจเช่นกัน ฉันไม่แน่ใจว่าฉันมีคำตอบสำหรับสิ่งนั้นหรือไม่ หากคุณกำลังลบกรณีรูปแบบและความปรารถนาที่จะดำเนินการกับพวกเขาต่อมามันอาจจะเป็นไปได้ที่จะเป็นอันดับพวกเขาJSON.dumps
แล้ว JSON.loads
deserialize มันจะเป็นไปไม่ได้ที่จะสร้างกราฟออบเจ็กต์ใหม่อย่างสมบูรณ์ในภายหลัง (การสอบถามรุ่นที่เกี่ยวข้อง) เนื่องจากฟิลด์ที่เกี่ยวข้องนั้นถูกโหลดจากฐานข้อมูลที่ขี้เกียจและลิงก์นั้นจะไม่มีอยู่อีกต่อไป
ตัวเลือกอื่นจะทำเครื่องหมายวัตถุสำหรับการลบอย่างใดและลบเฉพาะเมื่อสิ้นสุดรอบการร้องขอ / ตอบกลับ (หลังจากสัญญาณทั้งหมดได้รับการบริการ) post_delete
มันอาจจะต้องใช้สัญญาณที่กำหนดเองในการดำเนินการนี้แทนที่จะอาศัย