ฉันใช้ชุดทดสอบโหลดเพื่อตรวจสอบประสิทธิภาพของการตั้งค่าต่อไปนี้:
Node.js test suite (client) --> StatsD (server) --> Graphite (server)
กล่าวโดยย่อชุดทดสอบ node.js จะส่งจำนวนเมตริกที่กำหนดทุก ๆ วินาทีไปยังอินสแตนซ์ StatsD ซึ่งอยู่บนเซิร์ฟเวอร์อื่น จากนั้น StatsD จะล้างข้อมูลเมตริกทุกวินาทีไปยังอินสแตนซ์ Graphite ที่อยู่บนเซิร์ฟเวอร์เดียวกัน จากนั้นฉันดูจำนวนของเมทริกที่ถูกส่งโดยชุดทดสอบจริงและจำนวนของกราไฟต์ที่ได้รับเพื่อตรวจสอบการสูญหายของแพ็คเก็ตระหว่างชุดทดสอบและกราไฟท์
อย่างไรก็ตามฉันสังเกตเห็นว่าบางครั้งฉันก็มีอัตราการส่งแพ็คเก็ตขนาดใหญ่มาก (โปรดทราบว่ามันถูกส่งด้วยโปรโตคอล UDP) ตั้งแต่ 20-50% ดังนั้นเมื่อฉันเริ่มดูว่าแพ็กเก็ตเหล่านี้ถูกทิ้งไปอย่างไรเนื่องจากเป็นปัญหาด้านประสิทธิภาพของ StatsD ดังนั้นฉันจึงเริ่มบันทึกการวัดในทุกส่วนของระบบเพื่อติดตามว่าการลดลงนี้เกิดขึ้นที่ไหน และนี่คือสิ่งที่แปลก
ฉันใช้tcpdumpเพื่อสร้างไฟล์จับภาพซึ่งฉันตรวจสอบหลังจากการทดสอบเสร็จสิ้นแล้ว แต่เมื่อใดก็ตามที่ฉันทำการทดสอบด้วยการรัน tcpdump การสูญเสียแพ็กเก็ตนั้นแทบจะไม่มีเลย! ดูเหมือนว่า tcpdump กำลังเพิ่มประสิทธิภาพการทดสอบของฉันและฉันไม่สามารถหาสาเหตุและวิธีการนี้ได้ ฉันใช้คำสั่งต่อไปนี้เพื่อบันทึกข้อความ tcpdump บนทั้งเซิร์ฟเวอร์และไคลเอนต์:
tcpdump -i any -n port 8125 -w test.cap
ในกรณีทดสอบหนึ่งกรณีฉันส่ง 40000 เมตริก / s การทดสอบในขณะที่รัน tcpdump มีการสูญเสียแพ็คเก็ตประมาณ 4% ในขณะที่การทดสอบโดยไม่ต้องมีการสูญเสียแพ็คเก็ตประมาณ 20%
ทั้งสองระบบกำลังทำงานเป็น Xen VM ด้วยการตั้งค่าต่อไปนี้:
- Intel Xeon E5-2630 v2 @ 2.60GHz
- 2GB RAM
- Ubuntu 14.04 x86_64
สิ่งที่ฉันตรวจสอบแล้วสำหรับสาเหตุที่เป็นไปได้:
- การเพิ่มขนาดการรับ / ส่งบัฟเฟอร์ของ UDP
- ภาระของ CPU ที่มีผลต่อการทดสอบ (โหลดสูงสุด 40-50% ทั้งฝั่งไคลเอ็นต์และฝั่งเซิร์ฟเวอร์)
- รัน tcpdump บนอินเตอร์เฟสเฉพาะแทน 'any'
- รัน tcpdump ด้วย '-p' เพื่อปิดโหมด promiscuous
- รัน tcpdump บนเซิร์ฟเวอร์เท่านั้น ส่งผลให้เกิดการสูญเสียแพ็กเก็ต 20% ที่เกิดขึ้นและดูเหมือนว่าจะไม่ส่งผลกระทบต่อการทดสอบ
- รัน tcpdump บนไคลเอ็นต์เท่านั้น ส่งผลให้ประสิทธิภาพเพิ่มขึ้น
- การเพิ่ม netdev_max_backlog และ netdev_budget เป็น 2 ^ 32-1 เรื่องนี้ไม่ทำให้เกิดความแตกต่าง
- พยายามตั้งค่าโหมด promiscuous ที่เป็นไปได้ทุกรูปแบบ (เปิดเซิร์ฟเวอร์และปิดไคลเอ็นต์ปิดเซิร์ฟเวอร์และเปิดไคลเอนต์ทั้งเปิดและปิด) เรื่องนี้ไม่ทำให้เกิดความแตกต่าง
ifconfig eth0 promisc
เปิดifconfig eth0 -promisc
ใช้งานและปิดใช้งานโหมดที่หลากหลายใน eth0 ถ้ามันสร้างความแตกต่างลองเปรียบเทียบชุด promisc เปิด / ปิดที่เป็นไปได้ทั้ง 4 อย่างบนทั้งสองเครื่อง ที่อาจช่วยระบุสาเหตุของปัญหา
-p
ตัวเลือกเพื่อข้ามการทำเช่นนั้นเพื่อดูว่ามันสร้างความแตกต่างหรือไม่