ประสิทธิภาพของ Apache ลดลงอย่างมากเกินกว่าคำขอ 256 ~ พร้อมกัน


14

ฉันใช้ไซต์ที่มีปริมาณการใช้งานค่อนข้างต่ำซึ่งมีผู้คนจำนวนมากเข้ามาเยี่ยมชมสัปดาห์ละครั้งหลังจากที่มีการอัปเดตไซต์ ในช่วงนี้ประสิทธิภาพของเว็บไซต์แย่มากเมื่อเทียบกับส่วนที่เหลือของสัปดาห์ โหลดจริงบนเซิร์ฟเวอร์ยังคงต่ำมากเชื่อถือได้ต่ำกว่า 10% CPU และต่ำกว่า 30% RAM (ฮาร์ดแวร์ควร overkill เสร็จสมบูรณ์สำหรับสิ่งที่เราทำจริง ๆ ) แต่ด้วยเหตุผลบางอย่าง Apache ดูเหมือนไม่สามารถรับมือกับปริมาณ ของคำขอ เรากำลังเรียกใช้ apache 2.2.3 บน RHEL 5.7, เคอร์เนล 2.6.18-274.7.1.el5, x86_64

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

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:       15   25   5.8     24      37
Processing:    15   65  22.9     76      96
Waiting:       15   64  23.0     76      96
Total:         30   90  27.4    100     125

Percentage of the requests served within a certain time (ms)
  50%    100
  66%    108
  75%    111
  80%    113
  90%    118
  95%    120
  98%    122
  99%    123
 100%    125 (longest request)

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

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:       13  195 692.6     26    3028
Processing:    15   65  21.3     72     100
Waiting:       15   65  21.3     71      99
Total:         32  260 681.7    101    3058

Percentage of the requests served within a certain time (ms)
  50%    101
  66%    108
  75%    112
  80%    116
  90%    121
  95%   3028
  98%   3040
  99%   3044
 100%   3058 (longest request)

ผลลัพธ์เหล่านี้สอดคล้องกันมากในหลาย ๆ การทดสอบ เนื่องจากมีทราฟฟิกอื่น ๆ เข้ามาที่กล่องนั้นฉันไม่แน่ใจอย่างแน่นอนว่าจะมีการตัดทอนอย่างหนักถ้ามี แต่ดูเหมือนว่าจะใกล้ถึง 256 อย่างน่าสงสัย

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

<IfModule prefork.c>
StartServers     512
MinSpareServers  512
MaxSpareServers  512
ServerLimit      512
MaxClients       512
MaxRequestsPerChild  5000
</IfModule>

mod_status ยืนยันว่าตอนนี้ฉันกำลังใช้งาน 512 เธรดที่มีอยู่

8 requests currently being processed, 504 idle workers

อย่างไรก็ตามการพยายามคำขอ 265 คำขอพร้อมกันยังคงให้ผลลัพธ์ที่เหมือนกันเกือบทั้งหมดมาก่อน

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:       25  211 714.7     31    3034
Processing:    17   94  28.6    103     138
Waiting:       17   93  28.5    103     138
Total:         57  306 700.8    138    3071

Percentage of the requests served within a certain time (ms)
  50%    138
  66%    145
  75%    150
  80%    161
  90%    167
  95%   3066
  98%   3068
  99%   3068
 100%   3071 (longest request)

หลังจากกำจัดเอกสาร (และการแลกเปลี่ยนสแต็ค) ฉันอยู่ที่การสูญเสียสำหรับการตั้งค่าเพิ่มเติมเพื่อพยายามที่จะแก้ไขปัญหาคอขวดนี้ มีบางอย่างที่ฉันขาดหายไปหรือไม่? ฉันควรเริ่มหาคำตอบนอกเหนือจาก apache หรือไม่ มีคนอื่นเห็นพฤติกรรมนี้อีกไหม ความช่วยเหลือใด ๆ ที่จะได้รับการชื่นชมอย่างมาก.

