Squid中文權威指南 第八章(高級磁盤緩存主題 )

第8章 高級磁盤緩存主題



8.1 是否存在磁盤I/O瓶頸?

Web緩存器例如squid,通常在磁盤I/O變成瓶頸時,不會正確的體現和告知你。代替的是,隨着負載的增加,響應時間和/或命中率會更低效。當然,響應時間和命中率可能因爲其他原因而改變,例如網絡延時和客戶請求方式的改變。

也許探測cache性能瓶頸的最好方式是做壓力測試,例如Web Polygraph。壓力測試的前提是你能完全控制環境,消除未知因素。你可以用不同的cache配置來重複相同的測試。不幸的是,壓力測試通常需要大量的時間,並要求有空閒的系統(也許它們正在使用中)。

假如你有資源執行squid壓力測試,請以標準的cache工作負載開始。當你增加負載時,在某些點上你能看到明顯的響應延時和/或命中率下降。一旦你觀察到這樣的性能降低,就禁止掉磁盤緩存,再測試一次。你可以配置squid從來不緩存任何響應(使用null存儲機制,見8.7章)。代替的,你能配置工作負載到100%不可cache響應。假如不使用cache時,平均響應時間明顯更好,那麼可以確認磁盤I/O是該水平吞吐量的瓶頸。

假如你沒有時間或沒有資源來執行squid壓力測試,那麼可檢查squid的運行時統計來查找磁盤I/O瓶頸。cache管理器的General Runtime Information 頁面(見14章)會顯示出cache命中和cache丟失的中值響應時間。

Median Service Times (seconds)  5 min    60 min:

        HTTP Requests (All):   0.39928  0.35832

        Cache Misses:          0.42149  0.39928

        Cache Hits:            0.12783  0.11465

        Near Hits:             0.37825  0.39928

        Not-Modified Replies:  0.07825  0.07409

對健壯的squid緩存來說,命中顯然快於丟失。中值命中響應時間典型的少於0.5秒或更少。我強烈建議你使用SNMP或其他的網絡監視工具來從squid緩存採集定期測量值。如果平均命中響應時間增加得太明顯,意味着系統有磁盤I/0瓶頸。

假如你認爲產品cache面臨此類問題,可以用前面提到的同樣的技術來驗證你的推測。配置squid不cache任何響應,這樣就避開了所有磁盤I/O。然後仔細觀察cache丟失響應時間。假如它降下去,那麼你的推測該是正確的。

一旦你確認了磁盤吞吐能力是squid的性能瓶頸,那麼可做許多事來改進它。其中一些方法要求重編譯squid,然而另一些相對較簡單,只需調整Unix文件系統。



8.2 文件系統調整選項

首先,從來不在squid的緩存目錄中使用RAID。以我的經驗看,RAID總是降低squid使用的文件系統的性能。最好有許多獨立的文件系統,每個文件系統使用單獨的磁盤驅動器。

我發現4個簡單的方法來改進squid的UFS性能。其中某些特指某種類型的操作系統例如BSD和Linux,也許對你的平臺不太合適:

  • 1.某些UFS支持一個noatime的mount選項。使用noatime選項來mount的文件系統,不會在讀取時,更新相應的i節點訪問時間。使用該選項的最容易的方法是在/etc/fstab裏增加如下行:
    # Device            Mountpoint    FStype  Options        Dump    Pass#
       
    /dev/ad1s1c         /cache0       ufs     rw,noatime     0       0


  • 2.檢查mount(8)的manpage裏的async選項。設置了該選項,特定的I/O操作(例如更新目錄)會異步執行。某些系統的文檔會標明這是個危險的標籤。某天你的系統崩潰,你也許會丟失整個文件系統。對許多squid安裝來說,執行性能的提高值得冒此風險。假如你不介意丟失整個cache內容,那麼可以使用該選項。假如cache數據非常有價值,async選項也許不適合你。

  • 3.BSD有一個功能叫做軟更新。軟更新是BSD用於Journaling文件系統的代替品。在FreeBSD上,你可以在沒有mount的文件系統中,使用tunefs命令來激活該選項:
    # umount /cache0
    
    # tunefs -n enable /cache0
    
    # mount /cache0


  • 4.你對每個文件系統運行一次tunefs命令就可以了。在系統重啓時,軟更新自動在文件系統中激活了。 在OpenBSD和NetBSD中,可使用softdep mount選項:
    # Device            Mountpoint    FStype  Options        Dump    Pass#
    
    /dev/sd0f           /usr          ffs     rw,softdep     1       2

