Django—— 緩衝架構

來源:互聯網
上載者:User

標籤:http   io   os   使用   ar   for   檔案   sp   資料   

譯者註:1、無用的,吹噓的說辭不翻譯;2、意譯,很多地方不準確。

動態網站最為重要的一點就是好,網頁是動態。每一次使用者請求頁面,網站就要進行各種計算——從資料庫查詢,到render模板,到各種邏輯運算——產生頁面所需的。這個過程是異常消耗資源的,遠遠比從硬碟讀取一個檔案然後顯示出來的代價高昂。

對於大多數中小網站來說,這也許不是問題,因為他們的訪問量不大,而對於大型網站而言,必須盡量減少不必要的伺服器資源開支。

因此,有了緩衝技術。

緩衝就是把一些需要消耗很多資源的計算結果儲存下來,當下次需要時,不需要再次進行計算,直接從緩衝中取,從而節省了資源。緩衝的偽碼錶達如下:

給定的url,在緩衝中尋找是否存在;

如果存在,返回cached page;

否則:

     產生該頁面;

     把該頁面儲存在緩衝中

     return 頁面

django的緩衝系統非常健壯…..(一些自誇的話,譯者注)。簡單的說,django提供不同粒度的緩衝:特定view的緩衝,緩衝某個耗時的程式片段的結果,或者緩衝整個網站。

django也能夠和一些“上遊的”緩衝技術協同工作,例如squid ,瀏覽器的緩衝等。這些緩衝類型是你不需要直接控制,但是可以通過HTTP head 協議來告訴別人,網站的那些部分需要被緩衝,如何緩衝。

建立緩衝

緩衝系統(cache system)需要一些設定。你需要告訴django,你的快取資料儲存在什麼地方:檔案,資料庫,或者記憶體中。不同的緩衝方式的效能是不同的。

在settings.py檔案中,設定CACHE_BACKEND, 下面是一些可用的CACHE_BACKEND值:

Memcached

目前最快的,效率最高的cache。

Memcached的官方網站:http://danga.com/memcached/  Memcached的所有資料都存在記憶體中,因此,不會有資料庫消耗和讀取檔案消耗。

安裝Memcached後,你需要安裝Memcached python bindings。目前有兩種版本可用,分別為:

速度最快的選擇是cmemcache,為 http://gijsbert.org/cmemcache/

django 1.0之前版本不可用。

如果你無法安裝 cmemcache, 你可以選擇安裝 python-memcached, :ftp://ftp.tummy.com/pub/python-memcached/ . 如果這個網址已經失效,, 到memcached官方網站 (http://www.danga.com/memcached/) ,到“Client APIs”下載 Python bindings.

使用Memcached,只需把CACHE_BACKEND設定為memcached://ip:port/的格式,ip地址是memcached服務啟動並執行機器ip地址,連接埠是memcached服務監聽的連接埠號碼。

樣本如下,如果memcached服務運行於本機,連接埠為11211,則配置語句為:

CACHE_BACKEND=’memcached://127.0.0.1:11211/’

memcached一個非常好的特性是可以多機共用cache,只需把所有提供緩衝的機器的ip地址和連接埠號碼全部列入即可,之間用逗號分開。樣本如下:

CACHE_BACKEND= ‘memcached://172.19.26.240:11211;172.19.26.242:11211/’

memcache也許有一個缺點,那就是由於memcached是基於記憶體的,當你的伺服器crash時,所有的cache資料都將丟失。但由於cache本身就是臨時的,所以,丟失cache資料沒什麼大問題。

 

 

翻譯:django 緩衝架構(2)(django cache framework)[轉載] January 17, 2009 by admin · Leave a Comment
Filed under: django 

在網路上搜尋了一下,這篇文章已經有人翻譯過了。

原文在這裡:http://www.woodpecker.org.cn/obp/django/django-faq/cache.html

檔案系統快取

 

要在檔案系統中儲存快取資料, 在 CACHE_BACKEND 中使用 “file://” 緩衝類型. 下面這個例子將快取資料儲存在 /var/tmp/django_cache 中, 設定如下:

 

CACHE_BACKEND = ‘file:///var/tmp/django_cache’

注意 file: 之後是三個斜線而不是兩個. 前兩個是 file:// 協議, 第三個是路徑 /var/tmp/django_cache 的第一個字元.

 

這個目錄路徑必須是絕對路徑 — 也就是說,它應該從你的檔案系統的根開始算起.至於路徑的最後是否加一個斜線, Django 並不在意.

要確保這個設定的路徑存在並且 Web 服務器可以讀寫.繼續上面的例子,如果你的伺服器以 apache 使用者身份運行, 確保目錄 /var/tmp/django_cache 存在並且可以被使用者 apache 讀寫.

 