แก้ไข:

ตามคำแนะนำของ Ladadadada ฉันวิ่งแข่งกับอาปาเช่ ฉันลองกับ -tt และ -T สองสามครั้งและหาอะไรผิดปกติ จากนั้นฉันพยายามใช้ strace -c กับกระบวนการ apache ที่กำลังทำงานอยู่ทั้งหมดและได้สิ่งนี้:

% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 22.09    0.317836           5     62128      4833 open
 19.91    0.286388           4     65374      1896 lstat
 13.06    0.187854           0    407433           pread
 10.70    0.153862           6     27076           semop
  7.88    0.113343           3     38598           poll
  6.86    0.098694           1    100954     14380 read

( ... abdridged)

ถ้าฉันอ่านสิ่งนี้ถูกต้อง (และอดทนกับฉันเพราะฉันไม่ได้ใช้ strace บ่อยนัก) ไม่มีการเรียกของระบบใด ๆ ที่สามารถใช้เวลาที่คำขอเหล่านี้ใช้ ดูเหมือนว่าคอขวดจะเกิดขึ้นก่อนที่คำขอจะไปที่เธรดผู้ปฏิบัติงาน

แก้ไข 2:

อย่างที่หลายคนแนะนำผมก็ทำการทดสอบอีกครั้งบนเว็บเซิร์ฟเวอร์เอง (ก่อนหน้านี้การทดสอบนั้นรันจากตำแหน่งอินเทอร์เน็ตที่เป็นกลาง) ผลลัพธ์น่าประหลาดใจ:

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0   11   6.6     12      21
Processing:     5  247 971.0     10    4204
Waiting:        3  245 971.3      7    4204
Total:         16  259 973.3     21    4225

Percentage of the requests served within a certain time (ms)
  50%     21
  66%     23
  75%     24
  80%     24
  90%     26
  95%   4225
  98%   4225
  99%   4225
 100%   4225 (longest request)

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

เรียกใช้การทดสอบอีกครั้งจากเครื่องอื่นในเครือข่ายท้องถิ่นเดียวกันกับโฮสต์ Apache ฉันเห็นผลลัพธ์ที่สมเหตุสมผลมากขึ้น:

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        1    2   0.8      2       4
Processing:    13  118  99.8    205     222
Waiting:       13  118  99.7    204     222
Total:         15  121  99.7    207     225

Percentage of the requests served within a certain time (ms)
  50%    207
  66%    219
  75%    220
  80%    221
  90%    222
  95%    224
  98%    224
  99%    225
 100%    225 (longest request)

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


ตัวเลือกที่ต้องพิจารณา: CloudFlare, drupal.org/project/boost , CDN, Varnish cache
ceejayoz

คุณไม่ได้บอกอะไรเราเกี่ยวกับสิ่งที่เซิร์ฟเวอร์นี้กำลังทำ (จริง) นอกเหนือจากการให้บริการคำขอ HTTP มีฐานข้อมูล (หรือบางแหล่งข้อมูลทั่วไปอื่น ๆ ที่อาจประสบจากการช่วงชิงล็อก) ที่เกี่ยวข้อง? หากปัญหาที่เกิดขึ้นอย่างกระทันหันที่ตรง 256 คำขอ (OK ที่ 255) อาจมีบางทรัพยากรภายนอกถูกล้นมือ (การกระโดดของคุณที่ให้บริการหน้าคงที่นั้นผิดปกติเช่นกัน - ดูคำตอบของ Ladadadada สำหรับเคล็ดลับการแก้จุดบกพร่องที่นั่น)
voretaq7

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

voretaq7: ฉันเริ่มคิดตามบรรทัดเดียวกันเหล่านี้เนื่องจากคำขอทั่วไปจะเกี่ยวข้องกับ php / mysql แต่ปัญหายังคงอยู่ที่เกณฑ์เดียวกันแม้ว่าจะให้บริการเนื้อหาคงที่ทั้งหมด
cmckendry

