อะไรเป็นสาเหตุให้“ ไม่สามารถจัดสรรหน่วยความจำสำหรับพูล” ใน PHP


133

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

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

คำตอบ:


90

อาจเกี่ยวข้องกับ APC

สำหรับผู้ที่มีปัญหานี้โปรดระบุการตั้งค่า. ini โดยเฉพาะการตั้งค่า apc.mmap_file_mask ของคุณ

สำหรับ mmap ที่สำรองไฟล์ควรตั้งค่าเป็น:

apc.mmap_file_mask=/tmp/apc.XXXXXX

หากต้องการ mmap โดยตรงจาก / dev / zero ให้ใช้:

apc.mmap_file_mask=/dev/zero

สำหรับ mmap ที่รองรับหน่วยความจำแบบแบ่งใช้ที่รองรับ POSIX ให้ใช้:

apc.mmap_file_mask=/apc.shm.XXXXXX

ขอบคุณ! นั่นคือลิงค์ที่ฉันกำลังมองหา ขอบคุณความช่วยเหลือ!
jonathanatx

2
ฉันพบว่าการเปลี่ยนแปลงเหล่านี้ไม่สามารถแก้ไขปัญหาได้เนื่องจากความคิดเห็นในชุดข้อความที่เชื่อมโยงยังมีเอกสาร ...
วันโจนาธา

3
ข้อมูลเพิ่มเติมสำหรับการตั้งค่า APC นี้: php.net/apc.configuration#ini.apc.mmap-file-mask
mikeytown2

2
ในกรณีของฉันฉันต้องเปลี่ยนจาก file-backed เป็น POSIX-compliant เพื่อกำจัดข้อผิดพลาด
Attila Fulop

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

125

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

เพียงอ่านคู่มือเพื่อทำความเข้าใจวิธีใช้ ttl: http://www.php.net/manual/en/apc.configuration.php#ini.apc.ttl

วิธีแก้ปัญหาคือการเพิ่มหน่วยความจำที่จัดสรรให้กับ APC ทำได้โดยเพิ่ม apc.shm_size

ถ้า APC ถูกคอมไพล์เพื่อใช้ Shared Segment Memory คุณจะถูก จำกัด โดยระบบปฏิบัติการของคุณ พิมพ์คำสั่งนี้เพื่อดูขีด จำกัด ระบบของคุณสำหรับแต่ละเซ็กเมนต์:

sysctl -a | grep -E "shmall|shmmax"

หากต้องการจัดสรรหน่วยความจำเพิ่มเติมคุณจะต้องเพิ่มจำนวนเซ็กเมนต์ด้วยพารามิเตอร์ apc.shm_se segment

หาก APC ใช้หน่วยความจำ mmap คุณจะไม่มีขีด จำกัด จำนวนหน่วยความจำยังคงถูกกำหนดโดยอ็อพชัน apc.shm_size เดียวกัน

หากมีหน่วยความจำไม่เพียงพอบนเซิร์ฟเวอร์ให้ใช้ตัวเลือกตัวกรองเพื่อป้องกันไม่ให้ไฟล์ php ที่เข้าถึงบ่อยไม่ถูกแคช

แต่อย่าใช้ TTL เป็น 0

ตามที่ c33s กล่าวไว้ให้ใช้ apc.php เพื่อตรวจสอบ config ของคุณ คัดลอกไฟล์จากแพ็คเกจ apc ไปยังโฟลเดอร์เว็บแล้วชี้เบราว์เซอร์ไปที่มัน คุณจะเห็นว่ามีการจัดสรรอะไรบ้างและใช้อย่างไร กราฟต้องคงที่หลังจากผ่านไปหลายชั่วโมงหากมีการเปลี่ยนแปลงอย่างสมบูรณ์ในการรีเฟรชแต่ละครั้งแสดงว่าการตั้งค่าของคุณผิดพลาด (APC กำลังล้างข้อมูลทุกอย่าง) จัดสรรหน่วยความจำมากกว่าที่ APC ใช้เป็นค่ารักษาความปลอดภัย 20% และตรวจสอบเป็นประจำ

