當前位置:首頁 » 硬碟大全 » memcached緩存分布
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

memcached緩存分布

發布時間: 2022-09-25 20:46:25

『壹』 php 一個網站需要用memcached!主要緩存什麼內容 那些該緩存 應該注意什麼

這個東西最大的好處是可以存儲對象,減少很多資料庫和伺服器壓力。直接基於內存的存儲,調用速度非常給力。
主要緩存的內容,大概可以歸納為 1.不需要即時顯示的內容,或者mysql查詢耗時的內容。舉例說明:網站的列表【最火的 排行榜】等非及時的,最新的如果強調及時性,可不用,當然也可以使用,可能更新緩存頻率較高。
2.非常需要速度和性能的地方
有些頁面通過mysql可能聯合查詢,全表檢索查詢速度相當慢,這時候可用緩存暫時保留 例如搜索引擎的結果集。

3.臨時數據保存
我們知道mysql Oracle等關系型資料庫,需要建立表結構才能存儲,這就決定了,有些臨時數據的存儲,也需要建立特定的表結構。這樣就比較啰嗦,不便於維護。
4.存儲對象
這個也是一個比較有特色的地方,php創建對象的效率是不高的,甚至堪稱低效,再加上構造函數大量的資料庫操作的話,會讓性能低到谷底,那麼它能幫你吧已經創建好的對象 保存起來 下次相同的請求 無需new只需要將它還原。
綜上,緩存是php的利器,速度 效率 等詞彙都可以通過它去體現

『貳』 分析Memcached客戶端如何把緩存數據分布到多個伺服器上

解決方法1:不同的模塊使用不同memcached客戶端實例,這樣不同模塊就可以配置不同的伺服器列表,這樣不同模塊的數據就緩存到了不同的伺服器中。這樣,當某台伺服器不可用後,只會影響到相應memcached客戶端實例的數據,而不會影響到其它客戶端實例的數據。

解決方法2:修改或添加新的演算法,並在數據唯一鍵中添加命名空間,演算法根據配置和數據唯一鍵中命名空間來選擇不同的Socket連接,也就是伺服器啦。

數據項唯一鍵(key)的定義:命名空間.數據項ID,就跟編程中的」 命名空間」一樣,經如說用戶有一篇日誌的ID是」999999」, 那麼這條篇日誌的唯一鍵就是:Sns.UserLogs.Log.999999,當然我們存貯的時候考慮性能問題,可以用一個短的數值來代替命名空間。這樣在選擇Socket的時候就可以根據數據項中的唯一鍵來選擇啦。

『叄』 常用的緩存技術

第一章 常用的緩存技術
1、常見的兩種緩存

本地緩存:不需要序列化,速度快,緩存的數量與大小受限於本機內存
分布式緩存:需要序列化,速度相較於本地緩存較慢,但是理論上緩存的數量與大小無限(因為緩存機器可以不斷擴展)
2、本地緩存

Google guava cache:當下最好用的本地緩存
Ehcache:spring默認集成的一個緩存,以spring cache的底層緩存實現類形式去操作緩存的話,非常方便,但是欠缺靈活,如果想要靈活使用,還是要單獨使用Ehcache
Oscache:最經典簡單的頁面緩存
3、分布式緩存

memcached:分布式緩存的標配
Redis:新一代的分布式緩存,有替代memcached的趨勢
3.1、memcached

經典的一致性hash演算法
基於slab的內存模型有效防止內存碎片的產生(但同時也需要估計好啟動參數,否則會浪費很多的內存)
集群中機器之間互不通信(相較於Jboss cache等集群中機器之間的相互通信的緩存,速度更快<--因為少了同步更新緩存的開銷,且更適合於大型分布式系統中使用)
使用方便(這一點是相較於Redis在構建客戶端的時候而言的,盡管redis的使用也不困難)
很專一(專做緩存,這一點也是相較於Redis而言的)
3.2、Redis

可以存儲復雜的數據結構(5種)
strings-->即簡單的key-value,就是memcached可以存儲的唯一的一種形式,接下來的四種是memcached不能直接存儲的四種格式(當然理論上可以先將下面的一些數據結構中的東西封裝成對象,然後存入memcached,但是不推薦將大對象存入memcached,因為memcached的單一value的最大存儲為1M,可能即使採用了壓縮演算法也不夠,即使夠,可能存取的效率也不高,而redis的value最大為1G)
hashs-->看做hashTable
lists-->看做LinkedList
sets-->看做hashSet,事實上底層是一個hashTable
sorted sets-->底層是一個skipList
有兩種方式可以對緩存數據進行持久化
RDB
AOF
事件調度
發布訂閱等
4、集成緩存

專指spring cache,spring cache自己繼承了ehcache作為了緩存的實現類,我們也可以使用guava cache、memcached、redis自己來實現spring cache的底層。當然,spring cache可以根據實現類來將緩存存在本地還是存在遠程機器上。

5、頁面緩存

