งาน cron การเก็บขยะของ Ubuntu สำหรับเซสชัน PHP ใช้เวลา 25 นาทีทำไม?


13

Ubuntu มีการตั้งค่างาน cron ซึ่งค้นหาและลบเซสชัน PHP เก่า:

# Look for and purge old sessions every 30 minutes
09,39 *     * * *     root   [ -x /usr/lib/php5/maxlifetime ] \
   && [ -d /var/lib/php5 ] && find /var/lib/php5/ -depth -mindepth 1 \
   -maxdepth 1 -type f -cmin +$(/usr/lib/php5/maxlifetime) ! -execdir \
   fuser -s {} 2> /dev/null \; -delete

ปัญหาของฉันคือกระบวนการนี้ใช้เวลานานมากในการรันพร้อมดิสก์ IO จำนวนมาก นี่คือกราฟการใช้งาน CPU ของฉัน:

กราฟการใช้งาน CPU

การล้างข้อมูลจะถูกแสดงด้วยเดือยแหลม เมื่อถึงต้นงวดงานการล้างข้อมูลของ PHP จะถูกกำหนดเวลาเริ่มต้นที่ 09 และ 39 นาที เวลา 15:00 น. ฉันลบเวลา 39 นาทีออกจาก cron ดังนั้นงานล้างข้อมูลสองครั้งขนาดจะทำงานครึ่งหนึ่งบ่อยครั้ง (คุณสามารถเห็นจุดสูงสุดกว้างสองเท่าและครึ่งบ่อยครั้ง)

นี่คือกราฟที่สอดคล้องกันสำหรับเวลา IO:

เวลา IO

และการทำงานของดิสก์:

การทำงานของดิสก์

ที่จุดสูงสุดที่มีการใช้งานประมาณ 14,000 เซสชันการล้างข้อมูลสามารถเห็นได้ว่าทำงานเต็ม 25 นาทีซึ่งเห็นได้ชัดว่าใช้ 100% ของหนึ่งคอร์ของ CPU และสิ่งที่ดูเหมือนจะเป็น 100% ของดิสก์ IO ตลอดระยะเวลา เหตุใดทรัพยากรจึงเข้มข้นมาก lsไดเรกทอรีเซสชั่น/var/lib/php5ใช้เวลาเพียงเศษเสี้ยวของวินาที เหตุใดจึงใช้เวลา 25 นาทีในการตัดแต่งเซสชันเก่า มีอะไรที่ฉันสามารถทำได้เพื่อเร่งความเร็วนี้หรือไม่?

ระบบไฟล์สำหรับอุปกรณ์นี้กำลัง ext4 ซึ่งทำงานบน Ubuntu Precise 12.04 64- บิต

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


เว็บไซต์ของคุณมีปริมาณการใช้งานมากเพียงใดในการสร้างเซสชันจำนวนมาก?
Michael Hampton

คำตอบ:


9

การลบออกfuserจะช่วยได้ งานนี้รันfuserคำสั่ง (ตรวจสอบว่าไฟล์ถูกเปิดอยู่ในปัจจุบัน) สำหรับทุกไฟล์ที่พบซึ่งอาจใช้เวลาหลายนาทีในระบบไม่ว่างที่มีเซสชัน 14k นี่เป็นข้อผิดพลาด Debian (Ubuntu ขึ้นอยู่กับ Debian)

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


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

นั่นคือข้อผิดพลาดอื่น คุณมีปัญหาง่ายๆในการเริ่มต้นfuserกระบวนการนับพันซึ่งทุกคนต้องค้นหาไฟล์ทั้งหมดที่/proc/เปิดอยู่
Tometzky

9

ขอแสดงความยินดีที่มีเว็บไซต์ยอดนิยมและจัดการเพื่อให้มันทำงานบนเครื่องเสมือนได้ตลอดเวลา

หากคุณกำลังดึงจริงๆในสองล้านหน้าเว็บต่อวันแล้วคุณกำลังจะไปกองขึ้นมากของการประชุม PHP ในระบบแฟ้มและพวกเขากำลังจะต้องใช้เวลานานในการลบไม่ว่าคุณจะใช้fuserหรือrmหรือ เครื่องดูดฝุ่น.

ณ จุดนี้ฉันขอแนะนำให้คุณค้นหาวิธีอื่นในการจัดเก็บเซสชันของคุณ:

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

Memcached เป็นตัวเลือกแน่นอนแม้ว่ามันจะต้องเป็นกลุ่มที่แยกต่างหากจากอินสแตนซ์ memcached หลักของเรามิฉะนั้นเซสชันจะถูกขับไล่แบบสุ่มจากแรงกดดันแคชของเรา ฉันไม่เชื่อว่าการลบ 14,000 ไฟล์ควรใช้เวลา 25 นาที ฟังดูช้าไปสำหรับฉัน ฉันจะรอสองสามชั่วโมงและดูว่าการแสดงของคนเรียบง่ายrmเป็นอย่างไร
thenickdude

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