ค่าเริ่มต้นของการอนุญาตเพียง 32MB นั้นต่ำมาก PHP ได้รับการออกแบบเมื่อเซิร์ฟเวอร์มีขนาด 64MB และสคริปต์ส่วนใหญ่ใช้ไฟล์ php หนึ่งไฟล์ต่อหน้า ปัจจุบันโซลูชันเช่น Magento ต้องการไฟล์มากกว่า 10k (~ 60Mb ใน APC) คุณควรอนุญาตให้มีหน่วยความจำเพียงพอเพื่อให้ไฟล์ php ส่วนใหญ่ถูกแคชไว้เสมอ ไม่ใช่เรื่องเสีย แต่การเก็บ opcode ใน ram จะมีประสิทธิภาพมากกว่าการมี php ดิบที่สอดคล้องกันในแคชไฟล์ ทุกวันนี้เราสามารถหาเซิร์ฟเวอร์เฉพาะที่มีหน่วยความจำ 24Gb ได้ในราคาเพียง $ 80 / เดือนดังนั้นอย่าลังเลที่จะอนุญาตหลาย GB ให้กับ APC ฉันใส่ 2GB จาก 24GB บนเซิร์ฟเวอร์ที่โฮสต์ร้านค้า 5Magento และเว็บไซต์ wordpress ~ 40 แห่ง APC ใช้ 1.2GB นับ 64MB สำหรับการติดตั้ง Magento, 40MB สำหรับ Wordpress พร้อมปลั๊กอินบางตัว

นอกจากนี้หากคุณมีเว็บไซต์ developmentpment บนเซิร์ฟเวอร์เดียวกัน แยกออกจากแคช


2
นี้! ฉันใช้ Wordpress และ 32M ก็ไม่เพียงพอ สูงถึง 64M และตอนนี้ชัดเจน ตรวจสอบคน apc.php!
Dave Drager

คำตอบที่ดี! +1 ขอบคุณ
Kostanos

หากต้องการเพิ่มเป็น 64M คุณต้องเพิ่ม apc.shm_size = 64 ไม่ใช่ apc.shm_size = 64M (ตัวอย่างส่วนใหญ่ที่ฉันเคยเห็นมี M ต่อท้าย) ไม่ทำงานกับเวอร์ชัน apc ของฉัน (v3.1.3p1)
Patrick ลืม

1
คุณสมมติว่าคุณจะมีไฟล์แคชจำนวนมากที่อยู่ในแคชนานกว่า TTL c33s มีจุดสำคัญ หากทุกอย่างถูกเข้าถึงเมื่อเร็ว ๆ นี้ (สมมติว่าคุณมี 70% ของแคชที่เข้าถึงได้ตลอดเวลาอย่างที่คุณต้องการและมีการเพิ่มขึ้นอย่างมากซึ่งมีการเพิ่มไฟล์ที่ไม่บ่อยเป็นจำนวนมากในคราวเดียว) คุณจะได้รับข้อผิดพลาด โยนเป็นเวลา TTL วินาที แคชเต็มแล้วและคุณบอก APC ว่าไม่ควรล้างรายการเหล่านี้ดังนั้นจึงบ่น หากคุณมี TTL เป็นเวลา 5 ชั่วโมงคุณจะพบกับข้อผิดพลาด 5 ชั่วโมงที่รอให้ไฟล์ที่ไม่บ่อยเหล่านั้นหมดอายุ
Matthew Kolb

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

36

ทางออกสำหรับฉัน:

  • apc.ttl = 0
  • apc.shm_size = อะไรก็ได้ที่คุณต้องการ

แก้ไขเริ่มต้น

คำเตือน!

@bokan ระบุว่าฉันควรเพิ่มคำเตือนที่นี่

หากคุณมี ttl เป็น 0 หมายความว่าทุกรายการที่แคชไว้จะถูกลบออกทันที ดังนั้นหากคุณมีขนาดแคชเล็ก ๆ เช่น 2mb และ ttl เป็น 0 สิ่งนี้จะทำให้ apc ไร้ประโยชน์เนื่องจากข้อมูลในแคชจะถูกเขียนทับเสมอ

การลด ttl หมายความว่าแคชไม่สามารถเต็มได้เฉพาะกับรายการที่ไม่สามารถแทนที่ได้

ดังนั้นคุณต้องเลือกความสมดุลที่ดีระหว่าง ttl และขนาดแคช

ในกรณีของฉันฉันมีขนาดแคช 1gb ดังนั้นมันจึงมากเกินพอสำหรับฉัน

แก้ไขสิ้นสุด