在使用jsp的時候,我們會將一些復雜的頁面使用Oscache進行頁面緩存,使用非常簡單,就是幾個標簽的事兒;但是,現在一般的企業,前台都會使用velocity、freemaker這兩種模板引擎,本身速度就已經很快了,頁面緩存使用的也就很少了。

總結:

在實際生產中,我們通常會使用guava cache做本地緩存+redis做分布式緩存+spring cache就集成緩存(底層使用redis來實現)的形式
guava cache使用在更快的獲取緩存數據,同時緩存的數據量並不大的情況
spring cache集成緩存是為了簡單便捷的去使用緩存(以註解的方式即可),使用redis做其實現類是為了可以存更多的數據在機器上
redis緩存單獨使用是為了彌補spring cache集成緩存的不靈活
就我個人而言,如果需要使用分布式緩存,那麼首先redis是必選的,因為在實際開發中,我們會緩存各種各樣的數據類型,在使用了redis的同時,memcached就完全可以舍棄了,但是現在還有很多公司在同時使用memcached和redis兩種緩存。

『肆』 在抽象工廠模式中怎樣使用memcached緩存數據

一、Memcached簡介
memcached 常被用來加速應用程序的處理,在這里,我們將著重於介紹將它部署於應用程序和環境中的最佳實踐。這包括應該存儲或不應存儲哪些、如何處理數據的靈活分布以 及如何調節用來更新 memcached 和所存儲數據的方法。我們還將介紹對高可用性的解決方案的支持,比如 IBM WebSphere® eXtreme Scale。
所有的應用程序,特別是很多 web 應用程序都需要優化它們訪問客戶機和將信息返回至客戶機的速度。可是,通常,返回的都是相同的信息。從數據源(資料庫或文件系統)載入數據十分低效,若是每次想要訪問該信息時都運行相同的查詢,就尤顯低效。
雖然很多 web 伺服器都可被配置成使用緩存發回信息,但那與大多數應用程序的動態特性無法相適。而這正是 memcached 的用武之地。它提供了一個通用的內存存儲器,可保存任何東西,包括本地語言的對象,這就讓您可以存儲各種各樣的信息並可以從諸多的應用程序和環境訪問這些信息。
二、基礎知識
memcached 是一個開源項目,旨在利用多個伺服器內的多餘 RAM 來充當一個可存放經常被訪問信息的內存緩存。這里的關鍵是使用了術語緩存:memcached 為載入自他處的信息提供的是內存中的暫時存儲。
比如,考慮這樣一個典型的基於 web 的應用程序。即便是一個動態網站可能也會有一些組件或信息常量是貫穿頁面整個生命周期的。在一個博客站點內,針對單個 blog post 的類別列表不大可能在頁面查看間經常性地變更。每次都通過一個對資料庫的查詢載入此信息相對比較昂貴,特別是在數據沒有更改的情況下,就更是如此。從圖 1 可以看到一個博客站點內可被緩存的頁面分區。
圖1.一個典型的博客頁面內的可緩存元素

將這種結構放在 blog 站點的其他元素,poster 信息、注釋 — 設置 blog post 本身 — 進行推斷,可以看出為了顯示主頁的內容很可能需要發生 10-20 次資料庫查詢和格式化。 每天對數百甚至數千的的頁面查看重復此過程,那麼您的伺服器和應用程序執行的查詢要遠遠多於為了顯示頁面內容所需執行的查詢。
通過使用 memcached,可以將載入自資料庫的格式化信息存儲為一種可直接用在 Web 頁面上的格式。並且由於信息是從 RAM 而不是通過資料庫和其他處理從磁碟載入的,所以對信息的訪問幾乎是瞬時的。
再強調一下,memcached 是一個用來存儲常用信息的緩存,有了它,您便無需從緩慢的資源,比如磁碟或資料庫,載入並處理信息了。
對 memcached 的介面是通過網路連接提供的。這意味著您可以在多個客戶機間共享單個的 memcached 伺服器(或多個伺服器,如本文稍後所示的)。這個網路介面非常迅速,並且為了改善性能,伺服器會故意不支持身份驗證或安全性通信。但這不應限制部署選項。 memcached 伺服器應該存在於您網路的內部。網路介面的實用性以及可以部署多個 memcached 實例的簡便性讓您可以使用多個機器上的多餘 RAM 來提高您緩存的整體大小。
三、存儲方法
memcached 的存儲方法是一個簡單的鍵/值對,類似於很多語言內的散列或關聯數組。通過提供鍵和值來將信息存儲到 memcached 內,通過按特定的鍵請求信息來恢復信息。
信息會無限期地保留在緩存內,除非發生如下的情況:
為緩存分配的內存耗盡 — 在這種情況下,memcached 使用 LRU(最近最少使用)方法從此緩存刪除條目。最近未曾使用的條目會從此緩存中先刪除,最舊的最先訪問。
條目被明確刪除 — 總是可以從此緩存內刪除條目。
條目過期失效 — 各條目均有一個有效的期限以便針對此鍵存儲的信息在過於陳舊時可從緩存中清除這些條目。
上述這些情況可以與您應用程序的邏輯綜合使用以便確保緩存內的信息是最新的。有了這些基礎知識後,讓我們來看看在應用程序內如何能最好地利用 memcached。
四、何時使用memcached?
在使用 memcached 改進應用程序性能時,可以對一些關鍵的過程和步驟進行修改。
在載入信息時,典型的場景如圖 2 所示。
圖2.載入要顯示的信息的典型順序