คุณสามารถรวมพูลเซิร์ฟเวอร์ Memcached สำหรับความซ้ำซ้อนโดยการตั้งค่า memcache.session_redundancy = 2 ดูserverfault.com/questions/164350/... Redis เป็นตัวเลือกที่ดีถ้าคุณกังวลเกี่ยวกับการคงอยู่และเร็วกว่าที่เก็บฐานข้อมูล SQL
jfountain

4

ดังนั้นตัวเลือกที่เก็บข้อมูลเซสชัน Memcached และฐานข้อมูลที่แนะนำโดยผู้ใช้ที่นี่เป็นตัวเลือกที่ดีในการเพิ่มประสิทธิภาพโดยแต่ละตัวเลือกมีข้อดีและข้อเสียต่างกันไป

แต่จากการทดสอบประสิทธิภาพฉันพบว่าค่าใช้จ่ายมหาศาลในการบำรุงรักษาเซสชั่นนี้เกือบจะเรียกได้ว่าfuserเป็นงาน cron นี่คือกราฟประสิทธิภาพหลังจากเปลี่ยนกลับไปเป็นงาน Natty / Oneiric cron ซึ่งใช้rmแทนfuserการตัดแต่งเซสชันเก่าการเปลี่ยนแปลงเกิดขึ้นในเวลา 2:30 น.

การใช้งาน CPU

เวลา IO ที่ผ่านไป

การทำงานของดิสก์

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

(งาน IO ที่ไม่เกี่ยวข้องทำงานที่ 05:00 และงาน CPU ทำงานที่ 7:40 ซึ่งทั้งคู่ทำให้เกิด spikes ของตัวเองบนกราฟเหล่านี้)

งาน cron ที่แก้ไขแล้วที่ฉันกำลังทำงานอยู่คือ:

09 *     * * *     root   [ -x /usr/lib/php5/maxlifetime ] && \
   [ -d /var/lib/php5 ] && find /var/lib/php5/ -depth -mindepth 1 \
   -maxdepth 1 -type f -cmin +$(/usr/lib/php5/maxlifetime) -print0 \
   | xargs -n 200 -r -0 rm

-print0 | xargs ...ไม่จำเป็น - คุณสามารถออกไปจากที่-deleteนั่นได้ แต่มันจะทำงานทั้งสองวิธีด้วยความเร็วที่เทียบเท่ากัน
Tometzky

1

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

ในสถานการณ์ที่อธิบายไว้ OP กำลังใช้ ext4 ไดเรกทอรีใน ext4 จัดเก็บข้อมูลไฟล์ในรูปแบบฐานข้อมูล htree ซึ่งหมายความว่ามีผลกระทบเล็กน้อยในการเก็บไฟล์จำนวนมากในไดเรกทอรีเดียวเมื่อเทียบกับการกระจายข้ามไดเรกทอรีไดเรกทอรี สิ่งนี้ไม่เป็นความจริงสำหรับระบบไฟล์ทั้งหมด ตัวจัดการเริ่มต้นใน PHP อนุญาตให้คุณใช้หลายไดเรกทอรีย่อยสำหรับไฟล์เซสชัน (แต่โปรดทราบว่าคุณควรตรวจสอบว่ากระบวนการควบคุมซ้ำลงในไดเรกทอรีเหล่านั้น - งาน cron ด้านบนไม่ได้)

ค่าใช้จ่ายในการดำเนินการจำนวนมาก (หลังจากลบการเรียกไปยังฟิวเซอร์) เกิดจากการดูไฟล์ที่ยังไม่เก่า การใช้ (ตัวอย่าง) ไดเรกทอรีย่อยระดับเดียวและงาน 16 cron ที่ค้นหาในแต่ละไดเรกทอรีย่อย (0 /, 1 /, ... d /, e /, f /) จะทำให้การโหลดเกิดขึ้นอย่างราบรื่น

การใช้ตัวจัดการเซสชันแบบกำหนดเองกับวัสดุพิมพ์ที่เร็วขึ้นจะช่วยได้ - แต่มีให้เลือกมากมาย (memcache, redis, ซ็อกเก็ตตัวจัดการ mysql ... ) โดยเว้นช่วงคุณภาพของสิ่งที่เผยแพร่บนอินเทอร์เน็ตซึ่งคุณเลือกขึ้นอยู่กับ ข้อกำหนดเกี่ยวกับแอปพลิเคชันโครงสร้างพื้นฐานและทักษะของคุณอย่าลืมว่ามีความแตกต่างในการจัดการซีแมนทิกส์ (โดยเฉพาะการล็อค) เมื่อเปรียบเทียบกับตัวจัดการเริ่มต้น


0

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

http://www.dotdeb.org/2008/08/25/storing-your-php-sessions-using-memcached/

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

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