มีปัญหาเดียวกันใน centos 5 กับ php 5.2.17 และสังเกตว่าหากขนาดแคชเล็กและพารามิเตอร์ ttl "สูง" (เช่น 7200) ในขณะที่มีไฟล์ php จำนวนมากให้แคชแคชจะเต็มเร็วมาก และ apc ไม่พบสิ่งใดที่สามารถลบได้เนื่องจากไฟล์ทั้งหมดในแคชยังคงพอดีกับ ttl

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

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

หวังว่าจะช่วยได้

แก้ไข: ดูเพิ่มเติม: http://pecl.php.net/bugs/bug.php?id=16966

ดาวน์โหลดhttp://pecl.php.net/get/APCแตกไฟล์และเรียกใช้ apc.php ที่นั่นคุณมีแผนภาพที่ดีว่าการใช้แคชของคุณเป็นอย่างไร


2
ขอบคุณสิ่งนี้ช่วยได้ ฉันได้รับข้อผิดพลาด "ไม่สามารถจัดสรรหน่วยความจำ" ประมาณหนึ่งโหลต่อวินาที ฉันเพิ่มขนาดแคชเป็นสองเท่า (32 ถึง 64 MB) และลด ttl เป็น 0 นั่นเป็นการลบข้อผิดพลาดทั้งหมด
nicktacular

1
นี่คือการแก้ไขบนเซิร์ฟเวอร์ของเรา
จัสติน

1
สิ่งนี้ดูเหมือนจะช่วยแก้ปัญหาให้ฉันได้เช่นกัน
anisoptera

1
ใช้ ZWAMP และดูเหมือนจะทำเคล็ดลับเช่นกัน ขอบคุณ.
WernerCD

10
นี่ไม่ใช่วิธีแก้ปัญหา! ข้อผิดพลาดหายไป แต่ APC เกือบจะถูกปิดใช้งาน มันจะล้างแคชทั้งหมดทุกครั้งที่หน่วยความจำเต็ม เพียงแค่อ่านคู่มือของ Brideau ให้เรา php.net/manual/en/apc.configuration.php#ini.apc.ttl
bokan

7

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


1
ตามที่ c33s กล่าวว่า: ดาวน์โหลดpecl.php.net/get/APC extract และเรียกใช้ apc.php มีแผนภาพที่ดีว่าการใช้แคชของคุณเป็นอย่างไร
bokan

4

สำหรับมือใหม่อย่างฉันแหล่งข้อมูลเหล่านี้ช่วย:

ค้นหาไฟล์ apc.ini เพื่อทำการเปลี่ยนแปลงที่แนะนำโดย c33s ด้านบนและกำหนดจำนวนที่แนะนำ: http://www.untwistedvortex.com/optimizing-tuning-apc-alternate-php-cache/

การทำความเข้าใจว่า apc.ttl คืออะไร: http://www.php.net/manual/en/apc.configuration.php#ini.apc.ttl

การทำความเข้าใจว่า apc.shm_size คืออะไร: http://www.php.net/manual/en/apc.configuration.php#ini.apc.shm-size


ขอบคุณคุณชี้ให้เห็นวิธีแก้ปัญหาที่ถูกต้อง การลด TTL ก็เหมือนกับการปิด APC
bokan

4

ดังที่ Bokan ได้กล่าวไว้คุณสามารถเพิ่มหน่วยความจำได้หากมีและเขาก็คิดถูกว่าการตั้งค่า TTL เป็น 0 ที่มีประสิทธิผล

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

ปัญหาที่ฉันพบคือเมื่อฉันเปิดตัวแอปพลิเคชัน PHP เวอร์ชันใหม่ เช่นแทนที่ไฟล์. php ของฉันด้วยไฟล์ใหม่ APC จะโหลดทั้งสองเวอร์ชันลงในแคช

เนื่องจากฉันมีหน่วยความจำไม่เพียงพอสำหรับไฟล์ php สองเวอร์ชัน APC จึงทำให้หน่วยความจำหมด

มีตัวเลือกที่เรียกว่า apc.stat เพื่อบอกให้ APC ตรวจสอบว่าไฟล์ใดไฟล์หนึ่งมีการเปลี่ยนแปลงหรือไม่และหากเปลี่ยนเป็นเช่นนั้นโดยทั่วไปแล้วสิ่งนี้จะใช้ได้สำหรับการพัฒนาเนื่องจากคุณทำการเปลี่ยนแปลงอยู่ตลอดเวลาอย่างไรก็ตามในการผลิตมักจะปิดเหมือนเดิมในของฉัน กรณี - http://www.php.net/manual/en/apc.configuration.php#ini.apc.stat