1
นี่เป็นเซิร์ฟเวอร์จริงหรือ VM หรือไม่ คุณทำการทดสอบจาก localhost เครือข่ายท้องถิ่นหรืออินเทอร์เน็ตหรือไม่? เวลาตอบสนองน้อยที่สุดในช่วง 100ms แนะนำการทดสอบจากอินเทอร์เน็ต ลองทดสอบจาก localhost - บางทีผู้ให้บริการของคุณอาจควบคุมปริมาณคุณ
Tometzky

คำตอบ:


4

สิ่งที่ฉันจะทำในสถานการณ์นี้คือการทำงาน

strace -f -p <PID> -tt -T -s 500 -o trace.txt

ในหนึ่งในกระบวนการ Apache ของคุณระหว่างการทดสอบ ab จนกว่าคุณจะได้รับการตอบสนองช้า trace.txtจากนั้นได้ดูผ่าน

-ttและ-Tตัวเลือกให้คุณ timestamps ของการเริ่มต้นและระยะเวลาของแต่ละสายระบบเพื่อช่วยระบุคนที่ช้า

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


ความคิดที่ดีดูที่-cตัวเลือก คุณแน่ใจหรือไม่ว่าเด็ก Apache ที่คุณกำลังติดตามเสิร์ฟอย่างน้อยหนึ่งคำขอช้าในช่วงเวลานั้น (ฉันไม่แน่ใจด้วยซ้ำว่าคุณจะทำสิ่งนี้อย่างไรนอกเหนือจากการวิ่งstraceพร้อมกันในเด็กทุกคน)

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

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


ดูผลลัพธ์จากab:

การกระโดดอย่างฉับพลันในเวลาตอบสนอง (ดูเหมือนไม่มีเวลาตอบสนองที่ใดก็ได้ระหว่าง 150ms และ 3000ms) แสดงให้เห็นว่ามีการหยุดพักชั่วคราวเกิดขึ้นที่ไหนสักแห่งที่ได้รับการกระตุ้นโดยการเชื่อมต่อ 256 รอบพร้อมกัน คาดว่าจะมีการลดลงอย่างราบรื่นหากคุณใช้ RAM หรือ CPU หมดวงจร IO ปกติ

ประการที่สองการabตอบสนองช้าแสดงว่า 3000ms ใช้ในconnectเฟส เกือบทั้งหมดใช้เวลาประมาณ 30 มิลลิวินาที แต่ 5% ใช้เวลา 3000 มิลลิวินาที สิ่งนี้ชี้ให้เห็นว่าเครือข่ายเป็นปัญหา

คุณabมาจากที่ไหน คุณลองจากเครือข่ายเดียวกันกับเครื่อง Apache ได้ไหม

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

มันอาจคุ้มค่าที่จะดูบันทึกของอุปกรณ์เครือข่ายที่คุณสามารถเข้าถึงได้ ฉันเพิ่งพบปัญหากับหนึ่งในไฟร์วอลล์ของเราที่สามารถจัดการแบนด์วิดท์ในรูปของ kb / s แต่มันไม่สามารถจัดการจำนวนแพ็กเก็ตต่อวินาทีที่ได้รับ มันมียอดแพ็คเก็ต 140,000 ต่อวินาที คณิตศาสตร์ที่รวดเร็วในการabวิ่งของคุณทำให้ฉันเชื่อว่าคุณจะได้เห็นแพ็กเก็ตประมาณ 13,000 ต่อวินาที (ไม่สนใจคำขอที่ช้า 5%) บางทีนี่อาจเป็นปัญหาคอขวดของคุณ ความจริงที่ว่าสิ่งนี้เกิดขึ้นประมาณ 256 อาจเป็นเรื่องบังเอิญอย่างหมดจด

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