เราเข้าคิวและจัดลำดับซีเรียลอย่างถูกต้องหรือไม่?


13

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

ลักษณะของข้อความหมายถึงข้อมูลที่ต่อเนื่องของเราสิ้นสุดลงประมาณ 12-15 กิโลไบต์และเราประมวลผลข้อความประมาณ 4 ล้านข้อความต่อสัปดาห์ ข้อความถาวรใน MSMQ นั้นช้าเกินไปสำหรับเราและเมื่อข้อมูลเติบโตขึ้นเราก็รู้สึกกดดันจากไฟล์ที่แม็พหน่วยความจำของ MSMQ เซิร์ฟเวอร์อยู่ที่ 16GB ของการใช้หน่วยความจำและเพิ่มขึ้นเพียงเพื่อรอคิว ประสิทธิภาพยังลดลงเมื่อการใช้หน่วยความจำสูงเนื่องจากเครื่องเริ่มทำการแลกเปลี่ยน เรากำลังทำพฤติกรรมการล้างข้อมูลด้วยตนเองด้วย MSMQ

ฉันรู้สึกว่ามีส่วนหนึ่งที่เราทำผิดที่นี่ ฉันพยายามใช้ RavenDB เพื่อคงข้อความไว้และเพียงรอคิวตัวระบุ แต่ประสิทธิภาพการทำงานนั้นช้ามาก (ดีที่สุด 1,000 ข้อความต่อนาทีอย่างดีที่สุด) ฉันไม่แน่ใจว่าเป็นผลมาจากการใช้รุ่นพัฒนาหรืออะไร แต่เราต้องการปริมาณงานที่สูงขึ้น [1] แนวคิดนี้ทำงานได้ดีในทางทฤษฎี แต่ประสิทธิภาพไม่ได้ขึ้นอยู่กับภารกิจ

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

ดังนั้นคำถามของฉันคือสแต็คที่เหมาะสำหรับการส่งข้อความระหว่างเครื่องที่แยกจากกัน แต่เป็น LAN ในสภาพแวดล้อม C # / Windows ปกติแล้วฉันจะเริ่มต้นด้วย BinaryFormatter แทนที่จะเป็น XML serialization แต่นั่นก็เป็นช่องโหว่ของกระต่ายหากวิธีที่ดีกว่าคือการลดการทำให้เป็นอนุกรมลงในที่เก็บเอกสาร ดังนั้นคำถามของฉัน

[1]: ลักษณะของธุรกิจของเราหมายถึงยิ่งเราประมวลผลข้อความได้เร็วเท่าไหร่เราก็ยิ่งมีรายได้มากเท่านั้น เราได้รับการพิสูจน์เชิงประจักษ์แล้วว่าการประมวลผลข้อความในสัปดาห์ต่อมาหมายความว่าเรามีโอกาสน้อยที่จะทำเงินนั้น ในขณะที่ประสิทธิภาพการทำงานของ "1,000 ต่อนาที" ฟังดูเร็วมาก แต่เราต้องการจำนวนที่สูงกว่า 10k / นาที เพียงเพราะฉันให้ตัวเลขในข้อความต่อสัปดาห์ไม่ได้หมายความว่าเรามีทั้งสัปดาห์ในการประมวลผลข้อความเหล่านั้น

=============== แก้ไข:

ข้อมูลเพิ่มเติม

จากความคิดเห็นฉันจะเพิ่มคำอธิบายบางอย่าง:

  • ฉันไม่แน่ใจว่าการทำให้เป็นอันดับเป็นคอขวดของเรา ฉันได้ทำการเปรียบเทียบแอปพลิเคชั่นและในขณะที่การทำให้เป็นอนุกรมจะปรากฏขึ้นในกราฟความร้อนมีความรับผิดชอบเพียง 2.5-3% ของการใช้งาน CPU ของบริการ

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

  • การเพิ่มแรมเพิ่มเติมเป็นการวัดที่หยุดชั่วคราว เครื่องได้หายไปจาก 4GB -> RAM 16 GB แล้วและมันก็ยากขึ้นที่จะนำมันลงมาเพิ่มอีกเรื่อย ๆ

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

  • รูปแบบการกำหนดเส้นทางดาวนั้นมีความสำคัญอย่างยิ่งต่อแอปพลิเคชันและจะไม่เปลี่ยนแปลง เราไม่สามารถใช้แอปพลิเคชั่นตะขาบได้เพราะทุกชิ้นที่ทำงานแบบอะซิงโครนัส (ในแบบสำรวจ) และเราต้องการรวบรวมพฤติกรรมการลองใหม่ในที่เดียว

  • ตรรกะของแอปพลิเคชันนั้นเขียนด้วย C # วัตถุนั้นเป็น POCO ที่ไม่เปลี่ยนรูปแบบสภาพแวดล้อมการปรับใช้เป้าหมายคือ Windows Server 2012 และเราได้รับอนุญาตให้ตั้งเครื่องเพิ่มเติมหากมีซอฟต์แวร์เฉพาะใน Linux ที่รองรับ

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


ความคิดเห็นได้รับการทำความสะอาดเนื่องจากมีการรวมประเด็นที่เกี่ยวข้องไว้ในคำถาม
ChrisF

