การลดการใช้หน่วยความจำ Django ผลไม้แขวนต่ำ?


136

การใช้หน่วยความจำของฉันเพิ่มขึ้นเมื่อเวลาผ่านไปและการรีสตาร์ท Django นั้นไม่เหมาะสำหรับผู้ใช้

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

ฉันมีความรู้สึกว่ามีขั้นตอนง่ายๆที่สามารถสร้างผลกำไรจำนวนมาก การตรวจสอบให้แน่ใจว่า 'debug' ถูกตั้งค่าเป็น 'False' เป็นปัญหาที่เห็นได้ชัด

ใครสามารถแนะนำคนอื่นได้บ้าง การปรับปรุงจะแคชเว็บไซต์ที่มีอัตราการเข้าชมต่ำเท่าใด

ในกรณีนี้ฉันใช้งาน Apache 2.x กับ mod_python ฉันได้ยินมาว่า mod_wsgi นั้นค่อนข้างผอม แต่มันก็เป็นเรื่องยากที่จะสลับมาที่ขั้นนี้เว้นแต่ว่าฉันรู้ว่าผลกำไรจะมีความสำคัญ

แก้ไข: ขอบคุณสำหรับเคล็ดลับจนถึง ข้อเสนอแนะวิธีการค้นหาสิ่งที่ใช้หน่วยความจำ? มีคำแนะนำในการทำโปรไฟล์หน่วยความจำ Python หรือไม่?

นอกจากนี้ตามที่กล่าวมามีบางสิ่งที่จะทำให้ยากที่จะเปลี่ยนไปใช้ mod_wsgi ดังนั้นฉันต้องการมีความคิดเกี่ยวกับกำไรที่ฉันคาดหวังก่อนที่จะไถไปข้างหน้าในทิศทางนั้น

แก้ไข: Carl โพสต์การตอบกลับที่มีรายละเอียดเพิ่มเติมเล็กน้อยที่นี่ซึ่งควรค่าแก่การอ่าน: การปรับใช้ Django: การตัด Overhead ของ Apache

แก้ไข: บทความของ Graham Dumpleton เป็นบทความที่ดีที่สุดที่ฉันพบใน MPM และ mod_wsgi ฉันค่อนข้างผิดหวังที่ไม่มีใครสามารถให้ข้อมูลเกี่ยวกับการดีบักการใช้หน่วยความจำในแอปได้

แก้ไขครั้งสุดท้าย:ฉันได้คุยเรื่องนี้กับ Webfaction เพื่อดูว่าพวกเขาสามารถช่วย Apache คอมไพล์ใหม่ได้หรือไม่และนี่คือคำพูดของพวกเขาในเรื่อง:

"ฉันไม่คิดว่าคุณจะได้รับประโยชน์มากนักจากการเปลี่ยนไปใช้การติดตั้ง MPM Worker + mod_wsgi ฉันคาดว่าคุณจะสามารถประหยัดได้ประมาณ 20MB แต่อาจไม่มากไปกว่านั้น"

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

ขอบคุณสำหรับความช่วยเหลือของทุกคน แต่ฉันคิดว่าคำถามนี้ยังคงเปิดอยู่!

อีกการแก้ไขขั้นสุดท้าย ;-)

ฉันถามสิ่งนี้ในรายชื่อผู้ใช้ django และได้รับคำตอบที่มีประโยชน์มาก

สุจริตปรับปรุงล่าสุดที่เคย!

นี่เพิ่งเปิดตัว อาจเป็นทางออกที่ดีที่สุด: การทำโปรไฟล์ขนาดวัตถุ Django และการใช้หน่วยความจำด้วย Pympler

คำตอบ:


50

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

mod_pythonอย่าใช้ มันโหลดล่ามภายในอาปาเช่ หากคุณต้องการใช้ apache ให้ใช้mod_wsgiแทน ไม่สลับซับซ้อน มันง่ายมาก ๆ. mod_wsgiเป็นวิธีที่ง่ายต่อการกำหนดค่าสำหรับ Djangomod_pythonกว่าสมองที่ตาย

หากคุณสามารถลบ apache ออกจากความต้องการของคุณนั่นจะเป็นการดียิ่งขึ้นไปยังหน่วยความจำของคุณ spawningน่าจะเป็นวิธีที่ปรับขนาดได้ใหม่อย่างรวดเร็วในการใช้งานแอพพลิเคชั่นเว็บไพ ธ อน

แก้ไข : ฉันไม่เห็นวิธีการเปลี่ยนไปใช้ mod_wsgi อาจเป็น " ยุ่งยาก " มันควรจะเป็นงานง่ายมาก โปรดอธิบายรายละเอียดเกี่ยวกับปัญหาที่คุณมีกับสวิตช์


4
@ Josh: การขยายตัวของ apache และการใช้หน่วยความจำนั้นโง่ถ้าคุณไม่ได้ใช้คุณสมบัติ apache-only มันเป็นแค่เลเยอร์ที่ไม่จำเป็น
nosklo