假如你象我一樣,你可能想知道在async選項和軟更新選項之間有何不同。一個重要的區別是,軟更新代碼被設計成在系統崩潰事件中,保持文件系統的一致性,而async選項不是這樣的。這也許讓你推斷async執行性能好於軟更新。然而,如我在附錄D中指出的,事實相反。

以前我提到過,UFS性能特別是寫性能,依賴於空閒磁盤的數量。對空文件系統的磁盤寫操作,要比滿文件系統快得多。這是UFS的最小自由空間參數,和空間/時間優化權衡參數背後的理由之一。假如cache磁盤滿了,squid執行性能看起來很糟,那麼試着減少cache_dir的容量值,以便更多的自由空間可用。當然,減少cache大小也會降低命中率,但響應時間的改進也許值得這麼做。假如你給squid緩存配置新的設備,請考慮使用超過你需要的更大磁盤,並且僅僅使用空間的一半。



8.3 可選擇的文件系統

某些操作系統支持不同於UFS(或ext2fs)的文件系統。Journaling文件系統是較普遍的選擇。在UFS和Journaling文件系統之間的主要不同在於它們處理更新的方式。在UFS下,更新是實時的。例如,當你改變了某個文件並且將它存儲到磁盤,新數據就替換了舊數據。當你刪除文件時,UFS直接更新了目錄。

Journaling文件系統與之相反,它將更新寫往獨立的記帳系統,或日誌文件。典型的你能選擇是否記錄文件改變或元數據改變,或兩者兼備。某個後臺進程在空閒時刻讀取記帳,並且執行實際的改變操作。Journaling文件系統典型的在系統崩潰後比UFS恢復更快。在系統崩潰後,Journaling文件系統簡單的讀取記帳,並且提交所有顯著的改變。

Journaling文件系統的主要弊端在於它們需要額外的磁盤寫操作。改變首先寫往日誌文件,然後才寫往實際的文件或目錄。這對web緩存影響尤其明顯,因爲首先web緩存傾向於更多的磁盤寫操作。

Journaling文件系統對許多操作系統可用。在Linux上,你能選擇ext3fs,reiserfs, XFS,和其他的。XFS也可用在SGI/IRIX,它原始是在這裏開發的。Solaris用戶能使用Veritas文件系統產品。TRU64(以前的Digital Unix)高級文件系統(advfs)支持Journaling。

你可以不改變squid的任何配置而使用Journaling文件系統。簡單的創建和掛載在操作系統文檔裏描述的文件系統,而不必改變squid.cf配置文件裏的cache_dir行。

用類似如下命令在Linux中製作reiserfs文件系統:

# /sbin/mkreiserfs /dev/sda2

對XFS,使用:

# mkfs -t xfs -f /dev/sda2

注意ext3fs其實簡單的就是激活了記帳的ext2fs。當創建該文件系統時,對mke2fs使用-j選項:

# /sbin/mke2fs -j /dev/sda2

請參考其他操作系統的相關文檔。



8.4 aufs存儲機制

aufs存儲機制已經發展到超出了改進squid磁盤I/O響應時間的最初嘗試。"a"代表着異步I/O。默認的ufs和aufs之間的唯一區別,在於I/O是否被squid主進程執行。數據格式都是一樣的,所以你能在兩者之間輕鬆選擇,而不用丟失任何cache數據。

aufs使用大量線程進行磁盤I/O操作。每次squid需要讀寫,打開關閉,或刪除cache文件時,I/O請求被分派到這些線程之一。當線程完成了I/O後,它給squid主進程發送信號,並且返回一個狀態碼。實際上在squid2.5中,某些文件操作默認不是異步執行的。最明顯的,磁盤寫總是同步執行。你可以修改src/fs/aufs/store_asyncufs.h文件,將ASYNC_WRITE設爲1,並且重編譯squid。

aufs代碼需要pthreads庫。這是POSIX定義的標準線程接口。儘管許多Unix系統支持pthreads庫,但我經常遇到兼容性問題。aufs存儲系統看起來僅僅在Linux和Solaris上運行良好。在其他操作系統上,儘管代碼能編譯,但也許會面臨嚴重的問題。