มันจะเหมาะสมที่จะแก้ไขปัญหาที่เร่งด่วนที่สุดก่อนที่จะกังวลเกี่ยวกับการสับเปลี่ยนระบบย่อยการจัดคิว ความจริงที่ว่าหน่วยความจำเพิ่มขึ้นจากการควบคุมแสดงให้เห็นว่ายังมีการรั่วไหลบางแห่ง การทำโปรไฟล์หน่วยความจำ (ถ้ามี) ทำอะไร?
Dan Lyons

@DanLyons: การเติบโตของหน่วยความจำเพียงอย่างเดียวคือใน MSMQ ไม่มีใครพูดถึงมันจริงๆ แต่ดูเหมือนว่าเป็นเพราะข้อความที่ไม่ถาวรซึ่งถูกแม็พหน่วยความจำทั้งหมด เนื่องจากเราจัดลำดับข้อมูลจำนวนมากจึงทำให้มีการจัดสรรหน่วยความจำจำนวนมาก หน่วยความจำจะถูกเรียกคืน (ในที่สุด) เนื่องจากมีการใช้ข้อความและการล้างข้อมูลภายในของ MSMQ จะทำงาน
ไบรอัน Boettcher

คำตอบ:


1

ต่อไปนี้เป็นเกณฑ์มาตรฐานของคิวที่คุณอาจสนใจ MSMQ ควรสามารถจัดการข้อความ 10K ต่อวินาที มันอาจจะเป็นปัญหาการกำหนดค่าหรือลูกค้าไม่ได้ติดตามการอ่านคิว? และโปรดสังเกตว่า ZeroMQ นั้นเร็วเพียงใดในการวัดประสิทธิภาพ (ประมาณ 100K ข้อความต่อวินาที) มันไม่ได้มีตัวเลือกการคงอยู่ แต่ควรนำคุณไปยังที่ที่คุณต้องการให้มีประสิทธิภาพ


4

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

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

เราออกแบบคิวที่เราขนานนามVMQueue (สำหรับ Virtual Memory Queue ซึ่งเป็นชื่อที่แย่มากในการย้อนหลัง) ความคิดของคิวนี้คือถ้ากระบวนการผู้บริโภคทำงานได้ถึงระดับกล่าวคือประมวลผลเร็วพอที่จะสามารถรักษาจำนวนองค์ประกอบที่ถูกจัดให้ต่ำกว่าระดับที่กำหนดได้ ตามคิว อย่างไรก็ตามเมื่อผู้บริโภคชะลอตัวลงหรือไม่สามารถใช้งานได้และคิวผู้ผลิตเพิ่มขึ้นถึงขนาดที่แน่นอนแล้วคิวจะเริ่มต้นองค์ประกอบการเพจโดยอัตโนมัติไปยังดิสก์จากดิสก์ (โดยใช้BinaryFormatterการทำให้เป็นอันดับโดยวิธีการ) กระบวนการนี้จะควบคุมการใช้หน่วยความจำอย่างสมบูรณ์และกระบวนการสลับหน้านั้นเร็วหรืออย่างน้อยเร็วกว่าการแลกเปลี่ยนหน่วยความจำเสมือนที่เกิดขึ้นระหว่างการโหลดหน่วยความจำหนัก เมื่อผู้บริโภคจัดการเพื่อระบายคิวต่ำกว่าเกณฑ์มันจะกลับมาทำงานเป็นคิวที่อิงตามหน่วยความจำบริสุทธิ์

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

หากคุณสนใจฉันสามารถแบ่งปันVMQueueรหัสที่มาชั้นเรียนเพื่อให้คุณสามารถเล่นกับมัน คิวจะยอมรับคลาสใด ๆ ที่ทำเครื่องหมายเป็น Serializable เมื่อสร้างคิวคุณจะสร้างขนาดของหน้าในจำนวนองค์ประกอบ อินเทอร์เฟซสำหรับชั้นเรียนจะเหมือนกับคลาสคิวจริง รหัสเก่ามาก (.net 1.1) ดังนั้นจึงไม่มีอินเทอร์เฟซทั่วไปอยู่

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


1

ระบบ HP ProLiant ML350G5ได้รับธุรกรรม 82k ต่อนาที - เช่นมีมากกว่า 8 เท่าที่อัตราการรับส่งข้อมูล "10k / นาที" ที่คุณกล่าวถึง

ประสิทธิภาพการทำงาน: 82,774 tpmC

นอกจากนี้เพื่อความซื่อสัตย์ฉันเพิ่งไปกับ 64 หรือ 128 GB RAM - RAM ราคาถูก Greenspunชี้ให้เห็นถึงความแตกต่างระหว่าง "ขว้างแรมใส่มัน" และ "รับคนที่มีความรู้จาก MIT เพื่อเพิ่มประสิทธิภาพ" และ RAM ก็ชนะ

เขาลงเอยด้วยเครื่อง SQL Server พร้อม RAM 64 GB และเครื่อง front-end จำนวนหนึ่งที่รันหน้า ASP.NET ... เว็บไซต์ swaptree.com จัดการสมาชิกปัจจุบันมากกว่า 400,000 คน (เติบโตอย่างรวดเร็ว) โดยไม่ยาก ...

หมายเหตุ "เครื่องไปถึง RAM ขนาด 16 GB แล้ว" นั้นยังไม่เพียงพอโดยบทความระบุว่าเซิร์ฟเวอร์ที่จัดการกับผู้ใช้ 400k บน RAM 64 GB

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.