ความเข้าใจในการสร้างไฟล์แบ็คเอนด์เพื่อให้การดาวน์โหลดไฟล์ไคลเอนต์รวดเร็ว

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

ความคิดของฉันในการดำเนินโครงการ:

เช่นเดียวกับที่ไคลเอนต์ดาวน์โหลดไฟล์โดยใช้ตัวจัดการการดาวน์โหลดบางตัว ในทำนองเดียวกัน จะต้องมีตัวจัดการ/รหัส/อัลกอริทึมฝั่งเซิร์ฟเวอร์บางตัว ซึ่งจะอัปโหลด/สร้างไฟล์อย่างรวดเร็วเพื่อให้ไคลเอนต์ดาวน์โหลดไฟล์ ลูกค้าจะต้องไม่ดำเนินการใดๆ ยกเว้นการเลือกไฟล์ที่จะดาวน์โหลด!

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

เซิร์ฟเวอร์ seed/make มีประโยชน์ต่อไฟล์ไปยังไคลเอนต์อย่างไรหากไคลเอนต์ส่งพา ธ เป็นสตริงไปยังเซิร์ฟเวอร์ใน Java เพื่อดาวน์โหลดเท่านั้น

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


person Am_I_Helpful    schedule 28.10.2014    source แหล่งที่มา


คำตอบ (1)


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

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

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

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

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

หากคุณมีไคลเอนต์จำนวนมากที่ดาวน์โหลดจากเซิร์ฟเวอร์ของคุณพร้อมกัน ขีดจำกัดที่คุณอาจจะถึงคือ:

  • ขีดจำกัดอัปสตรีมของผู้ให้บริการของคุณ

  • ความเร็วในการอ่านฮาร์ดไดรฟ์ของคุณ (SSD มี ~ 500MB/s เท่าที่ฉันแจ้ง)

เซิร์ฟเวอร์ของคุณสามารถลองเก็บไฟล์ที่มีการร้องขอบ่อยที่สุดในหน่วยความจำของเขา และให้บริการเนื้อหาจากที่นั่น (DDR3 RAM เข้าถึงความเร็วได้ 17GB/วินาที) ฉันสงสัยว่าคุณมีไฟล์เพียงไม่กี่ไฟล์บนเซิร์ฟเวอร์ของคุณที่คุณสามารถแคชไฟล์ทั้งหมดไว้ใน RAM ของเซิร์ฟเวอร์ของคุณได้

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

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

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


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

person lSoleyl    schedule 08.11.2014
comment
โปรดตรวจสอบสิ่งนี้และตอบกลับ---mailinator.blogspot.in/2008/02/ . หากพอใจ ฉันจะโหวตคำตอบของคุณ และจะมอบรางวัลให้คุณในภายหลัง! - person Am_I_Helpful; 09.11.2014
comment
ฉันไม่มั่นใจกับผลลัพธ์ของพวกเขาจริงๆ ฉันเชื่อว่าพวกเขาวัดผลลัพธ์เหล่านี้ได้จริงๆ และไม่ได้ถูกสร้างขึ้นมา แต่การเขียนโปรแกรมด้วย NIO นั้นซับซ้อนกว่าการใช้ vanilla blocking IO มาก เนื่องจากฉันไม่มีข้อมูลเชิงลึกเกี่ยวกับโค้ดของพวกเขา ฉันจึงไม่สามารถยืนยันได้ว่าการทดสอบเหล่านี้มีความยุติธรรม สิ่งที่สองที่ทำให้ฉันรำคาญคือพวกเขาทำการวัดเฉพาะการเชื่อมต่อที่เกิดขึ้นพร้อมกัน 1,700 รายการเท่านั้น ฉันค่อนข้างมั่นใจว่าการบล็อก IO จะทำให้เกิดปัญหาเมื่อขึ้นไปอีก และมันจะขึ้นไปอีก (ความคิดเห็นถัดไป) - person lSoleyl; 09.11.2014
comment
ดังนั้นตามที่คุณเชื่อมต่อพร้อมกัน 1,700 รายการไม่น่าเชื่อใช่ไหม ฉันอยู่กับพวกเขาเพราะมันดูเหมือนถูกต้องตามกฎหมายเพียงพอและจะไม่มีใครลองเชื่อมต่อมากกว่านี้! - person Am_I_Helpful; 09.11.2014
comment
การตั้งค่าของพวกเขาค่อนข้างสะดวกสำหรับการแสดงให้เห็นว่า IO มีประสิทธิภาพเหนือกว่า NIO ได้ดีเพียงใดโดยการจำกัดการเชื่อมต่อพร้อมกันไว้ที่ 1700 และเพียงการวัดปริมาณงาน แต่ในกรณีของคุณ หากไคลเอนต์จำนวนมากดาวน์โหลดไฟล์พร้อมกันและไฟล์เหล่านี้อาจมีขนาดใหญ่ การเชื่อมต่อแต่ละรายการจะเปิดเป็นเวลานาน อย่างที่ฉันบอกไป ฉันไม่รู้ว่าคุณให้บริการไคลเอนต์ใด แต่ผู้ใช้อินเทอร์เน็ตโดยเฉลี่ยมีขีดจำกัดแบนด์วิธค่อนข้างคร่าวๆ และปริมาณงานไม่ควรเป็นปัญหาหลักของคุณ แต่คุณจะต้องให้บริการการเชื่อมต่อแบบเปิด (ช้า) หลายพันรายการพร้อมกัน และการมีหลายเธรดจะส่งผลต่อประสิทธิภาพของเซิร์ฟเวอร์... - person lSoleyl; 09.11.2014
comment
@shekharsuman เกี่ยวกับความคิดเห็นของคุณ: มันน่าเชื่อสำหรับตัวเลขนั้น ฉันไม่ชอบคำสั่งทั่วไปที่บล็อก IO ดีกว่า NIO ซึ่งเป็นผลมาจากการตั้งค่าเฉพาะอย่างใดอย่างหนึ่ง หากคุณตั้งเป้าที่จะจัดหาเซิร์ฟเวอร์ที่ไม่ได้มุ่งเน้นไปที่การให้บริการลูกค้าหลายพันรายพร้อมกัน การบล็อก IO น่าจะทำได้ดีในกรณีของคุณ - person lSoleyl; 09.11.2014
comment
ขอบคุณครับ ผมจะลองทำตามคำแนะนำดูครับ รางวัลของคุณกำลังรอคุณอยู่! - person Am_I_Helpful; 13.11.2014
comment
คุณอาจสนใจเช่นกัน: ฉันพบงานทางวิทยาศาสตร์จากปี 2011 ซึ่งแสดงให้เห็นว่า แอปพลิเคชัน NodeJS ที่ไม่ปิดกั้นมีประสิทธิภาพเหนือกว่าแอปพลิเคชัน Java และ Scala ด้วยปริมาณข้อความที่สูงกว่าเจ็ดเท่า - person lSoleyl; 17.11.2014