爲了使用aufs,可以在./configure時增加一個選項:

% ./configure --enable-storeio=aufs,ufs

嚴格講,你不必在storeio模塊列表中指定ufs。然而,假如你以後不喜歡aufs,那麼就需要指定ufs,以便能重新使用穩定的ufs存儲機制。

假如願意,你也能使用—with-aio-threads=N選項。假如你忽略它,squid基於aufs cache_dir的數量,自動計算可使用的線程數量。表8-1顯示了1-6個cache目錄的默認線程數量。


Table 8-1. Default number of threads for up to six cache directories

cache_dirs Threads
1 16
2 26
3 32
4 36
5 40
6 44

將aufs支持編譯進squid後,你能在squid.conf文件裏的cache_dir行後指定它:

cache_dir aufs /cache0 4096 16 256

在激活了aufs並啓動squid後,請確認每件事仍能工作正常。可以運行tail -f store.log一會兒,以確認緩存目標被交換到磁盤。也可以運行tail -f cache.log並且觀察任何新的錯誤或警告。


8.4.1 aufs如何工作

Squid通過調用pthread_create()來創建大量的線程。所有線程在任何磁盤活動之上創建。這樣,即使squid空閒,你也能見到所有的線程。

無論何時,squid想執行某些磁盤I/O操作(例如打開文件讀),它分配一對數據結構,並將I/O請求放進隊列中。線程循環讀取隊列,取得I/O請求並執行它們。因爲請求隊列共享給所有線程,squid使用獨享鎖來保證僅僅一個線程能在給定時間內更新隊列。

I/O操作阻塞線程直到它們被完成。然後,將操作狀態放進一個完成隊列裏。作爲完整的操作,squid主進程週期性的檢查完成隊列。請求磁盤I/O的模塊被通知操作已完成,並獲取結果。

你可能已猜想到,aufs在多CPU系統上優勢更明顯。唯一的鎖操作發生在請求和結果隊列。然而,所有其他的函數執行都是獨立的。當主進程在一個CPU上執行時,其他的CPU處理實際的I/O系統調用。


8.4.2 aufs發行

線程的有趣特性是所有線程共享相同的資源,包括內存和文件描述符。例如,某個線程打開一個文件,文件描述符爲27,所有其他線程能以相同的文件描述符來訪問該文件。可能你已知道,在初次管理squid時,文件描述符短缺是較普遍問題。Unix內核典型的有兩種文件描述符限制:


進程級的限制和系統級的限制。你也許認爲每個進程擁有256個文件描述符足夠了(因爲使用線程),然而並非如此。在這樣的情況下,所有線程共享少量的文件描述符。請確認增加系統的進程文件描述符限制到4096或更高,特別在使用aufs時。

調整線程數量有點棘手。在某些情況下,可在cache.log裏見到如下警告:

2003/09/29 13:42:47| squidaio_queue_request: WARNING - Disk I/O overloading

這意味着squid有大量的I/O操作請求充滿隊列,等待着可用的線程。你首先會想到增加線程數量,然而我建議,你該減少線程數量。

增加線程數量也會增加隊列的大小。超過一定數量,它不會改進aufs的負載能力。它僅僅意味着更多的操作變成隊列。太長的隊列導致響應時間變長,這絕不是你想要的。

減少線程數量和隊列大小,意味着squid檢測負載條件更快。當某個cache_dir超載,它會從選擇算法裏移除掉(見7.4章)。然後,squid選擇其他的cache_dir或簡單的不存儲響應到磁盤。這可能是較好的解決方法。儘管命中率下降,響應時間卻保持相對較低。


8.4.3 監視aufs操作

Cache管理器菜單裏的Async IO Counters選項,可以顯示涉及到aufs的統計信息。它顯示打開,關閉,讀寫,stat,和刪除接受到的請求的數量。例如:

% squidclient mgr:squidaio_counts

...

ASYNC IO Counters:

Operation       # Requests

open             15318822

close            15318813

cancel           15318813

write                   0

read             19237139

stat                    0

unlink            2484325

check_callback  311678364

queue                   0

取消(cancel)計數器正常情況下等同於關閉(close)計數器。這是因爲close函數總是調用cancel函數,以確認任何未決的I/O操作被忽略。

寫(write)計數器爲0,因爲該版本的squid執行同步寫操作,即使是aufs。

