Giảm sử dụng bộ nhớ Django. Quả treo thấp?


136

Việc sử dụng bộ nhớ của tôi tăng theo thời gian và khởi động lại Django không tốt với người dùng.

Tôi không chắc chắn về cách cấu hình sử dụng bộ nhớ nhưng một số mẹo về cách bắt đầu đo sẽ hữu ích.

Tôi có cảm giác rằng có một số bước đơn giản có thể tạo ra lợi nhuận lớn. Đảm bảo 'gỡ lỗi' được đặt thành 'Sai' là một vấn đề lớn.

Bất cứ ai có thể đề nghị những người khác? Bao nhiêu cải thiện sẽ lưu vào bộ nhớ cache trên các trang web lưu lượng thấp?

Trong trường hợp này, tôi đang chạy dưới Apache 2.x với mod_python. Tôi đã nghe nói mod_wsgi hơi gầy hơn nhưng sẽ rất khó để chuyển đổi ở giai đoạn này trừ khi tôi biết mức tăng sẽ rất đáng kể.

Chỉnh sửa: Cảm ơn những lời khuyên cho đến nay. Bất kỳ đề xuất làm thế nào để khám phá những gì sử dụng hết bộ nhớ? Có hướng dẫn nào về cấu hình bộ nhớ Python không?

Ngoài ra, như đã đề cập, có một số điều sẽ khiến cho việc chuyển sang mod_wsgi trở nên khó khăn, vì vậy tôi muốn có một số ý tưởng về lợi ích mà tôi có thể mong đợi trước khi đi tiếp theo hướng đó.

Chỉnh sửa: Carl đã đăng một câu trả lời chi tiết hơn một chút ở đây rất đáng đọc: Triển khai Django: Cắt giảm chi phí của Apache

Chỉnh sửa: Bài viết của Graham Dumpleton là bài viết hay nhất tôi tìm thấy trên MPM và những thứ liên quan đến mod_wsgi. Tôi khá thất vọng vì không ai có thể cung cấp bất kỳ thông tin nào về việc gỡ lỗi sử dụng bộ nhớ trong chính ứng dụng.

Chỉnh sửa cuối cùng: Tôi đã thảo luận vấn đề này với Webfaction để xem liệu họ có thể hỗ trợ biên dịch lại Apache hay không và đây là lời của họ về vấn đề này:

"Tôi thực sự không nghĩ rằng bạn sẽ nhận được nhiều lợi ích bằng cách chuyển sang thiết lập MPM Worker + mod_wsgi. Tôi ước tính rằng bạn có thể tiết kiệm được khoảng 20 MB, nhưng có lẽ không nhiều hơn thế."

Vì thế! Điều này đưa tôi trở lại câu hỏi ban đầu của tôi (mà tôi vẫn không phải là người khôn ngoan hơn). Làm thế nào để đi về việc xác định các vấn đề nằm ở đâu? Đó là một câu châm ngôn nổi tiếng mà bạn không tối ưu hóa mà không thử nghiệm để xem bạn cần tối ưu hóa ở đâu nhưng có rất ít cách hướng dẫn về cách sử dụng bộ nhớ Python và không có gì cụ thể đối với Django.

Cảm ơn sự giúp đỡ của mọi người nhưng tôi nghĩ câu hỏi này vẫn còn bỏ ngỏ!

Một chỉnh sửa cuối cùng ;-)

Tôi đã hỏi điều này trong danh sách người dùng django và nhận được một số câu trả lời rất hữu ích

Thành thật là bản cập nhật cuối cùng!

Điều này vừa được phát hành. Có thể là giải pháp tốt nhất: Cấu hình kích thước đối tượng Django và sử dụng bộ nhớ với Pympler

Câu trả lời:


50

Hãy chắc chắn rằng bạn không giữ tài liệu tham khảo toàn cầu về dữ liệu. Điều đó ngăn người thu gom rác python giải phóng bộ nhớ.

Đừng sử dụng mod_python. Nó tải một trình thông dịch bên trong apache. Nếu bạn cần sử dụng apache, sử dụng mod_wsgithay thế. Nó không phải là khó khăn để chuyển đổi. Nó rất dễ. mod_wsgicách dễ dàng hơn để cấu hình cho django hơn là chết não mod_python.

Nếu bạn có thể loại bỏ apache khỏi yêu cầu của bạn, điều đó sẽ còn tốt hơn cho bộ nhớ của bạn. spawningdường như là cách mở rộng nhanh mới để chạy các ứng dụng web python.