一般而言,這些步驟是:
執行一個或多個查詢來從資料庫載入信息
格式化適合於顯示(或進一步處理)的信息
使用或顯示格式化了的數據
在使用 memcached 時,為配合這個緩存,可對應用程序的邏輯進行稍許修改:
盡量從緩存載入信息
如果存在,使用信息的被緩存版本
如果它不存在:
執行一個或多個查詢來從資料庫載入信息
格式化適合於顯示或進一步處理的信息
將信息存儲到緩存內
使用格式化了的數據
圖 3 是對這些步驟的總結。
圖3.在使用memcached時載入適合於顯示的信息

數據載入成為了至多三個步驟的一個過程,從緩存載入數據或從資料庫(視情況而定)載入數據並存儲在緩存內。
當這個過程首次發生時,數據將正常地從資料庫或其他數據源載入,然後再存儲到 memcached 內。當下一次訪問此信息時,它就會從 memcached 拉出,而不是從資料庫載入,節省了時間和 CPU 循環。
問題的另一個方面是要確保如果更改了要存儲在 memcached 內的信息,在更新後端信息的同時還要更新 memcached 的版本。這會讓圖 4 內所示的這個典型順序發生稍許變化,如 圖 5 所示。
圖4.在一個典型的應用程序內更新或存儲數據

圖 5 顯示了使用 memcached 後發生了變化的流程。
圖5.在使用memcached時更新或存儲數據

比如,仍以博客站點為例,在博客系統更新資料庫內的類別列表時,更新應該遵循如下順序:
更新資料庫內的類別列表
格式化信息
將信息存儲到 memcached 內
將信息返回至客戶機
memcached 內的存儲操作是原子的,所以信息的更新不會讓客戶機只獲得部分數據;它們獲得的或者是老版本,或者是新版本。
對於大多數應用程序,這兩個操作是您惟一需要注意的。在訪問他人使用的數據時,它會自動被添加到這個緩存內,而且如果對該數據進行了更改,此緩存內也會自動進行更新。
五、鍵、名稱空間和值
memcached 另一個需要重點考慮的因素是如何組織和命名存儲在緩存內的這些數據。從之前博客站點的例子中,不難看出需要使用一種一致的命名結構以便您能載入博客類別、歷史和其他信息,然後再在載入信息(並更新緩存)時或者在更新數據(同樣也要更新緩存)時使用。
使用的何種具體的命名系統特定於應用程序,但通常可以使用一種與現有應用程序類似的結構,並且這種結構很可能基於某種惟一識別符。當從資料庫拉出信息或在整理信息集時,就會發生這種情況。
以 blog post 為例,可以在一個具有鍵 category-list 的項中存儲類別列表。與此 post ID 對應的單個 post,比如 blogpost-29 相關的值都可以使用,而該項的注釋則可以存儲在 blogcomments-29內,其中 29 就是這個 blog post 的 ID。這樣一來, 您就可以將各種各樣的信息存儲在緩存內,使用不同的前綴來標識這些信息。
memcached 鍵/值存儲的簡便性(以及安全性的缺乏)意味著如果您想要在使用同一個 memcached 伺服器的同時支持多個應用程序,那麼就可以考慮使用其他格式的量詞來標識數據屬於某種特定的應用程序。比如,可以添加像 blogapp:blogpost-29 這樣的應用程序前綴。這些鍵是沒有格式的,所以可以使用任何字元串作為鍵的名稱。
在存儲值的方面,應該確保存儲在緩存內的信息適合於您的應用程序。比如,對於這個博客系統,您可能想要存儲被博客應用程序使用的對象以便格式化博客信息,而不是原始的 HTML。如果同一個基礎結構用在應用程序內的多個地方,這一點更具實用性。
大多數語言的介面,包括 Java™、Perl、PHP 等,都能串列化語言對象以便存儲在 memcached 內。這就讓您可以存儲並隨後從內存存儲恢復全部對象,而不是在您的應用程序內手動重構它們。 很多對象,或它們使用的結構,都基於某種散列或數組結構。對於跨語言的環境,比如在 JSP 環境和 JavaScript 環境間共享相同信息,可以使用一種架構中立的格式,比如 JavaScript Object Notation (JSON) 甚或 XML。
六、填充並使用memcached
作為一種開源產品以及一種最初開發用來工作於現有開源環境內的產品,memcached 受大量環境和平台支持。與 memcached 伺服器通信的介面有很多,並常常具有針對所有語言的多個實現。參見參考資料 以獲得常用的庫和工具箱。
要列出所有受支持的介面和環境不太可能,但它們均支持 memcached 協議提供的基礎 API。這些描述已經被簡化並應用在不同語言的上下文內,在這些語言中,使用不同的值可指示錯誤。主要的函數有:
get(key) — 從存儲了特定鍵的 memcached 獲得信息。 如果鍵不存在,就返回錯誤。
set(key, value [, expiry]) — 使用緩存內的標識符鍵存儲這個特定的值。如果鍵已經存在,那麼它就會被更新。期滿時間的單位為秒,並且如果值小於 30 天 (30*24*60*60),那麼就用作相對時間,如果值大於 30 天,那麼就用作絕對時間 (epoch)。
add(key, value [, expiry]) — 如果鍵不存在就將這個鍵添加到緩存內,如果鍵已經存在就返回錯誤。如果您想要顯式地添加一個新鍵而又不會因它已經存在而更新它,那麼這個函數將十分有用。
replace(key, value [, expiry]) — 更新此特定鍵的值,如果鍵不存在就返回一個錯誤。
delete(key [, time]) — 從緩存中刪除此鍵/值對。如果您提供一個時間,那麼添加具有此鍵的一個新值就會被阻塞這個特定的時期。超時讓您可以確保此值總是可以重新讀取自您的數據中心。
incr(key [, value]) — 為特定的鍵增 1 或特定的值。只適用於數值。
decr(key [, value]) — 為特定的鍵減 1 或特定的值,只適用於數值。
flush_all — 讓緩存內的所有當前條目無效(或到期失效)。
比如,在 Perl 內,基本 set 操作可以如清單 1 所示的那樣處理。