check_callbak計數器顯示squid主進程對完成隊列檢查了多少次。

queue值顯示當前請求隊列的長度。正常情況下,隊列長度少於線程數量的5倍。假如你持續觀察到隊列長度大於這個值,說明squid配得有問題。增加更多的線程也許有幫助,但僅僅在特定範圍內。



8.5 diskd存儲機制

diskd(disk守護進程的短稱)類似於aufs,磁盤I/O被外部進程來執行。不同於aufs的是,diskd不使用線程。代替的,它通過消息隊列和共享內存來實現內部進程間通信。

消息隊列是現代Unix操作系統的標準功能。許多年以前在AT&T的Unix System V的版本1上實現了它們。進程間的隊列消息以較少的字節傳遞:32-40字節。每個diskd進程使用一個隊列來接受來自squid的請求,並使用另一個隊列來傳回請求。


8.5.1 diskd如何工作

Squid對每個cache_dir創建一個diskd進程。這不同於aufs,aufs對所有的cache_dir使用一個大的線程池。對每個I/O操作,squid發送消息到相應的diskd進程。當該操作完成後,diskd進程返回一個狀態消息給squid。squid和diskd進程維護隊列裏的消息的順序。這樣,不必擔心I/O會無序執行。

對讀和寫操作,squid和diskd進程使用共享內存區域。兩個進程能對同一內存區域進行讀和寫。例如,當squid產生讀請求時,它告訴diskd進程在內存中何處放置數據。diskd將內存位置傳遞給read()系統調用,並且通過發送隊列消息,通知squid該過程完成了。然後squid從共享內存區域訪問最近的可讀數據。

diskd與aufs本質上都支持squid的無阻塞磁盤I/O。當diskd進程在I/O操作上阻塞時,squid有空去處理其他任務。在diskd進程能跟上負載情況下,這點確實工作良好。因爲squid主進程現在能夠去做更多工作,當然它有可能會加大diskd的負載。diskd有兩個功能來幫助解決這個問題。

首先,squid等待diskd進程捕獲是否隊列超出了某種極限。默認值是64個排隊消息。假如diskd進程獲取的數值遠大於此,squid會休眠片刻,並等待diskd完成一些未決操作。這本質上讓squid進入阻塞I/O模式。它也讓更多的CPU時間對diskd進程可用。通過指定cache_dir行的Q2參數的值,你可以配置這個極限值:

cache_dir diskd /cache0 7000 16 256 Q2=50

第二,假如排隊操作的數量抵達了另一個極限,squid會停止要求diskd進程打開文件。這裏的默認值是72個消息。假如squid想打開一個磁盤文件讀或寫,但選中的cache_dir有太多的未完成操作,那麼打開請求會失敗。當打開文件讀時,會導致cache丟失。當打開文件寫時,會阻礙squid存儲cache響應。這兩種情況下用戶仍能接受到有效響應。唯一實際的影響是squid的命中率下降。這個極限用Q1參數來配置:

cache_dir diskd /cache0 7000 16 256 Q1=60 Q2=50

注意在某些版本的squid中,Q1和Q2參數混雜在默認的配置文件裏。最佳選擇是,Q1應該大於Q2。


8.5.2 編譯和配置diskd

爲了使用diskd,你必須在運行./configure時,在--enable-storeio列表後增加一項:

% ./configure --enable-storeio=ufs,diskd

diskd看起來是可移植的,既然共享內存和消息隊列在現代Unix系統上被廣泛支持。然而,你可能需要調整與這兩者相關的內核限制。內核典型的有如下可用參數:

MSGMNB

每個消息隊列的最大字節限制。對diskd的實際限制是每個隊列大約100個排隊消息。squid傳送的消息是32-40字節,依賴於你的CPU體系。這樣,MSGMNB應該是4000或更多。爲安全起見,我推薦設置到8192。

MSGMNI

整個系統的最大數量的消息隊列。squid對每個cache_dir使用兩個隊列。假如你有10個磁盤,那就有20個隊列。你也許該增加更多,因爲其他應用程序也要使用消息隊列。我推薦的值是40。

MSGGSZ

消息片斷的大小(字節)。大於該值的消息被分割成多個片斷。我通常將這個值設爲64,以使diskd消息不被分割成多個片斷。

MSGSEG