EDIT : Tôi không thấy việc chuyển sang mod_wsgi có thể " khó khăn " như thế nào . Nó nên là một nhiệm vụ rất dễ dàng. Xin hãy giải thích về vấn đề bạn đang gặp phải với công tắc.


4
@Josh: sự phình to và sử dụng bộ nhớ của apache là ngu ngốc nếu bạn không sử dụng các tính năng chỉ dành cho apache. Nó chỉ là một lớp không cần thiết.
nosklo

3
Django vẫn tán thành mod_python vì mod_wsgi vẫn còn khá mới và họ muốn bảo thủ. Nhưng nếu bạn theo dõi cộng đồng Django, bạn sẽ thấy mọi người chuyển sang mod_wsgi en masse. Sẽ không mất nhiều thời gian trước khi nó là lựa chọn được đề xuất.
Carl Meyer

1
@Tiago: apache rất tốt khi bạn đã có sẵn nhiều máy chủ ảo apache, sử dụng SSL với apache, v.v. Trong trường hợp này, hãy sử dụng mod_wsgi. Nếu bạn đang bắt đầu từ đầu, hãy sử dụng sinh sản. KHÔNG BAO GIỜ sử dụng mod_python.
nosklo

1
Cảm ơn, nosklo. Tôi đang xem xét việc sinh sản .. dường như không có tài liệu nào cả .. Tôi sẽ cố gắng làm theo một số hướng dẫn tôi tìm thấy trong các bài đăng trên blog và xem nơi tôi có thể nhận được.
Tiago

1
Hmm, vì ai đó mới bắt đầu sử dụng Django, tôi sẽ ghi nhớ rằng tôi nên sử dụng mod_wsgi.
Powerlord

28

Nếu bạn đang chạy dưới mod_wsgi và có lẽ sinh sản vì nó tuân thủ WSGI, bạn có thể sử dụng Dozer để xem xét việc sử dụng bộ nhớ của mình.

Trong mod_wsgi, chỉ cần thêm phần này vào cuối tập lệnh WSGI của bạn:

from dozer import Dozer
application = Dozer(application)

Sau đó trỏ trình duyệt của bạn tại http: // domain / _dozer / index để xem danh sách tất cả các cấp phát bộ nhớ của bạn.

Tôi cũng sẽ chỉ thêm tiếng nói hỗ trợ cho mod_wsgi. Nó tạo ra một thế giới khác biệt về hiệu suất và việc sử dụng bộ nhớ so với mod_python. Sự hỗ trợ của Graham Dumpleton cho mod_wsgi rất nổi bật, cả về phát triển tích cực và giúp mọi người trong danh sách gửi thư để tối ưu hóa cài đặt của họ. David Cramer tại curse.com đã đăng một số biểu đồ (mà bây giờ tôi không thể tìm thấy một cách đáng tiếc) cho thấy việc giảm đáng kể việc sử dụng cpu và bộ nhớ sau khi họ chuyển sang mod_wsgi trên trang web có lưu lượng truy cập cao đó. Một số nhà phát triển django đã chuyển đổi. Nghiêm túc mà nói, đó là một kẻ không có trí tuệ :)


Trong trường hợp nào tôi sẽ sớm đăng một câu hỏi hỏi làm thế nào một người có được xác thực dựa trên cookie cho người dùng django truy cập các tệp tĩnh ...
Andy Baker

15

Đây là các giải pháp trình lược tả bộ nhớ Python mà tôi biết (không liên quan đến Django):

Tuyên bố miễn trừ trách nhiệm: Tôi có cổ phần sau này.

Tài liệu của dự án riêng lẻ sẽ cung cấp cho bạn ý tưởng về cách sử dụng các công cụ này để phân tích hành vi bộ nhớ của các ứng dụng Python.

Sau đây là một "câu chuyện chiến tranh" hay cũng cung cấp một số gợi ý hữu ích:


5

Ngoài ra, hãy kiểm tra xem bạn có sử dụng bất kỳ loại leaker nào đã biết không. MySQLdb được biết là rò rỉ số lượng lớn bộ nhớ với Django do lỗi trong xử lý unicode. Ngoài ra, Thanh công cụ gỡ lỗi Django có thể giúp bạn theo dõi những con lợn.


amix.dk/blog/viewEntry/19420 cho thấy dozer đang được sử dụng để cho thấy rằng MySQLdb đã bị rò rỉ bộ nhớ. MySQLdb 1.2.3c1 và sau đó sửa lỗi này.
msanders