本地記憶體緩衝

 

如果你想要記憶體緩衝的高效能卻沒有條件運行 Memcached, 可以考虛使用本地記憶體緩衝後端. 這個緩衝後端是多進程的並且安全執行緒. 要使用它,設定 CACHE_BACKEND 為 “locmem:///”. 舉例來說:

 

CACHE_BACKEND = ‘locmem:///’

簡單緩衝(用於開發)

 

“simple:///” 是一個簡單的,單進程的記憶體緩衝類型. 它僅僅在進程中儲存快取資料, 這意味著它僅適用於開發或測試環境. 例子:

 

CACHE_BACKEND = ’simple:///’

虛擬緩衝 (用於開發)

 

最後, Django還支援一種 “dummy” 緩衝(事實上並未緩衝) — 僅僅實現了緩衝介面但未實際做任何事.

 

CACHE_BACKEND 參數

 

所有緩衝類型均接受參數. 提供參數的方式類似查詢字串風格. 下面列出了所有合法的參數:

 

timeout

預設的緩衝有效時間,以秒計. 預設值是 300 秒(五分鐘).

max_entries

用於 簡單緩衝 及 資料庫緩衝 後端, 緩衝的最大條目數(超出該數舊的緩衝會被清除,預設值是 300).

cull_percentage

當達到緩衝的最大條目數時要保留的精選條目比率. 實際被儲存的是 1/cull_percentage, 因此設定 cull_percentage=3 就會儲存精選的 1/3 條目上,其餘的條目則被刪除.

 

如果將 cull_percentage 設定為 0 則意味著當達到緩衝的最大條目數時整個緩衝都被清除.當快取命中率很低時這會 極大的 提高精選緩衝條目的效率(根本不精選).

這個例子裡, timeout 被設定為 60:

 

CACHE_BACKEND = “memcached://127.0.0.1:11211/?timeout=60″

這個例子, timeout 設定為 30 而 max_entries 設定為 400:

 

CACHE_BACKEND = “memcached://127.0.0.1:11211/?timeout=30&max_entries=400″

非法的參數會被忽略.

 

緩衝整個網站

 

設定了緩衝類型之後, 最簡單使用緩衝的方式就是緩衝整個網站. 在“MIDDLEWARE_CLASSES“ 設定中添加 django.middleware.cache.CacheMiddleware , 就象下面的例子一樣:

 

MIDDLEWARE_CLASSES = (

    ”django.middleware.cache.CacheMiddleware”,

    ”django.middleware.common.CommonMiddleware”,

)

( MIDDLEWARE_CLASSES 順序相關. 參閱下文中的 “Order of MIDDLEWARE_CLASSES”)

 

然後,在 Django 設定檔案中添加以下設定:

 

CACHE_MIDDLEWARE_SECONDS — 每個頁面被緩衝的時間.

CACHE_MIDDLEWARE_KEY_PREFIX — 如果緩衝被同一個 Django 安裝的多個網站共用, 在這裡佈建網站名字, 或者某些其它唯一的字串, 以避免 key 衝突.如果你不介意,也可以使用空串.

緩衝中介軟體緩衝沒有 GET/POST 參數的每個頁面.另外, CacheMiddleware 自動在每個 HttpResponse 中設定一些 headers:

 

當請求一個未快取頁面面時,設定 Last-Modified header 到當前的日期時間.

設定 Expires header 到當前日期時間加上定義的 CACHE_MIDDLEWARE_SECONDS.

設定 Cache-Control header 為該頁面的生存期 — 該生存期也來自 CACHE_MIDDLEWARE_SECONDS 設定.

參閱 middleware documentation 瞭解中介軟體的更多資訊.

 

緩衝單個 view

 

Django 能夠只緩衝特定的頁面. django.views.decorators.cache 定義了一個 cache_page 修飾符, 它能自動緩衝該 view 的響應. 該修飾符的使用極為簡單:

 

from django.views.decorators.cache import cache_page

 

def slashdot_this(request):

    …

 

slashdot_this = cache_page(slashdot_this, 60 * 15)

或者, 使用Python 2.4 的修飾符文法:

 

@cache_page(60 * 15)

def slashdot_this(request):

    …

cache_page 僅接受一個參數: 緩衝有效期間,以秒計. 在上面的例子裡,  slashdot_this() view 將被緩衝 15 分鐘.

 

底層緩衝 API

 

某些時候, 緩衝一個完整的頁面不符合你的要求. 比如你認為僅有某些高強度的查詢才有必要緩衝其結果.要達到這種目的,你能使用底層緩衝 API 來在任意層次儲存對象到緩衝系統.

 