在單個隊列裏能存在的最大數量的消息片斷。squid正常情況下,限制隊列的長度爲100個排隊消息。記住,在64位系統中,假如你沒有增加MSGSSZ的值到64,那麼每個消息就會被分割成不止1個片斷。爲了安全起見,我推薦設置該值到512。

MSGTQL

整個系統的最大數量的消息。至少是cache_dir數量的100倍。在10個cache目錄情況下,我推薦設置到2048。

MSGMAX

單個消息的最大size。對Squid來說,64字節足夠了。然而,你係統中的其他應用程序可能要用到更大的消息。在某些操作系統例如BSD中,你不必設置這個。BSD自動設置它爲MSGSSZ * MSGSEG。其他操作系統中,你也許需要改變這個參數的默認值,你可以設置它與MSGMNB相同。

SHMSEG

每個進程的最大數量的共享內存片斷。squid對每個cache_dir使用1個共享內存標籤。我推薦設置到16或更高。

SHMMNI

共享內存片斷數量的系統級的限制。大多數情況下,值爲40足夠了。

SHMMAX

單個共享內存片斷的最大size。默認的,squid對每個片斷使用大約409600字節。 爲安全起見,我推薦設置到2MB,或2097152。

SHMALL

可分配的共享內存數量的系統級限制。在某些系統上,SHMALL可能表示成頁數量,而不是字節數量。在10個cache_dir的系統上,設置該值到16MB(4096頁)足夠了,並有足夠的保留給其他應用程序。

在BSD上配置消息隊列,增加下列選項到內核配置文件裏:

# System V message queues and tunable parameters

options         SYSVMSG         # include support for message queues

options         MSGMNB=8192     # max characters per message queue

options         MSGMNI=40       # max number of message queue identifiers

options         MSGSEG=512      # max number of message segments per queue

options         MSGSSZ=64       # size of a message segment MUST be power of 2

options         MSGTQL=2048     # max number of messages in the system

options         SYSVSHM

options         SHMSEG=16       # max shared mem segments per process

options         SHMMNI=32       # max shared mem segments in the system

options         SHMMAX=2097152  # max size of a shared mem segment

options         SHMALL=4096     # max size of all shared memory (pages)

在Linux上配置消息隊列,增加下列行到/etc/sysctl.conf:

kernel.msgmnb=8192

kernel.msgmni=40

kernel.msgmax=8192

kernel.shmall=2097152

kernel.shmmni=32

kernel.shmmax=16777216

另外,假如你需要更多的控制,可以手工編輯內核資源文件中的include/linux/msg.h和include/linux/shm.h。

在Solaris上,增加下列行到/etc/system,然後重啓:

set msgsys:msginfo_msgmax=8192

set msgsys:msginfo_msgmnb=8192

set msgsys:msginfo_msgmni=40

set msgsys:msginfo_msgssz=64

set msgsys:msginfo_msgtql=2048

set shmsys:shminfo_shmmax=2097152

set shmsys:shminfo_shmmni=32

set shmsys:shminfo_shmseg=16

在Digital Unix(TRU64)上,可以增加相應行到BSD風格的內核配置文件中,見前面所敘。另外,你可使用sysconfig命令。首先,創建如下的ipc.stanza文件:

ipc:

msg-max = 2048

msg-mni = 40

msg-tql = 2048

msg-mnb = 8192

shm-seg = 16

shm-mni = 32

shm-max = 2097152

shm-max = 4096

然後,運行這個命令並重啓:

# sysconfigdb -a -f ipc.stanza

一旦你在操作系統中配置了消息隊列和共享內存,就可以在squid.conf裏增加如下的cache_dir行:

cache_dir diskd /cache0 7000 16 256 Q1=72 Q2=64

cache_dir diskd /cache1 7000 16 256 Q1=72 Q2=64

...

8.5.3 監視diskd

監視diskd運行的最好方法是使用cache管理器。請求diskd頁面,例如:

% squidclient mgr:diskd

...

sent_count: 755627

recv_count: 755627

max_away: 14

max_shmuse: 14

open_fail_queue_len: 0

block_queue_len: 0


             OPS SUCCESS    FAIL

   open   51534   51530       4

 create   67232   67232       0

  close  118762  118762       0

 unlink   56527   56526       1

   read   98157   98153       0

  write  363415  363415       0

請見14.2.1.6章關於該輸出的詳細描述。



8.6 coss存儲機制