清單 1. Perl 內的基本 set 操作

use Cache::Memcached;

my $cache = new Cache::Memcached {
'servers' => [
'localhost:11211',
],
};

$cache->set('mykey', 'myvalue');

Ruby 內的相同的基本操作如清單 2 所示。

清單 2. Ruby 內的基本 set 操作

require 'memcache'
memc = MemCache::new '192.168.0.100:11211'

memc["mykey"] = "myvalue"

在兩個例子中可以看到相同的基本結構:設置 memcached 伺服器,然後分配或設置值。其他的介面也可用,包括適合於 Java 技術的那些介面,讓您可以在 WebSphere 應用程序內使用 memcached。memcached 介面類允許將 Java 對象直接序列化到 memcached 以便於存儲和載入復雜的結構。當在像 WebSphere 這樣的環境內進行部署時,有兩個事情非常重要:服務的彈性(在 memcached 不可用時如何做)以及如何提高緩存存儲量來改進在使用多個應用程序伺服器或在使用像 WebSphere eXtreme Scale 這樣的環境時的性能。我們接下來就來看看這兩個問題。
七、彈性和可用性
有關 memcached 最常見的一個問題是:「若緩存不可用了,會發生什麼情況呢?」正如之前章節中明示的,緩存內的信息不應該成為信息的的惟一資源。必須要能夠從其他位置載入存儲在緩存內的數據。
雖然,無法從緩存訪問信息將會減緩應用程序的性能,但它不應該阻止應用程序的運轉。可能會發生這樣幾個場景:
如果 memcached 服務宕掉,應用程序應該回退到從原始數據源載入信息並對信息進行顯示所需的格式化。此應用程序還應繼續嘗試在 memcached 內載入和存儲信息。
一旦 memcached 伺服器恢復可用,應用程序就應該自動嘗試存儲數據。沒有必要強制重載已緩存了的數據,可以使用標準的訪問來用信息載入和填充緩存。最終,緩存將會被最常用的數據重新填充。
再次重申,memcached 是信息的緩存但並非惟一的數據源。memcached 伺服器不可用不應該是應用程序的終結,雖然這意味著在 memcached 伺服器恢復正常之前性能會有所降低。實際上,memcached 伺服器相對簡單,並且雖然不是絕對無故障的,但它的簡單性的結果就是它很少會出錯。
八、分配緩存
memcached 伺服器只是網路上針對一些鍵存儲值的一個緩存。如果有多台機器,那麼很自然地會想要在所有多餘機器上設置一個 memcached 的實例來提供一個超大的聯網 RAM 緩存存儲。
有了這個想法後,還有一種想當然是需要使用某種分配或復制機制來在機器之間復制鍵/值對。這種方式的問題是如果這么做反而會減少可用的 RAM 緩存,而不是增加。如圖 6 所示,可以看出這里有三個應用程序伺服器,每個伺服器都可以訪問一個 memcached 實例。
圖6.多重memcached實例的不正確使用

盡管每個 memcached 實例都是 1 GB 的大小(產生 3 GB 的 RAM 緩存),但如果每個應用程序伺服器只有其自己的緩存(或者在 memcached 之間存在著數據的復制),那麼整個安裝也仍只能有 1 GB 的緩存在每個實例間復制。
由於 memcached 通過一個網路介面提供信息,因此單個的客戶機可以從它所能訪問的任何一個 memcached 實例訪問數據。如果數據沒有跨每個實例被復制,那麼最終在每個應用程序伺服器上,就可以有 3 GB 的 RAM 緩存可用,如圖 7 所示。
圖7.多重memcached實例的正確使用