3
Django ยังคงรับรอง mod_python เพราะ mod_wsgi ยังค่อนข้างใหม่และพวกเขาต้องการที่จะอนุรักษ์ แต่ถ้าคุณติดตามชุมชน Django คุณจะเห็นคนเปลี่ยนไปใช้ mod_wsgi en masse ใช้เวลาไม่นานก่อนที่จะเป็นตัวเลือกที่แนะนำ
Carl Meyer

1
@ ติอาโก้: apache ดีเมื่อคุณมีโฮสต์เสมือน apache อยู่แล้วใช้ SSL กับ apache แล้วเป็นต้นในกรณีนี้ให้ใช้ mod_wsgi หากคุณเริ่มใหม่อีกครั้งใช้การวางไข่ ไม่เคยใช้ mod_python
nosklo

1
ขอบคุณ nosklo ฉันกำลังดูการวางไข่ .. ดูเหมือนจะมีเอกสารเล็กน้อยถึงไม่มีเลย .. ฉันจะพยายามทำตามคำแนะนำบางอย่างที่พบในโพสต์บล็อกและดูว่าฉันจะหาได้ที่ไหน
Tiago

1
อืมในขณะที่บางคนเพิ่งเริ่มใช้ Django ฉันจะจำไว้ว่าฉันควรใช้ mod_wsgi
Powerlord

28

หากคุณทำงานภายใต้ mod_wsgi และวางไข่อย่างน่าจะเป็นเพราะเป็นไปตามมาตรฐาน WSGI คุณสามารถใช้Dozerเพื่อดูการใช้งานหน่วยความจำของคุณ

ภายใต้ mod_wsgi เพียงเพิ่มที่ด้านล่างของสคริปต์ WSGI ของคุณ:

from dozer import Dozer
application = Dozer(application)

จากนั้นชี้เบราว์เซอร์ของคุณไปที่http: // domain / _dozer / indexเพื่อดูรายการการจัดสรรหน่วยความจำทั้งหมดของคุณ

ฉันจะเพิ่มเสียงสนับสนุนสำหรับ mod_wsgi ด้วย มันทำให้โลกของความแตกต่างในแง่ของประสิทธิภาพและการใช้หน่วยความจำมากกว่า mod_python การสนับสนุนของ Graham Dumpleton สำหรับ mod_wsgi นั้นยอดเยี่ยมทั้งในแง่ของการพัฒนาอย่างแข็งขันและการช่วยเหลือผู้คนในรายชื่อผู้รับจดหมายเพื่อเพิ่มประสิทธิภาพการติดตั้งของพวกเขา David Cramer ที่curse.comได้โพสต์ชาร์ต (ซึ่งตอนนี้ฉันไม่สามารถหาได้อย่างน่าเสียดาย) แสดงการลดลงอย่างมากในการใช้งานซีพียูและหน่วยความจำหลังจากที่พวกเขาเปลี่ยนมาใช้ mod_wsgi บนเว็บไซต์ที่มีปริมาณการใช้งานสูง มีการเปลี่ยน django devs หลายตัว อย่างจริงจังมันไม่มีเกมง่ายๆ :)


ซึ่งในกรณีนี้ผมจะเร็วจะโพสต์คำถามถามว่าใครได้รับการตรวจสอบตามคุกกี้สำหรับผู้ใช้ Django เข้าถึงไฟล์แบบคงที่ ...
แอนดี้เบเคอร์

15

เหล่านี้เป็นโซลูชันตัวสร้างโปรไฟล์หน่วยความจำ Python ที่ฉันทราบ (ไม่ใช่ Django ที่เกี่ยวข้อง):

  • Heapy
  • pysizer (ยกเลิก)
  • Python Memory Validator (เชิงพาณิชย์)
  • Pympler

ข้อจำกัดความรับผิดชอบ: ฉันมีส่วนร่วมในภายหลัง

เอกสารของแต่ละโครงการควรให้แนวคิดในการใช้เครื่องมือเหล่านี้เพื่อวิเคราะห์พฤติกรรมความจำของแอพพลิเคชั่น Python

ต่อไปนี้เป็น "เรื่องราวสงคราม" ที่ดีที่ให้คำแนะนำที่เป็นประโยชน์ด้วย:


5

นอกจากนี้ตรวจสอบว่าคุณไม่ได้ใช้ผู้ให้บริการที่รู้จัก เป็นที่ทราบกันดีว่า MySQLdb มีหน่วยความจำรั่วไหลจำนวนมากด้วย Django เนื่องจากบั๊กในการจัดการ Unicode นอกเหนือจากนั้นDjango Debug Toolbarอาจช่วยให้คุณติดตามหมูได้