循環目標存儲機制(Cyclic Object Storage Scheme,coss)嘗試爲squid定製一個新的文件系統。在ufs基礎的機制下,主要的性能瓶頸來自頻繁的open()和unlink()系統調用。因爲每個cache響應都存儲在獨立的磁盤文件裏,squid總是在打開,關閉,和刪除文件。

與之相反的是,coss使用1個大文件來存儲所有響應。在這種情形下,它是特定供squid使用的,小的定製文件系統。coss實現許多底層文件系統的正常功能,例如給新數據分配空間,記憶何處有自由空間等。不幸的是,coss仍沒開發完善。coss的開發在過去數年裏進展緩慢。雖然如此,基於有人喜歡冒險的事實,我還是在這裏描述它。


8.6.1 coss如何工作

在磁盤上,每個coss cache_dir是一個大文件。文件大小一直增加,直到抵達它的大小上限。這樣,squid從文件的開頭處開始,覆蓋掉任何存儲在這裏的數據。然後,新的目標總是存儲在該文件的末尾處。

squid實際上並不立刻寫新的目標數據到磁盤上。代替的,數據被拷貝進1MB的內存緩衝區,叫做stripe。在stripe變滿後,它被寫往磁盤。coss使用異步寫操作,以便squid主進程不會在磁盤I/O上阻塞。

象其他文件系統一樣,coss也使用塊大小概念。在7.1.4章裏,我談到了文件號碼。每個cache目標有一個文件號碼,以便squid用於定位磁盤中的數據。對coss來說,文件號碼與塊號碼一樣。例如,某個cache目標,其交換文件號碼等於112,那它在coss文件系統中就從第112塊開始。因此coss不分配文件號碼。某些文件號碼不可用,因爲cache目標通常在coss文件裏佔用了不止一個塊。

coss塊大小在cache_dir選項中配置。因爲squid的文件號碼僅僅24位,塊大小決定了coss緩存目錄的最大size:size = 塊大小 x (2的24次方)。例如,對512字節的塊大小,你能在coss cache_dir中存儲8GB數據。

coss不執行任何squid正常的cache置換算法(見7.5章)。代替的,cache命中被"移動"到循環文件的末尾。這本質上是LRU算法。不幸的是,它確實意味着cache命中導致磁盤寫操作,雖然是間接的。

在coss中,沒必要去刪除cache目標。squid簡單的忘記無用目標所分配的空間。當循環文件的終點再次抵達該空間時,它就被重新利用。


8.6.2 編譯和配置coss

爲了使用coss,你必須在運行./configure時,在--enable-storeio列表裏增加它:

% ./configure --enable-storeio=ufs,coss ...

coss緩存目錄要求max-size選項。它的值必須少於stripe大小(默認1MB,但可以用--enable-coss-membuf-size選項來配置)。也請注意你必須忽略L1和L2的值,它們被ufs基礎的文件系統使用。如下是示例:

cache_dir coss /cache0/coss 7000 max-size=1000000

cache_dir coss /cache1/coss 7000 max-size=1000000

cache_dir coss /cache2/coss 7000 max-size=1000000

cache_dir coss /cache3/coss 7000 max-size=1000000

cache_dir coss /cache4/coss 7000 max-size=1000000

甚至,你可以使用block-size選項來改變默認的coss塊大小。

cache_dir coss /cache0/coss 30000 max-size=1000000 block-size=2048

關於coss的棘手的事情是,cache_dir目錄參數(例如/cache0/coss)實際上不是目錄,它是squid打開或創建的常規文件。所以你可以用裸設備作爲coss文件。假如你錯誤的創建coss文件作爲目錄,你可以在squid啓動時見到如下錯誤:

2003/09/29 18:51:42|  /usr/local/squid/var/cache: (21) Is a directory

FATAL: storeCossDirInit: Failed to open a coss file.

因爲cache_dir參數不是目錄,你必須使用cache_swap_log指令(見13.6章)。否則squid試圖在cache_dir目錄中創建swap.state文件。在該情形下,你可以見到這樣的錯誤:

2003/09/29 18:53:38| /usr/local/squid/var/cache/coss/swap.state:
        
        (2) No such file or directory

FATAL: storeCossDirOpenSwapLog: Failed to open swap log.