Làm thế nào có thể django-debug-toolbargiúp đỡ?
Wtower

4

Ngoài việc không lưu giữ các tài liệu tham khảo toàn cầu về các đối tượng dữ liệu lớn, hãy cố gắng tránh tải các bộ dữ liệu lớn vào bộ nhớ ở mọi nơi có thể.

Chuyển sang mod_wsgi trong chế độ daemon và sử dụng mpm worker của Apache thay vì prefork. Bước thứ hai này có thể cho phép bạn phục vụ nhiều người dùng đồng thời hơn với chi phí bộ nhớ ít hơn nhiều.


Đồng thời xem câu trả lời của Carl tại đây: stackoverflow.com/questions/488864/ từ
Andy Baker

Ngoài ra - trong một vài bài đăng tôi đã đọc có vẻ như lợi ích thực sự là khi chuyển sang MPM worker chứ không phải sử dụng mod_wsgi ...
Andy Baker

4

Webfaction thực sự có một số mẹo để giảm mức sử dụng bộ nhớ django.

Những điểm chính:

  • Đảm bảo gỡ lỗi được đặt thành false (bạn đã biết điều đó).
  • Sử dụng "ServerLimit" trong cấu hình apache của bạn
  • Kiểm tra xem không có vật thể lớn nào đang được tải trong bộ nhớ
  • Xem xét việc phục vụ nội dung tĩnh trong một quy trình hoặc máy chủ riêng biệt.
  • Sử dụng "MaxRequestsPerChild" trong cấu hình apache của bạn
  • Tìm hiểu và hiểu bao nhiêu bộ nhớ bạn đang sử dụng

2
Cảm ơn, tôi đã đọc chúng. Đó là số 3 và 6 Tôi hy vọng có thêm một chút chi tiết! ;-)
Andy Baker

3

Một điểm cộng nữa cho mod_wsgi: đặt maximum-requeststham số trong lệnh của bạn WSGIDaemonProcessvà mod_wsgi sẽ khởi động lại quy trình daemon thường xuyên. Không nên có hiệu ứng rõ ràng cho người dùng, ngoài việc tải trang chậm vào lần đầu tiên một quy trình mới được thực hiện, vì nó sẽ tải Django và mã ứng dụng của bạn vào bộ nhớ.

Nhưng ngay cả khi bạn làm có rò rỉ bộ nhớ, mà nên giữ cho kích thước quá trình từ nhận được quá lớn, mà không cần phải gián đoạn dịch vụ cho người dùng của bạn.


1
Một cái gì đó tương tự được đề cập ở đây: mail-archive.com/django-users@googlegroups.com/msg84698.html chỉ họ sử dụng thời gian chờ không hoạt động thay vì yêu cầu tối đa.
Tomas Andrle

3

Đây là kịch bản tôi sử dụng cho mod_wsgi (được gọi là wsgi.py và đặt gốc trong dự án django của tôi):

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()

Điều chỉnh myproject.sinstall và đường dẫn nếu cần. Tôi chuyển hướng tất cả đầu ra thành / dev / null vì mod_wsgi theo mặc định ngăn in. Sử dụng đăng nhập thay thế.

Đối với 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>

Hy vọng rằng điều này ít nhất sẽ giúp bạn thiết lập mod_wsgi để bạn có thể thấy nếu nó tạo ra sự khác biệt.


1

Bộ nhớ cache: đảm bảo rằng chúng đang bị xóa. Thật dễ dàng để một cái gì đó hạ cánh trong bộ đệm, nhưng không bao giờ bị GC vì tham chiếu bộ đệm.

Mã Swig'd: Đảm bảo rằng mọi thao tác quản lý bộ nhớ đều được thực hiện chính xác, thực sự dễ dàng bỏ lỡ những điều này trong python, đặc biệt là với các thư viện bên thứ ba

Giám sát: Nếu bạn có thể, hãy lấy dữ liệu về việc sử dụng bộ nhớ và lượt truy cập. Thông thường bạn sẽ thấy mối tương quan giữa một loại yêu cầu và sử dụng bộ nhớ nhất định.


1

Chúng tôi tình cờ phát hiện ra một lỗi trong Django với sơ đồ trang web lớn (10.000 mục). Có vẻ Django đang cố tải tất cả chúng vào bộ nhớ khi tạo sơ đồ trang web: http://code.djangoproject.com/ticket/11572 - giết chết quá trình apache một cách hiệu quả khi Google ghé thăm trang web.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.