amix.dk/blog/viewEntry/19420แสดง dozer ที่ใช้เพื่อแสดงว่า MySQLdb มีหน่วยความจำรั่ว MySQLdb 1.2.3c1 และแก้ไขในภายหลัง
msanders

จะdjango-debug-toolbarช่วยได้อย่างไร?
Wtower

4

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

สลับไปที่ mod_wsgi ในโหมด daemon และใช้ Apache ของผู้ปฏิบัติงาน mpm แทน prefork ขั้นตอนหลังนี้ช่วยให้คุณสามารถให้บริการผู้ใช้ที่ใช้งานพร้อมกันได้มากขึ้นโดยมีหน่วยความจำน้อยกว่ามาก


ดูคำตอบของ Carl ได้ที่นี่: stackoverflow.com/questions/488864/…
Andy Baker

นอกจากนี้ยัง - ในการโพสต์ไม่กี่ฉันได้อ่านมันก็ดูเหมือนว่ากำไรที่แท้จริงอยู่ในการเปลี่ยนไปใช้ปฏิบัติงาน MPM มากกว่าการใช้งานของ mod_wsgi และ ...
แอนดี้เบเกอร์

4

จริง ๆ แล้วการ Webshop มีเคล็ดลับในการลดการใช้หน่วยความจำ django ลง

ประเด็นสำคัญ:

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

2
ขอบคุณฉันได้อ่านสิ่งเหล่านั้นแล้ว เป็นเบอร์ 3 และ 6 ฉันหวังว่าจะได้รายละเอียดเพิ่มอีก! ;-)
Andy Baker

3

ข้อดีอีกอย่างสำหรับ mod_wsgi: ตั้งค่าmaximum-requestsพารามิเตอร์ในWSGIDaemonProcessคำสั่งของคุณและ mod_wsgi จะรีสตาร์ทกระบวนการ daemon ทุก ๆ ครั้ง ไม่ควรมีเอฟเฟกต์ที่มองเห็นได้สำหรับผู้ใช้นอกเหนือจากการโหลดหน้าเว็บช้าในครั้งแรกที่มีการตีกระบวนการใหม่เนื่องจากจะโหลด Django และรหัสแอปพลิเคชันของคุณลงในหน่วยความจำ

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


1
มีการพูดถึงสิ่งที่คล้ายกันที่นี่: mail-archive.com/django-users@googlegroups.com/msg84698.html เฉพาะที่พวกเขาใช้การไม่ใช้งานหมดเวลาแทนการร้องขอสูงสุด
Tomas Andrle

3

นี่คือสคริปต์ที่ฉันใช้สำหรับ mod_wsgi (เรียกว่า wsgi.py และใส่รูทปิดโครงการ django ของฉัน):

import os
import sys
import django.core.handlers.wsgi

from os import path

sys.stdout = open('/dev/null', 'a+')
sys.stderr = open('/dev/null', 'a+')

sys.path.append(path.join(path.dirname(__file__), '..'))

os.environ['DJANGO_SETTINGS_MODULE'] = 'myproject.settings'
application = django.core.handlers.wsgi.WSGIHandler()

ปรับ myproject.settings และเส้นทางตามต้องการ ฉันเปลี่ยนเส้นทางเอาต์พุตทั้งหมดเป็น / dev / null เนื่องจาก mod_wsgi โดยค่าเริ่มต้นจะป้องกันการพิมพ์ ใช้การบันทึกแทน

สำหรับ apache:

<VirtualHost *>
   ServerName myhost.com

   ErrorLog /var/log/apache2/error-myhost.log
   CustomLog /var/log/apache2/access-myhost.log common

   DocumentRoot "/var/www"

   WSGIScriptAlias / /path/to/my/wsgi.py

</VirtualHost>

หวังว่าอย่างน้อยนี่น่าจะช่วยให้คุณตั้งค่า mod_wsgi เพื่อให้คุณสามารถดูว่ามันสร้างความแตกต่าง


1

แคช: ตรวจสอบว่าพวกเขากำลังถูกลบทิ้ง มันง่ายสำหรับบางสิ่งที่จะลงจอดในแคช แต่ไม่เคยเป็น GC'd เพราะการอ้างอิงแคช

โค้ด Swig'd: ตรวจสอบให้แน่ใจว่าการจัดการหน่วยความจำถูกต้องอย่างถูกต้องมันง่ายมากที่จะพลาดสิ่งเหล่านี้ในไพ ธ อนโดยเฉพาะกับห้องสมุดบุคคลที่สาม

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


1

เราพบข้อผิดพลาดใน Django ที่มีแผนผังไซต์ขนาดใหญ่ (10.000 รายการ) ดูเหมือนว่า Django จะพยายามโหลดมันทั้งหมดในหน่วยความจำเมื่อสร้าง sitemap: http://code.djangoproject.com/ticket/11572 - ฆ่ากระบวนการ apache ได้อย่างมีประสิทธิภาพเมื่อ Google จ่ายการเยี่ยมชมเว็บไซต์

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