這個方法的問題是選擇哪個伺服器來儲存鍵/值對,以及當想要重新獲得一個值時,如何決定要與哪個 memcached 伺服器對話。問題的解決方案就是忽略復雜的東西,比如查找表,或是寄望 memcached 伺服器來為您處理這個過程。而 memcached 客戶機則必須要力求簡單。
memcached 客戶機不必決定此信息,它只需對在存儲信息時指定的鍵使用一個簡單的散列演算法。當想要從一列 memcached 伺服器存儲或獲取信息時,memcached 客戶機就會用一個一致的散列演算法從這個鍵獲取一個數值。舉個例子,鍵 mykey 被轉換成數值 23875 。是保存還是獲取信息無關緊要,這個鍵將總是被用作惟一標識符來從 memcached 伺服器載入,因此在本例中,「mykey」 散列轉化後對應的值總是 23875。
如果有兩個伺服器,那麼 memcached 客戶機將對這個數值進行一個簡單的運算(例如,系數)來決定它應將此值存儲在第一個還是第二個配置了的 memcached 實例上。
當存儲一個值時,客戶機會從這個鍵確定出散列值以及它原來存儲在哪個伺服器上。當獲取一個值時,客戶機會從這個鍵確定出相同的散列值並會選擇相同的伺服器來獲取信息。
如果在每個應用程序伺服器上使用的是相同的伺服器列表(並且順序相同),那麼當需要保存或檢索同一個鍵時,每個應用程序伺服器都將選擇同一個 伺服器。現在,在這個例子中,有 3GB 的 memcached 空間可以共享,而不是同一個 1 GB 的空間的復制,這就帶來了更多的可用緩存,並很有可能會提高有多個用戶情況下的應用程序的性能。
九、如何能不使用memcached?
盡管 memcached 很簡單,但 memcached 實例有時候還是會被不正確地使用。
memcached不是一個資料庫
最常見的 memcached 誤用就是把它用作一個數據存儲,而不是一個緩存。memcached 的首要目的就是加快數據的響應時間,否則數據從其他數據源構建或恢復需要很長時間。一個典型的例子就是從一個資料庫中恢復信息,特別是在信息顯示給用戶前 需要對信息進行格式化或處理的時候。Memcached 被設計用來將信息存儲在內存中以避免每次在數據需要恢復時重復執行相同的任務。
切不可將 memcached 用作運行應用程序所需信息的惟一信息源;數據應總是可以從其他信息源獲取。此外,要記住 memcached 只是一個鍵/值的存儲。不能在數據上執行查詢,或者對內容進行迭代來提取信息。應該使用它來存儲數據塊或對象以備批量使用。
不要緩存資料庫行或文件
雖然可以使用 memcached 存儲載入自資料庫的數據行,但這實際上是查詢緩存,並且大多數資料庫都提供各自的查詢緩存的機制。其他的對象,比如文件系統的圖像或文件的情況與此相同。很多應用程序和 web 伺服器針對此類工作已經有了一些很好的解決方案。
如果在載入和格式化後,使用它來存儲全部信息塊,就可以從 memcached 獲得更多的實用工具和性能上的改善。仍以我們的博客站點為例,存儲信息的最佳點是在將博客類別格式化為對象,甚至是在格式化成 HTML 後。博客頁面的構造可通過從 memcached 載入各個組件(比如 blog post、category list、post history 等)並將完成的 HTML 寫回至客戶機實現。
memcached並不安全
為了確保最佳性能,memcached 並未提供任何形式的安全性,沒有身份驗證,也沒有加密。這意味著對 memcached 伺服器的訪問應該這么處理:一是通過將它們放到應用程序部署環境相同的私有側,二是如果安全性是必須的,那麼就使用 UNIX® socket 並只允許當前主機上的應用程序訪問此 memcached 伺服器。
這多少犧牲了一些靈活性和彈性,以及跨網路上的多台機器共享 RAM 緩存的能力,但這是在目前的情況下確保 memcached 數據安全性的惟一一種解決方案。
十、不要限制自己
除了不應該使用 memcached 實例的情況外,memcached 的靈活性不應忽視。由於 memcached 與應用程序處於相同的架構水平,所以很容易集成並連接到它。並且更改應用程序以便利用 memcached 也並不復雜。此外,由於 memcached 只是一個緩存,所以在出現問題時它不會停止應用程序的執行。如果使用正確的話,它所做的是減輕其餘伺服器基礎設施的負載(減少對資料庫和數據源的讀操 作),這意味著無需更多的硬體就可以支持更多的客戶機。
但請記住,它僅僅是個緩存!
結束語
在本文中,我們了解了 memcached 以及如何最佳地使用它。我們看到了信息如何存儲、如何選擇合理的鍵以及如何選擇要存儲的信息。我們還討論了所有 memcached 用戶都要遇到的一些關鍵的部署問題,包括多伺服器的使用、當 memcached 實例消亡時該怎麼做,以及(也許最為重要的)在哪些情況下不能使用 memcached。
作為一種開源的應用程序並且是目的簡單而直白的應用程序,memcached 的功能和實用性均來自於這種簡單性。通過為信息提供巨大的 RAM 存儲空間、讓它在網路上可用,然後再讓它可通過各種不同的介面和語言訪問到,memcached 可被集成到多種多樣的安裝和環境中。