緩衝 API 是簡單的. 從緩衝模組 django.core.cache 匯出一個由 CACHE_BACKEND 設定自動產生的 cache 對象:

 

>>> from django.core.cache import cache

基本的介面是 set(key, value, timeout_seconds) 和 get(key):

 

>>> cache.set(’my_key’, ‘hello, world!’, 30)

>>> cache.get(’my_key’)

‘hello, world!’

timeout_seconds 參數是可選的,其預設值等於 CACHE_BACKEND 的 timeout 參數.如果緩衝中沒有該對象, cache.get() 返回 None:

 

>>> cache.get(’some_other_key’)

None

 

# Wait 30 seconds for ‘my_key’ to expire…

 

>>> cache.get(’my_key’)

None

get() 可以接受一個 default 參數:

 

>>> cache.get(’my_key’, ‘has expired’)

‘has expired’

當然還有一個 get_many() 介面, 它僅僅命中緩衝一次. get_many() 返回一個字典,包括未到期的實際存在的你請求的所有鍵.:

 

>>> cache.set(’a‘, 1)

>>> cache.set(’b‘, 2)

>>> cache.set(’c‘, 3)

>>> cache.get_many([‘a‘, ‘b‘, ‘c‘])

{’a‘: 1, ‘b’: 2, ‘c’: 3}

最後, 你可以使用  delete() 顯式的刪除鍵. 這是一個在緩衝中清除特定對象的簡便的方式:

 

>>> cache.delete(’a‘)

就是這樣. 緩衝機制限制非常少: 你可以安全的緩衝能被 pickled 的任意對象(key必須是字串).

 

Upstream caches

 

到現在為止, 我們的目光僅僅聚焦在 你自己的 資料上. 在 WEB 開發中還有另外一種類型的緩衝: 

 

“upstream” 緩衝. 這是使用者請求還未抵達你的網站時由瀏覽器實施的緩衝.

 

下面是 upstream 緩衝的幾個例子:

 

你的 ISP 會緩衝特定頁面, 當你請求 somedomain.com 的一個頁面時, 你的 ISP 會直接發送給你一個快取頁面.(不訪問 somedomain.com ).

