在前文中我們提到了,快取是在電腦技術中用來提升資料存取速度的重要技巧。不過,快取本身機制並不是毫無代價的,一來系統必須建置額外的機制因而提高了架構上的複雜度,二來,當快取誤失時,整體的存取速度反而較不透過快取還慢。

當然,快取也會需要佔用額外的資源,尤其是記憶體空間。因此,設計者在考慮運用快取來提升資料存取效率之前,必須先了解系統所操作之資料的特性,進而挑選適合置入的快取,以提高存取效率的資料。

接下來,讓我們來看看,實際建置軟體系統所要用到的快取機制時,你需要再仔細考慮的一些技術因素。

找到適合你應用的快取系統類型
首先,你必須選定快取系統的實作。快取系統的區分,可以依快取所用的記憶體空間,是否位在和應用系統同樣的記憶體位址空間內來看。

有些快取系統所用的記憶體空間和應用系統位在相同的位址空間內,也就是說,它們是屬於同一個行程,應用系統想要存取快取中的資料,並不需要進行跨越行程的通訊(Inter-Process Communication,IPC)。

相反的,另一類的快取系統所用的記憶體空間和應用系統位在不同的位址空間內(甚至位在不同的主機之上),所以,當應用系統想要存取快取中的資料時,便需要進行跨越行程的通訊。當二者位在不同的主機上時,通常得經由網路通訊才能更新或取得快取中的資料。

之所以會有這兩種類型的設計,意謂著這兩種類型的快取系統各有優劣。
當快取系統所用的記憶體空間和應用系統位在相同的位址空間時,毋需透過IPC即可取得快取中的資料,存取速度較快。

相反的,若二者不在相同的位址空間內,資料便必須經由IPC的通道來傳送,其速度和直接於記憶體空間中存取,便會有明顯的高下差別。此外,資料若欲透過IPC傳送,必須經由過序列化(serialization)的程序,而接收時也必須進行解序列化(deserialization)處理,而這兩種動作,也會耗去CPU的運算資源,影響到存取的時間。

有壞就有好,雖然需透過IPC才能取得快取資料,雖然單看資料存取速度是位居下風,但是,當應用系統和快取系統能夠分別位在不同的位址空間,甚至不同的主機時,卻有一些其他無法被取代的優點,這是這一類設計之所以能夠存在的原因。那麼,這樣子有什麼優點呢?

最大的優點是這樣的設計是有規模擴充性(scalability)的。

在電腦系統裡,單一個行程所能定址的記憶體空間是有限的,也就是說,倘若使用同一行程內的記憶體空間做為快取空間,那麼,快取所能配置的記憶體空間量,便受這單一行程最大能擁有的記憶體空間所限制。

再者,位於快取內的資料,也僅能供同一行程內的應用系統所用,當應用系統同時間由多部主機所構成的分散式架構來提供服務時,快取系統本身便無法同時以分散式的架構來匹配。由於記憶體空間受限、無法以分散式的架構進行擴充,便成了此種快取系統的最大致命傷。

當然,當系統所需的規模或應用型態不需要時,它仍舊具備著存取快速的優勢。

大部分網站會用獨立的快取系統
現在許多網站系統,都採用快取系統來提高資料的存取效率。

由於網站應用本身就需要較大的規模,而網站需要快取的資料量也都較大,因此,多半選擇獨立於應用系統之外的快取系統。

這些系統通常是以獨立的伺服器型式存在,應用系統可以透過特定的通訊協定,將資料在經序列化完之後,利用IPC的方式,將資料送入快取系統中,當然,也是透過特定的通訊協定,利用IPC的方式,將資料自快取系統中取出,並且加以解序列化之後,便可還原當初置入快取系統中的資料。

這一類的快取系統中最廣為人知的,莫過於memcached了。

它最早是Danga Interactive為了Live Journal所發展出來的開放原始碼系統,而現今,許多大大小小的網站,都採用memcached來做為它們的快取系統。這中間包括了超大型規模的YouTube、Facebook及Twitter。由此可見其受歡迎的程度,以及應付超大規模使用的能耐。

不過,不論快取系統究竟位在和應用系統同一行程空間中,就應用系統存取快取的程式設計模型來說,仍然都是相同的。同樣都是給定一個鍵(key)值,對應到資料。

一般來說,你只要使用和快取系統相對應的客戶端程式庫,便不需要理會快取系統傳輸協定等細節,只需要以高階的存取模型來看待快取即可。以memcached而言,你可以輕易找到各種主流程式語言的客戶端程式庫,可以說是十分的方便。

注意快取系統的安全性
在key值的運用上有一些議題值得討論。一般來說,key值是個字串,而有些快取系統對key值的長度有所限制,例如在memcached中,key值的長度限制是250個字元,所以,不論使用何種方式來做為key值,都必須在快取系統的長度限制之內。

所以,在使用快取時,你必須為你要快取的每一筆資料都取一個特定的名稱,做為它在快取系統中的key值。

倘若以快取關聯式資料庫中資料的應用來說,你可以為欲快取的SQL述句進行命名,那麼便可以利用這名稱來做為該SQL述句對應資料的key值。

使用SQL述句本身做為key值,當然也是一個方式,但是幾乎沒有什麼優點。一來,SQL述句長度很容易超過限制,二來,完全不具備任何的可讀性,沒有什麼人能夠看到一句冗長的SQL述句就明白它確切的作用。

因此,為程式中所用到的每一個SQL述句命名是一項良好的程式設計習慣。當然,把這名稱用到快取系統的key值,剛好適得其所。

不過,使用命名良好的key值名稱,固然能增加程式的可讀性,但是,同時間也造成了另一個隱憂。就像跨行程的快取系統伺服器,可能因為效率的考慮,而不會在通訊協定上設計認證及授權等安全性的機制。

也就是說,只要有辦法利用網路連上其通訊埠,進而了解通訊協定的內容,伺服器便允許其存取快取中的資料。如此一來,當應用系統使用快取的名稱易於理解,而有心人士又能連上快取伺服器時,便有機會取得儲存於快取中的資料,因而形成安全性的漏洞。

因此,程式設計者可以考慮最終在面對快取系統時,將程式中所用的key值,經過一些好的hashing演算法,例如MD5,把key值加以混亂,再使用混亂後的結果,做為實際於快取系統中運用的key值。如此,程式一樣能夠保持可讀性,而快取系統中所使用的key值,也不再那麼容易被識破、理解,同時,使用hashing演算法,還能有限縮key值好處字串長度。

因此,在使用快取系統時,若能賦予每一筆資料有意義的名稱、然後再透過適當的hashing演算法加以處理,便可以同時兼顧可讀性及安全性。

專欄作者

熱門新聞

Advertisement