『伍』 緩存的分布緩存

分布式緩存系統是為了解決資料庫伺服器和web伺服器之間的瓶頸。如果一個網站的流量很大,這個瓶頸將會非常明顯,每次資料庫查詢耗費的時間將會非常可觀。對於更新速度不是很快的網站,我們可以用靜態化來避免過多的資料庫查詢。對於更新速度以秒計的網站,靜態化也不會太理想,可以用緩存系統來構建。如果只是單台伺服器用作緩存,問題不會太復雜,如果有多台伺服器用作緩存,就要考慮緩存伺服器的負載均衡。
使用Memcached分布式緩存服務來達到保存用戶的會話數據,而達到各個功能模塊都能夠跨省份、跨伺服器共享本次會話中的私有數據的目的。每個省份使用一台伺服器來做為Memcached伺服器來存儲用話的會話中的數據,當然也可以多台伺服器,但必須確保每個省份的做Memcached伺服器數量必須一致,這樣才能夠保證Memcached客戶端操作的是同一份數據,保證數據的一致性。
會話數據的添加、刪除、修改
Memcached客戶端,添加、刪除和、修改會話信息數據時,不僅要添加、刪除、修改本省的Memcached伺服器數據,而且同時要對其它省份的Memcahed伺服器做同樣的操作,這樣用戶訪問其它省份的伺服器的功能模塊進也能讀取到相同的會話數據。Memcached客戶端伺服器的列表使用區域網的內網IP(如:192.168.1.179)操作本省的Memcahed伺服器,使用公網的IP((如:202.183.62.210))操作其它省份的Memcahe伺服器。
會話數據的讀取
系統所有模塊讀取會話數據的Memcached客戶端伺服器列表都設為本省Memcached伺服器地址的內網IP來向Memcahed伺服器中讀取會話數據。
同一會話的確認
使用Cookie來保持客戶與服務端的聯系。每一次會話開始就生成一個GUID作為SessionID,保存在客戶端的Cookie中,作用域是頂級域名,這樣二級、三級域名就可以共享到這個Cookie,系統中就使用這個SessionID來確認它是否是同一個會話。
會話數據的唯一ID
會話數據存儲在Memcached伺服器上的唯一鍵Key也就是會話數據數據的唯一ID定義為:SessionID_Name, SessionID就是保存在客戶端Cookie中的SessionID,Name就是會話數據的名稱,同一次會話中各個會話數據的Name必須是唯一的,否則新的會話數據將覆蓋舊的會話數據。
會話的失效時間
會話的失效通過控制Cookie的有效時間來實現,會話的時間設為SessionID或Cookie中的有效時間,且每一次訪問SessionID時都要重新設置一下Cookie的有效時間,這樣就達到的會話的有效時間就是兩次間訪問Cookie中SessionID值的的最長時間,如果兩次訪問的間隔時間超過用效時間,保存在SessionID的Cookie將會失效,並生成新的SessionID存放在Cookie中, SessionID改變啦,會話就結束啦。Memcached伺服器中會話數據的失效,每一次向Memcache伺服器中添加會話數據時,都把有效時間設為一天也就是24小時,讓Memcached服務使用它內部的機制去清除,不必在程序中特別做會話數據的刪除操作。數據在Memcache伺服器中有有效時間只是邏輯上的,就算是過了24 小時,如果分配給Memcached服務的內存還夠用的話,數據還是保存在內存當中的,只是Memcache客戶端讀取不到而已。只有到了分配給Memcached服務的內存不夠用時,它才會清理沒用或者比較舊的數據,也就是懶性清除。

『陸』 緩存系統中的主要使用的數據結構是什麼

緩存系統中的主要使用的數據結構是memcached。

memcached是一套分布式的高速緩存系統,由LiveJournal的Brad Fitzpatrick開發,但被許多網站使用。這是一套開放源代碼軟體,以BSD license授權發布。

memcached的API使用三十二比特的循環冗餘校驗(CRC-32)計算鍵值後,將數據分散在不同的機器上。當表格滿了以後,接下來新增的數據會以LRU機制替換掉。

由於memcached通常只是當作緩存系統使用,所以使用memcached的應用程序在寫回較慢的系統時(像是後端的資料庫)需要額外的代碼更新memcached內的數據。

(6)memcached緩存分布擴展閱讀:

一、存儲方式

為了提高性能,memcached中保存的數據都存儲在memcached內置的內存存儲空間中。由於數據僅存在於內存中,因此重啟memcached、重啟操作系統會導致全部數據消失。

另外,內容容量達到指定值之後,就基於LRU(Least Recently Used)演算法自動刪除不使用的緩存。memcached本身是為緩存而設計的伺服器,因此並沒有過多考慮數據的永久性問題。

