A través d'aquest llibre hem mencionat molts objectius que ens han dut al desenvolupament de Django. Facilitat d'ús, amigable per als programadors novells, abstracció de les tasques repetitives -- tots aquest han impulsats als desenvolupadors de Django.
Tanmateix, des de la concepció interna, d'un projecte tancat, sempre s'ha tingut en ment un altre objectiu increïblement important: Django ha de ser senzill de desplegar, i hauria de servir molta quantitat de trànsit amb uns recursos limitats.
Les motivacions d'aquest objectiu són aparents quan veus el rerefons de Django: un petit diari familiar de Kansas amb prou feines pot permetre's un petits servidor, així els desenvolupadors originals de Django s'han concentrat en esprémer el millor rendiment possible amb un recursos limitats. De fet, durant anys els desenvolupadors de Django has estat els seus propis administradors del sistema -- allí simplement no hi havia prou maquinari per les necessitats de dedicació dels administradors -- encara que aquests llocs tenien desenes de milions de clics al dia.
Com que Django es va convertir en un projecte de codi obert, aquest focus sobre el rendiment i la facilitat de desplegament va convertir-se en una cosa importat per una raó diferent: desenvolupadors afeccionats. Individus que volen utilitzar Django agraeixen trobar que poden hostatjar un lloc amb un transit petit -- o mitjà -- per uns 10 € al mes.
Però el fet de poder reduir-ho només és la meitat de la batalla. Django també necessita ser capaç d'escalar per reunir les necessitats de grans companyies i corporacions. Aquí, Django adopta un filosofia comuna de l'estil web LAMP sovint anomenat "res compartit".
LAMP?
L'acrònim LAMP fou originalment encunyat per descriure un popular conjunt de programari de codi obert utilitzat per realitzar molts llocs web:
- Linux (el sistema operatiu)
- Apache (el servidor web)
- MySQL (la base de dades)
- PHP (el llenguatge de programació)
Passat el temps, l'acrònim ha arribar a referir més a la filosofia d'aquests tipus de piles de programari obert que a una pila en particular. Així mentre Django utiltiza Python i no té cap base de dades preferida, la filosofia provada per la pila LAMP encaixa en la mentalitat del desenvolupament de Django.
Hi ha hagut algunes temptatives (la majoria de to d'humor) de crear un acrònim similar per descriure la pila tecnològica de Django; els seus autors han trobat PAID (PostgreSQL, Apache, Internet i Django) o LAPD (Linux, Apache, PostgreSQL i Django).
El la seva base, la filosofia de "Res compartit" és només l'aplicació del desacoblament a tota la pila de programari. Aquesta arquitectura es va presentar en resposta directa al que llavors era l'arquitectura prevalent: un servidor d'una aplicació web monolítica que encapsula el llenguatge, la base de dades, el servidor web -- fins i tot parts del sistema operatiu -- en un únic procés (p.e. Java).
Quan volem començar a escalar, aquest pot ser un gran problema; seria clarament impossible dividir la feina d'un procés monolític a través de moltes màquines diferent, així les aplicacions monolítiques necessiten servidors enormement potents. Aquests servidors, per descomptat, costen desenes o fins i tot centenars de milers d'euros, posant llocs web molt grans fora de l'abast de persones individuals o petites companyies.
El que la comunitat LAMP va adonar-se, és que si es trencava cada element en components individuals, podries començar amb un servidor econòmic, i afegir simplement servidors econòmics a mida que anés creixen. Si el teu servidor de base de dades de 3.000 € no pot aguantar la càrrega, simplement compra'n un segon (o tercer, o quart) fins que pugui. Si et cal més capacitat d'emmagatzemament, afegeix un servidor NFS.
Per fer aquesta feina, les aplicacions web ha d'assumir que el mateix servidor ha de tractar cada petició -- o fins i tot cada part d'una única petició. En un desplegament de gran escala LAMP (i Django), amb una mitja dotzena de servidors poden estar involucrats en el tractament d'una única pàgina! Les repercussions d'això són nombroses, però en essència són les dels punts següents:
Com probablement hauràs suposat, Django ho tracta més o menys transparentment -- cap part de Django viola aquests principis -- però conèixer la filosofia t'ajuda a l'hora d'escalar el sistema.
Però això funciona?
Aquesta filosofia pot sonar molt bé sobre el paper, (o en la pantalla), però això funciona actualment?Bé, en comptes de respondre directament, mira't una llista incompleta d'unes quantes companyies que han basat les seves empreses en aquesta arquitectura. Podràs reconèixer-ne alguns noms:
- Amazon
- Blogger
- Craigslist
- LiveJournal
- Slashdot
- Wikipedia
- Yahoo
- YouTube
Per parafrasejar una escena famosa de "Quan Harry va trobar la Sally...": "tindrem el que tenen"
Abans que entrem en detalls, fem un petit parèntesi.
El codi obert és famós per la anomenada "guerra religiosa": s'ha escrit molt sobre els editors de text (emacs vers vi), sistemes operatius (Linux vers Windows vers MacOSX), motors de bases de dades (MySQL vers PostgreSQL), i -- per descomptat -- llenguatges de programació.
Nosaltres intentem no entrar en aquestes batalles, no tenim prou temps.
Tanmateix, hi ha un bon nombre d'opcions quan fas el desplegament Django, i ens pregunten constantment per les nostres preferències. Dir aquestes preferències pot causar perilloses discussions en alguna d'aquestes batalles. Tanmateix, per a que les conegueu les indiquem aquí. Nosaltres preferim:
Per descomptat, podem dir que molts usuaris de Django que han escollit altres opcions i els funcionen perfectament.
Actualment Apache i mod_python es la configuració més robusta per usar amb Django en un servidor de producció.
mod_python és un plugin d'Apache que introdueix Python dins d'apache i carrega el codi Python en la memòria quan s'engega el servidor. El codi queda en memòria durant la vida del procés Apache, que implica un increment de rendiment davant d'altres solucions del servidor.
Django necessita Apache 2.x i mod_python 3.x, i hauries d'usar el prefork MPM d'Apache, en comptes del worker MPM.
Nota
La configuració d'Apache no entra en l'abast d'aquest llibre, així que simplement mencionarem els detalls que necessitis. Afortunadament, hi ha un bon nombre de recursos disponibles si et cal aprendre'n més sobre Apache. Uns quants d'ells que ens agraden són:
- La documentació en línia d'apache lliure.
- Pro Apache de Peter Wainwrite (Apress)
- Apache: La Guia Definitiva de Ben Laurie i Peter Laurie (O'Reilly)
Per configurar Django amb mod_python, primer assegura't que tens l'Apache instal·lat amb el mòdul mod_python activat. Això normalment significa que tens la directiva LoadModule en la configuració d'Apache; hi hauria d'haver alguna cosa com aquesta:
LoadModule python_module /usr/lib/apache2/modules/mod_python.so
Llavors edita la configuració de l'apache i afegeix-hi el següent:
<Location "/"> SetHandler python-program PythonHandler django.core.handlers.modpython SetEnv DJANGO_SETTINGS_MODULE mysite.settings PythonDebug On </Location>
Assegura't de substituir mysitte.settings de DJANGO_SETTINGS_MODULE amb el que encaixi en el teu lloc.
Això li indica a l'Apache: "Utilitza el mod_python per qualsevol URL sota '/', utilitzant l'adaptador mod_python de Django". Aquest passa el valor DJANGO_SETTINGS_MODULE per a que mod_python sàpiga quines configuracions utilitzar.
Fixa't que estem usant la directiva <Location>, no la directiva <Directory>. L'últim s'utilitza per apuntar a llocs del teu sistema de fitxers, mentre que <Location> apunta a llocs en l'estructura de la URL d'un lloc web. <Directory> no tindria sentit aquí.
També, si has modificat manualment el teu PYTHONPATH per posar el teu projecte Django en ell, cal dir-li a mod_python:
PythonPath "['/path/to/project'] + sys.path"
També pots afegir directives com PythonAutoReload Off per millorar el rendiment. Mira la documentació de mod_python per veure el llistat complet d'opcions.
Fixa't que hauries d'activar PythonDebug Off en un servidor en producció. Si deixes PythonDebug On, els teus usuaris podrien veure traces lletges (i rellevants) de Python si alguna cosa va malament dins de mod_python.
Re-arrenca Apache, i qualsevol petició al teu lloc (o hostes virtuals si has posat la directiva <VirtualHost>) serà servida per Django.
Nota
Si desplegues Django en un subdirectori -- és a dir, en algun lloc més enllà de "/" -- Django no retalla el prefix de la URL dels teus patrons URL. Així, si tens una configuració Apache semblant a aquesta:<Location "/mysite/"> SetHandler python-program PythonHandler django.core.handlers.modpython SetEnv DJANGO_SETTINGS_MODULE mysite.settings PythonDebug On </Location>Tots els teus patrons URL necessitaran començar amb "/mysite/". Per aquesta raó normalment recomanem deplegar Django a l'arrel del teu domini o hoste virtual.
És perfectament possible executar múltiples instal·lacions Django en la mateixa instància d'Apache. Només cal que utilitzis VirtualHost per fer-ho:
NameVirtualHost * <VirtualHost *> ServerName www.example.com # ... SetEnv DJANGO_SETTINGS_MODULE mysite.settings </VirtualHost> <VirtualHost *> ServerName www2.example.com # ... SetEnv DJANGO_SETTINGS_MODULE mysite.other_settings </VirtualHost>
Si necessites posar dues instal·lacions Django dins del mateix VirtualHost, et caldrà vigilar per assegurar-te que la memòria cau de mod_python no s'emboliqui amb les coses anteriors. Utilitza la directiva PythonInterpreter per cada directiva <Location> per separar els intèrprets:
<VirtualHost *> ServerName www.example.com # ... <Location "/something"> SetEnv DJANGO_SETTINGS_MODULE mysite.settings PythonInterpreter mysite </Location> <Location "/otherthing"> SetEnv DJANGO_SETTINGS_MODULE mysite.other_settings PythonInterpreter mysite_other </Location> </VirtualHost>
Els valors de PythonInterpreter no són realment preocupants, només serveixen per diferenciar entre els dos blocs de Location.
Com que mod_python carrega en memòria el codi Python, quan desplegues llocs Django amb mod_python no hauràs de re-iniciar Apache cada cop que fas canvis en el teu codi. Això pot ser una molèstia, així que aquí tenim un truc per evitar-ho:
Només afegint MaxRequestsPerChild 1 en el teu fitxer de configuració per forçar a Apache a recarregar en cada petició. Però no ho facis en un servidor en producció, no es revocaran els teus privilegis de Django.
Si ets un programador del tipus que depura utilitzant línies print, fixa't que els print no tenen efecte a mod_python; aquests no apareixen en el log d'Apache, com un podria esperar. Si et cal imprimir informació de depuració en una configuració mod_python, probablement voldràs usar el paquet de logs estàndard de Python o afegir la informació de depuració en una plantilla de la teva pàgina.
Django no serveix els seus propis fitxers multimèdia; deixa aquesta feina a qualsevol servidor web que tu vulguis. Recomanem que utilitzis un servidor web diferent -- p.e., un que no estigui executant Django -- per servir aquests continguts multimèdia; mira en la secció d'escalat, més avall.
Si, tanmateix, no tens cap opció i has de servir fitxers multimèdia en el mateix VirtualHost d'Apache que Django, aquí s'explica com aturar el mod_python per una part en particular del lloc:
<Location "/media/"> SetHandler None </Location>
Canvia Location a la URL arrel dels teus fitxers multimèdia.
També pots utilitzar la directiva <LocationMatch> per a que encaixi amb una expressió regular. Per exemple, això activa Django en l'arrel del lloc però explícitament desactiva Django per el subdirectori media i qualsevol URL que acabi amb .jpg, .gif, .png:
<Location "/"> SetHandler python-program PythonHandler django.core.handlers.modpython SetEnv DJANGO_SETTINGS_MODULE mysite.settings </Location> <Location "media"> SetHandler None </Location> <LocationMatch "\.(jpg|gif|png)$"> SetHandler None </LocationMatch>
Quan utilitzes Apache/mod_python, els errors els capturarà Django -- en altres paraules, els errors no es propaguen fins al nivell d'Apache i no apareixeran en error_log de l'Apache.
L'excepció és si hi ha alguna cosa que realment malfeta en la configuració de Django. En aquest cas, veuràs una pàgina "Internal Server Error" en el teu navegador i la traça completa de Python en el teu fitxer error_log Apache. La traça de l'error_log s'estén en múltiples línies. (Si, això és lleig i difícil de llegir, però és com mod_python fa les coses).
Algunes vegades, Apache genera fallades de segment quan instal·les Django. Quan això succeeix, la majoria de vegades és a causa d'una d'aquestes dues coses no relacionades amb el propi Django:
Si continues tenint problemes amb el mod_python, una bona opció és deixar-lo en els ossos, sense la framework Django. Això és una forma fàcil per aïllar els problemes específics de mod_python. Aquí obtindràs més detalls del funcionament de mod_python.
El següent pas s'hauria de ser per editar el teu codi de text i afegir una importació de qualsevol codi Django que utilitzis -- les teves vistes, els teus models, el teu URLconf, la teva configuració RSS, etc. Posar aquestes importacions en la teva funció de test i accedir a la URL de test en el navegador. Si això provoca un error, s'haurà confirmat que importar el codi Django causa el problema. Gradualment redueix el conjunt de les importacions fins que s'aturi la fallada, així fins a trobar el mòdul específic que causa el problema. Entra dins dels mòduls i mira que importen, si cal.
Encara que Django sota Apache i mod_python és la configuració més robusta, molta gent utilitza un hostatge compartit on FastCGI és l'única opció viable.
A més, in algunes situacions, FastCGI permet una millor seguretat i possiblement un millor rendiment que mod_python. Per llocs petits, FastCGI també pot tenir menor càrrega que Apache.
FastCGI és un forma eficient de deixar que una aplicació externa serveixi pàgines a un servidor web. El servidor web delega les peticions d'entrada (via un socket) a FastCGI, que executa el codi i retorna la resposta al servidor Web, que, a l'hora, la passa al navegador web del client.
Com mod_python, FastCGI permet que el codi estigui en la memòria, permetent peticions es serveixin sense un temps d'arrencada. A diferència de mod_python, un procés FastCGI no s'executa dins el procés del servidor Web, sinó en un procés persistent i separat.
Perquè executar el codi en un procés separat?
La forma tradicional de mod_* a Apache inclou varis llenguatges d'script (els més coneguts com el PHP, Python i Perl) dins de l'espai del procés del servidor web. Encara que això redueix el temps d'arrencada -- perquè el codi no ha de llegir-se del dist a cada petició -- representa un costa en l'ús de la memòria.Cada procés Apache crea una còpia completa de l'Apache, amb totes les característiques de l'Apache que Django simplement no aprofitarà. Els processos FastCGI, per altra banda, només té en la memòria Python i Django.
Degut a la natua de FastCGI, també és possible tenir processos que funcionin en comptes d'usuari diferents del procés del servidor web. Això és un benefici per la seguretat en sistemes compartits, perquè això vol dir que pots assegurar el teu codi d'altres usuaris.
Abans que puguis començar a utilitzar FastCGI amb Django, el cal instal·lar flup, que és una llibreria Python per tractar amb FastCGI. Alguns usuaris tenen problemes amb les versions més antigues, potser t'interessa descarregar-te la versió SVN.
FastCGI funciona amb un model client-servidor, i en la majoria de casos engegarà el procés del servidor FastCGI sobre el teu propi. El teu servidor web (sigui Apache, lighttpd, o un altre) només contacta amb el teu procés FastCGI-Django quan el servidor necessiti carregar una pàgina dinàmica. Com que el dimoni s'executa amb el codi en la memòria, és possible servir la resposta molt ràpid.
Nota
Si ets en un sistema d'hostatge compartit, probablement t'obligaran a usar un servidor web amb processos FastCGI. Mira la secció més avall d'executar Django amb un servidor web funcionant sobre processos.
Un servidor web pot connectar al servidor FastCGI d'una o dues formes: Aquest pot utilitzar un socket unix (una "canonada amb nom" en sistemes Win32), o utilitzant un socket TCP. Què escollir, depèn de les teves preferències; un socket TCP és més fàcil perquè pots editar els permisos.
Per engegar el teu servidor, primer canvia dins el directori del teu projecte (on és el teu manage.py), i llavors executar manage.py amb l'opció runfcgi:
./manage.py runfcgi [options]
Si especifiques help com a única opció després de runfcgi, mostrarà una llista de totes les opcions disponibles.
Necessitaràs especificar si un socket o el host i el port. Llavors, quan actives el teu servidor web, només necessitaràs apuntar a aquest host/port o socket que has especificat quan has engegat el servidor FastCGI.
Uns quants exemple t'ajudaran a entendre així:
./manage.py runfcgi method=threaded host=127.0.0.1 port=3033
./manage.py runfcgi method=prefork socket=/home/user/mysite.sock pidfile=django.pid
./manage.py runfcgi daemonize=false socket=/tmp/mysite.sock
Si tens el procés en marxa al davant, serà fàcil aturar-lo: simplement prement Ctrl-C s'aturarà i sortirà del servidor FastCGI. Tanmateix, quan el fas funcionar al darrera, necessitaràs utilitzar la comanda Unix kill.
Si especifiques l'opció pidfile en el teu manage.py runfcgi, podràs matar el dimoni FastCGI així:
kill `cat $PIDFILE`
... on $PIDFILE és el pidfile que has especificat.
Per facilitar l'engegada del teu dimoni FastCGI sobre UNIX, podries usar un petit escript shell:
#!/bin/bash # Replace these three settings. PROJDIR="/home/user/myproject" PIDFILE="$PROJDIR/mysite.pid" SOCKET="$PROJDIR/mysite.sock" cd $PROJDIR if [ -f $PIDFILE ]; then kill `cat -- $PIDFILE` rm -f -- $PIDFILE fi exec /usr/bin/env - \ PYTHONPATH="../python:.." \ ./manage.py runfcgi socket=$SOCKET pidfile=$PIDFILE
Per usar Django amb Apache i FastCGI, necessitaràs instal·lar Apache i configurar-lo, amb el mod_fastcgi instal·lat i activat. Consulta la documentació de mod_fastcgi i Apache per trobar-ne les instruccions.
Un cop el tens configurat, apunta l'Apache a la teva instància FastCGI de Django editant el fitxer de configuració d'Apache. Necessitaràs fer dues coses:
La directiva FastCGIExternalServer li diu a Apache on trobar el teu servidor FastCGI. Com explica el documents del FastCGIExternalServer, pots especificar un socket o un host. Aquí hi ha ambdós objectes:
# Connect to FastCGI via a socket / named pipe. FastCGIExternalServer /home/user/public_html/mysite.fcgi -socket /home/user/mysite.sock # Connect to FastCGI via a TCP host/port. FastCGIExternalServer /home/user/public_html/mysite.fcgi -host 127.0.0.1:3033
En cap cas, el fitxer /home/user/public_html/mysite.fcgi no ha d'existir en el mateix moment. És només una URL usada pel servidor web internament -- un ganxo per indicar quines peticions d'una URL han de tractar-se per una FastCGI. (En parlarem més en la pròxima secció).
El segon pas és dir-li a l'Apache que utilitzi FastCGI per les URL que encaixen en un cert patró. Per fer això, utilitza el mòdul mod_rewrite i re-escriure les URL a mysite.cgi (o qualsevol lloc que tu hagis especificat en la directiva FastCGIExternalServer, com s'ha explicat en la secció anterior).
En aquest exemple, li diem a l'Apache que utilitzi FastCGI per tractar qualsevol petició que no representi un fitxer del sistema de fitxers i no comenci amb /media/. Això és probablement el cas més comú, si estàs utilitzant un lloc Django:
<VirtualHost 12.34.56.78>
ServerName example.com
DocumentRoot /home/user/public_html
Alias /media /home/user/python/django/contrib/admin/media
RewriteEngine On
RewriteRule ^/(media.*)$ /$1 [QSA,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^/(.*)$ /mysite.fcgi/$1 [QSA,L]
</VirtualHost>
lighttpd és un servidor web lleuger normalment usat per servir fitxer estàtics. Suporta FastCGI natívament i, aquesta, és una bona opció per servir pàgines estàtiques i dinàmiques, si el teu lloc no té cap necessitat específica d'utilitzar l'Apache.
Assegura't que mod_fascgi està en la vostra llista de mòduls, en algun lloc després de mod_rewrite i mod_access, però no després de mod_accesslog. Probablement també voldràs mod_alias, per servir el multimèdia de l'administrador.
Afegeix el següent al teu fitxer de configuració de lighttpd:
server.document-root = "/home/user/public_html" fastcgi.server = ( "/mysite.fcgi" => ( "main" => ( # Use host / port instead of socket for TCP fastcgi # "host" => "127.0.0.1", # "port" => 3033, "socket" => "/home/user/mysite.sock", "check-local" => "disable", ) ), ) alias.url = ( "/media/" => "/home/user/django/contrib/admin/media/", ) url.rewrite-once = ( "^(/media.*)$" => "$1", "^/favicon\.ico$" => "/media/favicon.ico", "^(/.*)$" => "/mysite.fcgi$1", )
lighttpd et permet usar "configuració condicional" que permet que les configuracions siguin personalitzades per l'hoste. Per especificar múltiples llocs FastCGI, només has d'afegir un bloc condicional al voltant de la teva configuració FastCGI per a cada lloc:
# If the hostname is 'www.example1.com'...
$HTTP["host"] == "www.example1.com" {
server.document-root = "/foo/site1"
fastcgi.server = (
...
)
...
}
# If the hostname is 'www.example2.com'...
$HTTP["host"] == "www.example2.com" {
server.document-root = "/foo/site2"
fastcgi.server = (
...
)
...
}
També pots executar múltiples instal·lacions Django en el mateix lloc simplement especificant múltiples entrades de la directiva fastcgi.server. Afegeix un host FastCGI per a cadascuna.
Molts proveïdors d'hostatge compartit no et permeten que executis el teus propis dimonis servidors o modificar el fitxer httpd.conf. En aquests casos, segueix sent possible executar Django utilitzant processos engendradors de servidor web.
Nota
Si estàs utilitzant aquests processos, no hi ha necessitat d'engegar el servidor FastCGI. Apache genera una serie de processos, escalant-los depenent de les necessitats.Ni idea del que he escrit.
En el teu directori web arrel, afegeix un fitxer anomenat .htaccess
AddHandler fastcgi-script .fcgi
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ mysite.fcgi/$1 [QSA,L]
Llavors, crear un petit escript que li digui a l'apache com carregar el teu programa FastCGI. Crea un fitxer mysite.fcgi i situa'l en el teu directori web, i assegura't que sigui executable:
#!/usr/bin/python
import sys, os
# Add a custom Python path.
sys.path.insert(0, "/home/user/python")
# Switch to the directory of your project. (Optional.)
# os.chdir("/home/user/myproject")
# Set the DJANGO_SETTINGS_MODULE environment variable.
os.environ['DJANGO_SETTINGS_MODULE'] = "myproject.settings"
from django.core.servers.fastcgi import runfastcgi
runfastcgi(method="threaded", daemonize="false")
Si canvies qualsevol codi python del teu lloc, necessitaràs dir-li a FastCGI el codi que ha canviat. Però no cal re-engegar l'Apache en aquest cas. En comptes d'això, només re-actualitza el mysite.fcgi -- o modifica el fitxer -- per a que canviï la data del fitxer. Quan l'Apache vegi que el fitxer s'ha modificat, re-engegarà la teva aplicació Django per tu.
Si tens accés a una comanda del sistema Unix, pots realitzar-ho fàcilment amb la comanda touch:
touch mysite.fcgi
Ara que ja sabem com posar en marxa Django en un servidor únic, mirem com podríem escalar una instal·lació Django. Aquesta secció caminarà a través de com un lloc pot escalar des d'un únic servidor a un cluster de gran escala que podria servir milions de clic per hora.
És important fixar-se, tanmateix, que quasi cada lloc gran és gran des de diferents perspectives, així l'escalat és qualsevol cosa menys un única operació que ho arregla tot. La següent caminada seria suficient per mostrar els principis generals, i intentar mostrar les diferents opcions que podrien fet que fos possible.
Primer, assumirem que farem l'escalat exclusivament sota Apache i mod_python. Encara que coneixem diversos desplegaments mitjans i grans amb FastCGI que funcionen bé, simplement estem més familiaritzats amb Apache.
La majoria de lloc comencen amb un únic servidor, amb una arquitectura que és quelcom semblant així:

Això funciona perfectament per a lloc petits o mitjans, i és molt barat -- pots posar junts un únic servidor per a Django amb menys de 2,500 EUR.
Tanmateix, quan el transit s'incrementa ràpidament entraràs en la contenció de recursos entre les diferents peces del programari. Els servidors de bases de dades i els servidors web els agrada tenir tot els servidors per a ells, així quan els executes en el mateix servidor acaben lluitant pels mateixos recursos (RAM, CPU), que preferirien monopolitzar.
Això se soluciona fàcilment movent el servidor de base de dades a una segona màquina.
Tal com s'ha concebut Django, això és extremadament fàcil: simplement necessitaran canviar el paràmetre de configuració DATABASE_HOST posant-lo a la IP o nom de DNS del teu servidor de base de dades. És probablement una bona idea usar la IP si és possible; passant per sobre del DNS per la connexió entre la web i la base de dades que podria ser un bon problema.
Amb un servidor de base de dades, la nostra arquitectura ara queda així:

Ara comencem a entrar en el que s'anomena arquitectura de grada-N. No t'espantis per aquesta paraulota: es refereix al fet que diferents "grades" d'una pila web s'han separat en diferents màquines.
En aquest punt si has anticipat més necessitats per créixer més enllà s'un únic servidor de base de dades, és probablement una bona idea començar a pensar sobre la reunió de les connexions i/o la replicació de les bases de dades. No hi ha prou espai en aquest llibre per parlar-ne amb justícia -- desafortunadament -- així que hauràs de consultar la documentació de la teva base de dades o de la comunitat internauta per a saber-ne més.
Tenim que eliminar un altre gran problema des de la configuració del servidor: estem servint el contingut multimèdia des del mateix servidor que el contingut dinàmic.
Aquestes dues activitats rendeixen millor sota diferents circumstàncies, i per mantenir-les juntes en la mateixa caixa no tindrem cap millora en el rendiment. Així el següent pas es separar el contingut multimèdia -- és a dir, qualsevol cosa no generada per una vista Django -- en un servidor dedicat.

Idealment, aquest servidor multimèdia executarà un servidor web optimitzat per a contingut multimèdia estàtic. lighttpd i tux són dues molt bones opcions, però un Apache pelat també funcionaria.
Per llocs pesats en contingut estàtic -- fotos, vídeos, etc. -- moure el servidor de muntimèdia a part és doblement important, i hauria de ser el primer pas en l'escalat.
Tanmateix, aquest pas pot ser lleugermaent difícil. L'administrador de Django necessita poder escriure els media carregats al servidor multimèdia (el paràmetre MEDIA_ROOT control on s'escriu aquest contingut multimèdia). Si el contingut multimèdia es en un altre servidor, tanmateix, necessitaràs tenir una forma d'escriure'l a través de la xarxa.
La forma fàcil de fer això és simplement usar un NFS montant en els directoris del servidor multimèdia sobre del servidor web. Si els montes en en mateix lloc apuntats pel paràmetre MEDIA_ROOT, el contingut multimèdia carregat funcionarà perfectament.
En aquest punt, hem de trencar les coses el màxim possible. Aquesta configuració de tres servidors haurà de tractar una gran quantitat de transit -- servim al voltant de 10 milions de clics al dia des d'una arquitectura d'aquest tipus -- així si creixem més, necessitarem afegir redundància.
Això és una bona cosa, actualment: una ullada al diagrama de sobre et mostra que si un únic dels teus tres servidors falla, el teu lloc web caurà completament. Així que afegeix servidors redundants, no només per incrementar la capacitat, també per incrementar la disponibilitat.
Com a motiu d'aquest exemple, assumeix que el servidor web disposa de la primera capacitat. És relativament fàcil obtenir múltiples còpies d'un lloc Django executant-se en diferent maquinari -- només cal que copiïs tot el codi dins de múltiples màquines, i engeguis l'Apache en totes elles.
Tanmateix, necessitaràs una altra peça de programari per distribuir el transit sobre múltiples servidors: un balancejador de càrrega. Pots comprar maquinari de balanceig de càrrega propietaris i cars, o hi ha un increïblement petit programari de codi obert d'alta qualitat que balanceja la càrrega.
El mod_proxy d'Apache és una opció, però hem trobat el Perlbal que és simplement fantàstic. És un balancejador de càrrega i proxy invers escrit pels mateixos xicots que han escrit el memcached (mireu el capítol 14).
Nota
Si estàs utilitzant FastCGI, pots aconseguir aquest mateix balanceig de càrrega separant els servidor web i els processos FastCGI sobre diferents màquines. El servidor de la presentació es converteix essencialment en el balancejador de càrrega i els processos FastCGI del darrera substitueixen els servidors Apache/mod_python/Django.
Amb els servidors web en cluster, la nostra arquitectura ja comença a ser més complexa:

Fixa't que en el diagrama els servidors web hi són representats com un "cluster" per indicar que el nombre de servidors és bàsicament variable; un cop tens un balancejador de càrrega al davant, pots afegir i treure fàcilment servidors web sense cap caiguda.
En aquest punt, les següents passes es deriven de l'última:
Després d'unes quantes iteracions, una arquitectura de gran escala seria quelcom així:

Encara que només es mostrin dos o tres servidors en cada nivell, no hi ha cap límit de quan en pots afegir.
Si tens un munt de diners, només et cal comprar més maquinari i més potent. Per a la resta de nosaltres, l'ajust del rendiment és necessari.
Nota
Si per casualitat, algun multimilionari ens està llegint, si us plau, considereu l'opció de fer una donació al projecte Django. Acceptem diamants en brut i també lingots d'or.
Desafortunadament, l'ajust del rendiment és més un art que ciència, i fins i tot és molt difícil escriure sobre com s'escalen. Si estàs realment interessat en desplegar una gran aplicació Django, hauràs de dedicar un munt de temps aprenent com ajustar cada peça de la teva pila.
Aquí, de totes formes, hem descobert durant els anys alguns trucs per ajustar Django:
De la mateixa forma que la RAM és cara, uns 200$ per cada gigabyte -- són cèntims comparats amb el temps d'ajustar alguna cosa. Comprar tanta RAM com puguis, i després compra'n una mica més.
Processadors més ràpids realment no incrementaran massa el rendiment; la majoria dels servidors web dediquen el 90% del seu temps en accessos al disc. Tant bon punt que comencis a utilitzar memòria swap, el rendiment començarà a morir. Discos més ràpids ajuden lleugerament, però són molt més ràpids que la RAM que no és realment preocupant.
Si tens múltiples servidors, el primer lloc on posar RAM és en el servidor de la base de dades. Si pots afrontar-ho, agafa prou RAM per a omplir-la amb tota la base de dades. Això no hauria de ser massa difícil; la base de dades de LJWorld.com -- incloent-hi sobre mig milió d'articles des d'abans del 1989 -- és d'uns 2GB.
El pròxim servidor a augmentar la ram és el servidor web. La situació ideal és en els que comencen a necessitar utilitzar el disc swap. Si arribes a el punt que no necessitin accedir a la SWAP segurament seràs capaç de servir la majoria del tràfic.
Keep-alive (mantenir-se viu) és una característica de l'HTTP que permet que múltiples peticions HTTP siguin servides en una única connexió TCP, evitant el desgast de muntar i desmuntar el TCP.
Això sembla bo en un primer moment, però actualment pot matar el rendiment d'un lloc Django. Si estàs servint multimèdia des de servidors separats, cada usuari que navegui pel vostre lloc només podrà actualitzar una pàgina del vostre servidor Django cada 10 segons en el millor dels casos. Això deixa els servidors HTTP esperant per la següent petició keep-alive, i un servidor HTTP en espera només consumeix RAM que un d'actiu no podrà usar.
Encara que Django permet un bon nombre de diferents tipus de servidors de memòria cau, cap d'ells és més ràpid que memcached. Si tes un lloc amb molt de transit, no provis altres servidors, vés directament a memcached.
Per descomptat, seleccionar memcached no serà bo si encara no l'utilitzes. El Capítol 14 és el vostre millor amic ara: apren com Django utilitza la framework de memòria cau, i utilitza arreu on puguis. Memòria cau agressiva, predictiva és normalment l'únic pensament que ha de tenir un lloc sota molt de transit.
Cada peça de la pila Django -- des del Linux a Apache a PostgreSQL o MySQL -- hi té una comunitat al darrera. Si realment vols exprèmer fins a l'última gota dels teus servidors, uneix-te a les comunitats de codi obert més enllà del teu programari i demana ajuda. La majoria dels membres de la comunitat del programari lliure estaran encantats d'ajudar-te.
I també assegura't d'ajuntar-te a la comunitat Django. Els seus humils autors són només dos membres d'una comunitat increïblement activa, que té molta experiència col·lectiva a oferir.
Et desitgem molta sort en el funcionament del teu lloc Django, ja sigui una petita joguina per a tu i els teus amics, o el pròxim Google.