你的 Django Web 網站可能建立在一個 Squid (http://www.squid-cache.org/) WebProxy 伺服器之後, 它會快取頁面面以提高效能. 這種情況下,每個請求會先經 Squid 處理, 僅在需要時它會將請求傳遞給你的應用程式.

你的瀏覽器也會緩衝一些頁面. 如果一個 WEB 頁發送了正確的 headers, 瀏覽器會用本地(緩衝的)拷貝來回應後發的同一頁面的請求.

Upstream 緩衝是一個非常有效推進, 不過它也有相當不足之處: 很多 WEB 頁基於授權及一堆變數, 而這個緩衝系統盲目的單純依賴 URL 快取頁面面, 這可能會對不適當的使用者泄露敏感資訊.

 

舉例來說,假設你使用一個 Web e-mail 系統, “inbox” 頁的內容顯然依賴當前登入使用者. 如果一個 ISP 盲目的緩衝了你的網站, 後來的使用者就會看到前一使用者的收件匣, 這可不是一件有趣的事.

 

幸運的是, HTTP 提供了一個該問題的解決方案: 用一系列 HTTP headers 來構建緩衝機制以區分緩衝內容, 這樣緩衝系統就不會緩衝某些特定頁.

 

使用 Vary headers

 

其中一個 header 就是 Vary. 它定義了緩衝機制在建立緩衝 key 時的請求 headers. 舉例來說, 如果一個網頁的內容依賴一個戶的語言設定, 則該網頁被告知 “vary on language.”

 

預設情況, Django 的緩衝系統使用請求路徑建立 緩衝 key —比如, ”/stories/2005/jun/23/bank_robbed/”. 這意味著該 URL 的每個請求使用相同的緩衝版本,不考慮使用者代理程式的不同.(cookies 及語言特性).

 

因此我們需要 Vary .

 

如果你的基於 Django 的頁面根據不同的請求 headers 輸出不同的內容 — 比如一個 cookie, 或語言, 或使用者代理程式 — 你會需要使用 Vary header 來告訴緩衝系統這個頁面輸出依賴這些東西.

 

要在 Django 中做到這一步, 使用  vary_on_headers view 修飾符,就象下面這樣:

 

from django.views.decorators.vary import vary_on_headers

 

# Python 2.3 syntax.

def my_view(request):

    …

my_view = vary_on_headers(my_view, ‘User-Agent’)

 

# Python 2.4 decorator syntax.

@vary_on_headers(’User-Agent’)

def my_view(request):

    …

這樣緩衝系統 (比如 Django 自己的緩衝中介軟體) 會為不同的使用者代理程式緩衝不同的版本的頁面.使用 vary_on_headers修飾符的優勢在於(與人工設定 Vary header 相比:使用類似 response[‘Vary‘] =‘user-agent’)修飾符會添加到 Vary header (可能已存在) 而不是覆蓋掉它.

 

你也可以傳遞多個 header 給 vary_on_headers():

 

@vary_on_headers(’User-Agent’, ‘Cookie’)

def my_view(request):

    …

由於多個 cookie 的情況相當常見, 這裡有一個 vary_on_cookie 修飾符. 下面兩個 views 是等價的:

 

@vary_on_cookie

def my_view(request):

    …

 

@vary_on_headers(’Cookie’)

def my_view(request):

    …

需要注意一點傳遞給 vary_on_headers 的參數是大小寫不敏感的. “User-Agent” 與 “user-agent” 完全相同.

 

你也可以直接使用一個協助函數, django.utils.cache.patch_vary_headers:

 

from django.utils.cache import patch_vary_headers

def my_view(request):

    …

    response = render_to_response(’template_name’, context)

    patch_vary_headers(response, [‘Cookie‘])

    return response

patch_vary_headers 接受一個 HttpResponse 執行個體作為它的第一個參數及一個 header 名字的列表或tuple作為第二個參數.

 

要瞭解 Vary headers 的更多資訊, 參閱 official Vary spec.

控制緩衝: 使用其它 headers緩衝的另一個問題是資料的私密性及瀑布緩衝模式下資料儲存到哪裡.

 

使用者經常要面對的有兩種緩衝: 他自己的瀏覽器緩衝(私人緩衝) 及網站提供的緩衝(公開緩衝).一個公開緩衝用於多使用者情況,其內容由另外的人控制. 這造成了資料的私密性問題: 你當然不想你的銀行帳號儲存在公用緩衝裡.因此應用程式需要一種方式告訴緩衝系統哪些東西是私密的,哪些則是公開的.

 

解決方案就是聲明某個頁面的緩衝是 “私密的”. 在 Django 中, 使用 cache_control view 修飾符. 例子:

 

from django.views.decorators.cache import cache_control

@cache_control(private=True)

def my_view(request):

    …

這個修飾符會在幕後謹慎的發送適當的 HTTP header 發避免上面的問題.

 

還有一些其它的方式控制緩衝參數. 舉例來說,HTTP 允許應用程式做以下事:

 

定義一個頁面被緩衝的最大時間.指定緩衝是否需要總是檢查新版本, 如果沒有變化則僅傳送緩衝版本. (某些緩衝即使伺服器端頁面變化也僅傳遞緩衝版本–僅僅因為緩衝拷貝尚未到期).

在 Django 中, 使用 cache_control view 修飾符指定緩衝參數.在這個例子裡 cache_control 通知緩衝每次檢驗緩衝版本, 直到 3600 秒到期:

 

from django.views.decorators.cache import cache_control

@cache_control(must_revalidate=True, max_age=3600)

def my_view(request):

    …

所有合法的 Cache-Control HTTP 指令在 cache_control() 中都是合法的. 下面是完整的指令列表:

 

public=True

private=True

no_cache=True

no_transform=True

must_revalidate=True

proxy_revalidate=True

max_age=num_seconds

s_maxage=num_seconds

要瞭解 Cache-Control HTTP 指令的細節,參閱 Cache-Control spec.

 

(注意緩衝中介軟體已經通過設定中的 CACHE_MIDDLEWARE_SETTINGS 的值設定了緩衝 header 的 max-age.如果你在 cache_control 修飾符中使用了自訂的 max_age , 修飾符中的設定將被優先使用, header 值會被正確的合并)

 

其它最佳化

 

Django 內建了一些中介軟體以協助你提高網站效能:

 

django.middleware.http.ConditionalGetMiddleware 添加了有條件GET的支援. 它利用了 ETag 及 Last-Modified headers.

django.middleware.gzip.GZipMiddleware 為支援 Gzip 的瀏覽器對發送內容進行壓縮(所有流行瀏覽器均支援).

MIDDLEWARE_CLASSES 順序

 

如果你使用了 CacheMiddleware, 在 MIDDLEWARE_CLASSES 設定中使用正確順序非常重要. 由於緩衝中介軟體需要知道哪些 headers 由哪些緩衝儲存.中介軟體總是在可能的情況下添加某些東西到 Vary 響應 header.

 

將 CacheMiddleware 放到其它可能添加某些東西到 Vary Header的中介軟體之後,下面的中介軟體會添加東西到 Vary header:

 

SessionMiddleware 添加了 Cookie

GZipMiddleware 添加了 Accept-Encoding

Django—— 緩衝架構

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.