二、通信分布式

memcached盡管是「分布式」緩存伺服器,但伺服器端並沒有分布式功能。各個memcached不會互相通信以共享信息。那麼,怎樣進行分布式呢?這完全取決於客戶端的實現。本文也將介紹memcached的分布式。

『柒』 memcached 緩存什麼數據

memcached 是流行的key/value緩存軟體。就是說緩存的內容是以key/value對的形式緩存的。只要值可以被序列化且大小不超過系統限制均可緩存。一般用來緩存代碼表,頻繁使用的查詢結果等。

『捌』 php的memcached分布式hash演算法,如何解決分布不均crc32這個演算法沒辦法把key值均勻的分布出去

memcached的總結和分布式一致性hash
當前很多大型的web系統為了減輕資料庫伺服器負載,會採用memchached作為緩存系統以提高響應速度。
目錄: (http://hounwang.com/lesson.html)
memchached簡介
hash
取模
一致性hash
虛擬節點
源碼解析
參考資料
1. memchached簡介
memcached是一個開源的高性能分布式內存對象緩存系統。
其實思想還是比較簡單的,實現包括server端(memcached開源項目一般只單指server端)和client端兩部分:
server端本質是一個in-memory key-value store,通過在內存中維護一個大的hashmap用來存儲小塊的任意數據,對外通過統一的簡單介面(memcached protocol)來提供操作。
client端是一個library,負責處理memcached protocol的網路通信細節,與memcached server通信,針對各種語言的不同實現分裝了易用的API實現了與不同語言平台的集成。
web系統則通過client庫來使用memcached進行對象緩存。
2. hash
memcached的分布式主要體現在client端,對於server端,僅僅是部署多個memcached server組成集群,每個server獨自維護自己的數據(互相之間沒有任何通信),通過daemon監聽埠等待client端的請求。
而在client端,通過一致的hash演算法,將要存儲的數據分布到某個特定的server上進行存儲,後續讀取查詢使用同樣的hash演算法即可定位。
client端可以採用各種hash演算法來定位server:
取模
最簡單的hash演算法
targetServer = serverList[hash(key) % serverList.size]
直接用key的hash值(計算key的hash值的方法可以自由選擇,比如演算法CRC32、MD5,甚至本地hash系統,如java的hashcode)模上server總數來定位目標server。這種演算法不僅簡單,而且具有不錯的隨機分布特性。
但是問題也很明顯,server總數不能輕易變化。因為如果增加/減少memcached server的數量,對原先存儲的所有key的後續查詢都將定位到別的server上,導致所有的cache都不能被命中而失效。
一致性hash
為了解決這個問題,需要採用一致性hash演算法(consistent hash)
相對於取模的演算法,一致性hash演算法除了計算key的hash值外,還會計算每個server對應的hash值,然後將這些hash值映射到一個有限的值域上(比如0~2^32)。通過尋找hash值大於hash(key)的最小server作為存儲該key數據的目標server。如果找不到,則直接把具有最小hash值的server作為目標server。
為了方便理解,可以把這個有限值域理解成一個環,值順時針遞增。
如上圖所示,集群中一共有5個memcached server,已通過server的hash值分布到環中。
如果現在有一個寫入cache的請求,首先計算x=hash(key),映射到環中,然後從x順時針查找,把找到的第一個server作為目標server來存儲cache,如果超過了2^32仍然找不到,則命中第一個server。比如x的值介於A~B之間,那麼命中的server節點應該是B節點
可以看到,通過這種演算法,對於同一個key,存儲和後續的查詢都會定位到同一個memcached server上。
那麼它是怎麼解決增/刪server導致的cache不能命中的問題呢?
假設,現在增加一個server F,如下圖
此時,cache不能命中的問題仍然存在,但是只存在於B~F之間的位置(由C變成了F),其他位置(包括F~C)的cache的命中不受影響(刪除server的情況類似)。盡管仍然有cache不能命中的存在,但是相對於取模的方式已經大幅減少了不能命中的cache數量。
虛擬節點
但是,這種演算法相對於取模方式也有一個缺陷:當server數量很少時,很可能他們在環中的分布不是特別均勻,進而導致cache不能均勻分布到所有的server上。
如圖,一共有3台server – 1,2,4。命中4的幾率遠遠高於1和2。
為解決這個問題,需要使用虛擬節點的思想:為每個物理節點(server)在環上分配100~200個點,這樣環上的節點較多,就能抑制分布不均勻。
當為cache定位目標server時,如果定位到虛擬節點上,就表示cache真正的存儲位置是在該虛擬節點代表的實際物理server上。
另外,如果每個實際server的負載能力不同,可以賦予不同的權重,根據權重分配不同數量的虛擬節點。
// 採用有序map來模擬環
this.consistentBuckets = new TreeMap();
MessageDigest md5 = MD5.get();//用MD5來計算key和server的hash值
// 計算總權重
if ( this.totalWeight for ( int i = 0; i < this.weights.length; i++ )
this.totalWeight += ( this.weights[i] == null ) ? 1 : this.weights[i];
} else if ( this.weights == null ) {
this.totalWeight = this.servers.length;
}
// 為每個server分配虛擬節點
for ( int i = 0; i < servers.length; i++ ) {
// 計算當前server的權重
int thisWeight = 1;
if ( this.weights != null && this.weights[i] != null )
thisWeight = this.weights[i];
// factor用來控制每個server分配的虛擬節點數量
// 權重都相同時,factor=40
// 權重不同時,factor=40*server總數*該server權重所佔的百分比
// 總的來說,權重越大,factor越大,可以分配越多的虛擬節點
double factor = Math.floor( ((double)(40 * this.servers.length * thisWeight)) / (double)this.totalWeight );
for ( long j = 0; j < factor; j++ ) {
// 每個server有factor個hash值
// 使用server的域名或IP加上編號來計算hash值
// 比如server - "172.45.155.25:11111"就有factor個數據用來生成hash值:
// 172.45.155.25:11111-1, 172.45.155.25:11111-2, ..., 172.45.155.25:11111-factor
byte[] d = md5.digest( ( servers[i] + "-" + j ).getBytes() );
// 每個hash值生成4個虛擬節點
for ( int h = 0 ; h < 4; h++ ) {
Long k =
((long)(d[3+h*4]&0xFF) << 24)
| ((long)(d[2+h*4]&0xFF) << 16)
| ((long)(d[1+h*4]&0xFF) << 8 )
| ((long)(d[0+h*4]&0xFF));
// 在環上保存節點
consistentBuckets.put( k, servers[i] );
}
}
// 每個server一共分配4*factor個虛擬節點
}
// 採用有序map來模擬環
this.consistentBuckets = new TreeMap();
MessageDigest md5 = MD5.get();//用MD5來計算key和server的hash值
// 計算總權重
if ( this.totalWeight for ( int i = 0; i < this.weights.length; i++ )
this.totalWeight += ( this.weights[i] == null ) ? 1 : this.weights[i];
} else if ( this.weights == null ) {
this.totalWeight = this.servers.length;
}
// 為每個server分配虛擬節點
for ( int i = 0; i < servers.length; i++ ) {
// 計算當前server的權重
int thisWeight = 1;
if ( this.weights != null && this.weights[i] != null )
thisWeight = this.weights[i];
// factor用來控制每個server分配的虛擬節點數量
// 權重都相同時,factor=40
// 權重不同時,factor=40*server總數*該server權重所佔的百分比
// 總的來說,權重越大,factor越大,可以分配越多的虛擬節點
double factor = Math.floor( ((double)(40 * this.servers.length * thisWeight)) / (double)this.totalWeight );
for ( long j = 0; j < factor; j++ ) {
// 每個server有factor個hash值
// 使用server的域名或IP加上編號來計算hash值
// 比如server - "172.45.155.25:11111"就有factor個數據用來生成hash值:
// 172.45.155.25:11111-1, 172.45.155.25:11111-2, ..., 172.45.155.25:11111-factor
byte[] d = md5.digest( ( servers[i] + "-" + j ).getBytes() );
// 每個hash值生成4個虛擬節點
for ( int h = 0 ; h < 4; h++ ) {
Long k =
((long)(d[3+h*4]&0xFF) << 24)
| ((long)(d[2+h*4]&0xFF) << 16)
| ((long)(d[1+h*4]&0xFF) << 8 )
| ((long)(d[0+h*4]&0xFF));
// 在環上保存節點
consistentBuckets.put( k, servers[i] );
}
}
// 每個server一共分配4*factor個虛擬節點
}
// 用MD5來計算key的hash值
MessageDigest md5 = MD5.get();
md5.reset();
md5.update( key.getBytes() );
byte[] bKey = md5.digest();

// 取MD5值的低32位作為key的hash值
long hv = ((long)(bKey[3]&0xFF) << 24) | ((long)(bKey[2]&0xFF) << 16) | ((long)(bKey[1]&0xFF) << 8 ) | (long)(bKey[0]&0xFF);

// hv的tailMap的第一個虛擬節點對應的即是目標server
SortedMap tmap = this.consistentBuckets.tailMap( hv );
return ( tmap.isEmpty() ) ? this.consistentBuckets.firstKey() : tmap.firstKey();
更多問題到問題求助專區(http://bbs.hounwang.com/)

『玖』 如何快速高效的更新memcached緩存數據

memcache伺服器,要特殊配置,內存要大,其他硬體能用即可其他解決方案:可以配置分布式緩存因為memcache一般是只供區域網使用的工作原理是:web伺服器使用memcache緩存,然後把數據緩存在memcache伺服器上,memecache只用到內存數據量過大隻能增加伺服器,部署分布式緩存其他可以再聯系

『拾』 memcached 緩存在哪兒。。我實驗成功了。但是我不知道他緩存在哪兒。求指點。

緩存在內存里。
telnet localhost xxxx #xxx是埠號,就能查看memcached的狀態了,可以使用命令stats~