coss使用異步I/O以實現更好的性能。實際上,它使用aio_read()和aio_write()系統調用。這點也許並非在所有操作系統中可用。當前它們可用在FreeBSD,Solaris,和Linux中。假如coss代碼看起來編譯正常,但你得到"Function not implemented"錯誤消息,那就必須在內核裏激活這些系統調用。在FreeBSD上,必須在內核配置文件中有如下選項:

options         VFS_AIO

8.6.3 coss發行

coss還是實驗性的功能。沒有充分證實源代碼在日常使用中的穩定性。假如你想試驗一下,請做好存儲在coss cache_dir中的資料丟失的準備。

從另一面說,coss的初步性能測試表現非常優秀。示例請見附錄D。

coss沒有很好的支持從磁盤重建cache數據。當你重啓squid時,你也許會發現從swap.state文件讀取數據失敗,這樣就丟失了所有的緩存數據。甚至,squid在重啓後,不能記憶它在循環文件裏的位置。它總是從頭開始。

coss對目標置換採用非標準的方式。相對其他存儲機制來說,這可能導致命中率更低。某些操作系統在單個文件大於2GB時,會有問題。假如這樣的事發生,你可以創建更多小的coss區域。例如:

cache_dir coss /cache0/coss0 1900 max-size=1000000 block-size=128

cache_dir coss /cache0/coss1 1900 max-size=1000000 block-size=128

cache_dir coss /cache0/coss2 1900 max-size=1000000 block-size=128

cache_dir coss /cache0/coss3 1900 max-size=1000000 block-size=128

使用裸磁盤設備(例如/dev/da0s1c)也不會工作得很好。理由之一是磁盤設備通常要求I/O發生在512個字節的塊邊界(譯者注:也就是塊設備訪問)。另外直接的磁盤訪問繞過了系統高速緩存,可能會降低性能。然而,今天的許多磁盤驅動器,已經內建了高速緩存。



8.7 null存儲機制

Squid有第5種存儲機制叫做null。就像名字暗示的一樣,這是最不健壯的機制。寫往null cache_dir的文件實際上不被寫往磁盤。

大多數人沒有任何理由要使用null存儲系統。當你想完全禁止squid的磁盤緩存時,null纔有用。你不能簡單的從squid.conf文件裏刪除所有cache_dir行,因爲這樣的話squid會增加默認的ufs cache_dir。null存儲系統有些時候在測試squid,和壓力測試時有用。既然文件系統是典型的性能瓶頸,使用null存儲機制能獲取基於當前硬件的squid的性能上限。

爲了使用該機制,在運行./configure時,你必須首先在--enable-storeio列表裏指定它:

% ./configure --enable-storeio=ufs,null ...

然後在squid.conf裏創建cache_dir類型爲null:

cache_dir /tmp null

也許看起來有點奇怪,你必須指定目錄給null存儲機制。squid使用目錄名字作爲cache_dir標識符。例如,你能在cache管理器的輸出裏見到它。



8.8 哪種最適合我?

Squid的存儲機制選擇看起來有點混亂和迷惑。aufs比diskd更好?我的系統支持aufs或coss嗎?假如我使用新的機制,會丟失數據嗎?可否混合使用存儲機制?

首先,假如Squid輕度使用(就是說每秒的請求數少於5個),默認的ufs存儲機制足夠了。在這樣的低請求率中,使用其他存儲機制,你不會觀察到明顯的性能改進。

假如你想決定何種機制值得一試,那你的操作系統可能是個決定因素。例如,aufs在Linux和Solaris上運行良好,但看起來在其他系統中有問題。另外,coss代碼所用到的函數,當前不可用在某些操作系統中(例如NetBSD)。

從我的觀點看來,高性能的存儲機制在系統崩潰事件中,更易受數據丟失的影響。這就是追求最好性能的權衡點。然而對大多數人來說,cache數據相對價值較低。假如squid的緩存因爲系統崩潰而破壞掉,你會發現這很容易,只需簡單的newfs磁盤分區,讓cache重新填滿即可。如果你覺得替換Squid的緩存內容較困難或代價很大,你就應該使用低速的,但可信的文件系統和存儲機制。

近期的Squid允許你對每個cache_dir使用不同的文件系統和存儲機制。然而實際上,這種做法是少見的。假如所有的cache_dir使用相同的size和相同的存儲機制,可能衝突更少。

 
發佈了12 篇原創文章 · 獲贊 5 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章