การเปิด apc.stat จะช่วยแก้ปัญหานี้ได้หากคุณพอใจกับประสิทธิภาพที่ได้รับ

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

define('PROJECT_VERSION', '0.28'); 

if(apc_exists('MY_APP_VERSION') ){

    if(apc_fetch('MY_APP_VERSION') != PROJECT_VERSION){
        apc_clear_cache();
        apc_store ('MY_APP_VERSION', PROJECT_VERSION);
        header('Location: ' . 'http'.(empty($_SERVER['HTTPS'])?'':'s').'://'.$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI']);
        exit;  
    }

}else{
    apc_store ('MY_APP_VERSION', PROJECT_VERSION);
}

2

สิ่งนี้ใช้ได้ผลกับพวกเรา (ใช้งานไซต์ Wordpress จำนวนมากบนเซิร์ฟเวอร์เดียวกัน)

เปลี่ยนการตั้งค่าหน่วยความจำในไฟล์ /etc/php.d/apc.ini มันถูกตั้งค่าเป็น 64M ดังนั้นเราจึงเพิ่มเป็นสองเท่าเป็น 128M

apc.shm_size = 128M


1

การมองไปที่อวัยวะภายในอาจมีสาเหตุหลายประการ ในกรณีของฉันปล่อยให้ทุกอย่างเริ่มต้นยกเว้น ...

apc.shm_size = 64M

... เคลียร์คำเตือนนับไม่ถ้วนที่ฉันได้รับก่อนหน้านี้


1

ฉันได้รับข้อผิดพลาด "ไม่สามารถจัดสรรหน่วยความจำสำหรับพูล" หลังจากย้ายการติดตั้ง OpenCart ไปยังเซิร์ฟเวอร์อื่น ฉันยังลองเพิ่ม memory_limit

ข้อผิดพลาดหยุดลงหลังจากที่ฉันเปลี่ยนสิทธิ์ของไฟล์ในข้อความแสดงข้อผิดพลาดเพื่อให้เข้าถึงการเขียนโดยผู้ใช้ที่ apache ทำงานเป็น (apache, www-data ฯลฯ ) แทนที่จะแก้ไข / etc / group โดยตรง (หรือ chmod-ing ไฟล์เป็น 0777) ฉันใช้ usermod:

usermod -a -G vhost-user-group apache-user

จากนั้นฉันต้องรีสตาร์ท apache เพื่อให้การเปลี่ยนแปลงมีผล:

apachectl restart

หรือ

sudo /etc/init.d/httpd restart

หรืออะไรก็ตามที่ระบบของคุณใช้ในการรีสตาร์ท apache

หากไซต์อยู่ในโฮสติ้งที่ใช้ร่วมกันคุณอาจต้องเปลี่ยนการอนุญาตไฟล์ด้วยโปรแกรม FTP หรือติดต่อผู้ให้บริการโฮสติ้ง?


1

เมื่อต้องการแก้ไขปัญหานี้ให้ตั้งค่า apc.shm_size เป็นจำนวนเต็มค้นหาไฟล์ apc.ini ของคุณ (ในตำแหน่งไฟล์ apc.ini ระบบของฉัน /etc/php5/conf.d/apc.ini) และ set: apc.shm_size = 1000


1

ในระบบของฉันฉันต้องแทรก apc.shm_size = 64M ลงใน /usr/local/etc/php.ini (FreeBSD 9.1) จากนั้นเมื่อฉันดู apc.php (ซึ่งฉันคัดลอกมาจาก / usr / local / share / doc / APC /apc.php เป็น / usr / local / www / apache24 / data) ฉันพบว่าขนาดแคชเพิ่มขึ้นจากค่าเริ่มต้น 32M เป็น 64M และฉันไม่ได้รับจำนวนแคชขนาดใหญ่อีกต่อไป

อ้างอิง: http://au1.php.net/manual/en/apc.configuration.php ยังอ่านความคิดเห็นของ Bokan พวกเขามีประโยชน์มาก


0

ตรวจสอบขนาดไฟล์แคชของคุณ (คุณสามารถใช้ apc.php จากแพ็คเกจ apc pecl) และเพิ่มขนาดไฟล์ apc.shm_size ตามความต้องการของคุณ

วิธีนี้ช่วยแก้ปัญหาได้

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