天天看點

Memcache筆記(1)

緩存主要分為:頁面緩存和資料緩存 Memcache 、redis、mongodb都是做資料緩存的 

Memcache是什麼?

  是一個高性能的分布式的記憶體對象緩存系統,通過在記憶體裡維護一個統一的巨大的hash表,它能夠用來存儲各種格式的資料,包括圖像、視訊、檔案以及資料庫檢索的結果等。簡單的說就是将資料調用到記憶體中,然後從記憶體中讀取,進而大大提高讀取速度。 Memcache緩存什麼資料? Memcache将資料存放在記憶體中,還可用于緩存其他東西,例如圖檔、視訊等等。

Memcache如何存值?

  MemCaChe是一個存儲鍵值對的HashMap,在記憶體中對任意的資料(比如字元串、對象等)所使用的key-value存儲,資料可以來自資料庫調用、API調用,或者頁面渲染的結果。MemCache設計理念就是小而強大,它簡單的設計促進了快速部署、易于開發并解決面對大規模的資料緩存的許多難題,而所開放的API使得MemCache能用于Java、C/C++/C#、Perl、Python、PHP、Ruby等大部分流行的程式語言。

什麼場合用memcache?

  Memcache是分布式的記憶體對象緩存系統,而那些不需要分布的,不需要共享的,或者幹脆規模小到隻有一台伺服器的應用,memcached不會帶來任何好處,相反還會拖慢系統效率,因為網絡連接配接同樣需要資源。Memcached在很多時候都是作為資料庫前端cache使用,因為他比資料庫少了很多sql解析、磁盤操作等開銷,而且它是使用記憶體來管理資料的, 是以它可以提供比直接讀取資料庫更好的性能,在大型系統中,通路同樣的資料是很頻繁的,memcached可以大大降低資料庫壓力,使系統執行效率提升。 另外,memcached也經常作為伺服器之間資料共享的存儲媒介,例如在SSO系統中儲存系統單點登陸狀态的資料就可以儲存在memcached 中,被多個應用共享。

  需要注意的是,memcached使用記憶體管理資料,是以它是易失的,當伺服器重新開機,或者memcached程序中止,資料便會丢失,是以memcached不能用來持久儲存資料。很多人的錯誤了解,memcached的性能非常好,好到了記憶體和硬碟的對比程度,其實memcached使用 記憶體并不會得到成百上千的讀寫速度提高,它的實際瓶頸在于網絡連接配接,它和使用磁盤的資料庫系統相比,好處在于它本身非常“輕”,因為沒有過多的開銷和直接 的讀寫方式,它可以輕松應付非常大的資料交換量,是以經常會出現兩條千兆網絡帶寬都滿負荷了,memcached程序本身并不占用多少CPU資源的情 況 。

  MemCache雖然被稱為"分布式緩存",但是MemCache本身完全不具備分布式的功能,MemCache叢集之間不會互相通信(與之形成對比的,比如JBoss Cache,某台伺服器有緩存資料更新時,會通知叢集中其他機器更新緩存或清除緩存資料),所謂的"分布式",完全依賴于用戶端程式的實作。

Memcache通路模型:

Memcache筆記(1)

Memcache一次寫緩存的流程:

  1、應用程式輸入需要寫緩存的資料;

  2、API将Key輸入路由算法子產品,路由算法根據Key和MemCache叢集伺服器清單得到一台伺服器編号;

  3、由伺服器編号得到MemCache及其的ip位址和端口号

  4、API調用通信子產品和指定編号的伺服器通信,将資料寫入該伺服器,完成一次分布式緩存的寫操作

  注:讀緩存和寫緩存一樣,隻要使用相同的路由算法和伺服器清單,隻要應用程式查詢的是相同的Key,MemCache用戶端總是通路相同的用戶端去讀取資料,隻要伺服器中還緩存着該資料,就能保證緩存命中。

   這種MemCache叢集的方式也是從分區容錯性的方面考慮的,假如Node2當機了,那麼Node2上面存儲的資料都不可用了,此時由于叢集中Node0和Node1還存在,下一次請求Node2中存儲的Key值的時候,肯定是沒有命中的,這時先從資料庫中拿到要緩存的資料,然後路由算法子產品根據Key值在Node0和Node1中選取一個節點,把對應的資料放進去,這樣下一次就又可以走緩存了,這種叢集的做法很好,但是缺點是成本比較大。

  從上圖看出對伺服器叢集的管理,路由的算法至關重要,其實路由的算法就和負載均衡差不多,他決定着究竟該通路叢集中的哪一台伺服器,路由算法主要有:餘數hash 一緻性hash

  餘數hash: 餘數hash他可以保證緩存資料在整個memcache伺服器叢集中均衡分布,但是如果考慮到伺服器叢集的伸縮性,那餘數hash就遠遠不能解決了!

  一緻性hash: 一緻性hash算法就是通過一個叫做一緻性hash環的資料結構實作key到緩存伺服器的hash映射!

  

Memcache筆記(1)

  

Memcache筆記(1)

  緩存伺服器叢集擴容

  

Memcache筆記(1)

  Hashcode 就是一個簽名。當兩個對象的hashcode一樣時,兩個對象就有可能一樣。如果不一樣的話兩個對象就肯定不一樣。一般用hashcode來進行比較兩個東西是不是一樣的,可以很容易的排除許多不一樣的東西。 最常用的地方就是在一堆東西裡找一個東西。先用你要找的東西的hashcode和所有東西的hashcode比較,如果不一樣的話就肯定不是你要找的東西。如果一樣的話就很可能是你要找的東西。然後再進行仔細的比較兩個東西是不是真的一模一樣。

  兩個不同的東西的hashcode可以是一樣的,不過這樣會減慢運作速度,是以盡量避免(也就是所謂的碰撞)

  一緻性hash缺點:

  1、原有節點1,2,3,在2和3之間加入節點4,那麼影響的就是2與4之間的路徑,那麼節點3上的通路量就會減少,給節點4,但是節點1,2,不受影響,如果1,2,3,4的配置性能都一樣,這樣負載不均衡的問題不是我們所想要的!

  2、如有三個節點Node1,Node2,Node3,分布在環上時三個節點挨的很近,落在環上的key尋找節點時,大量key順時針總是配置設定給Node2,而其它兩個節點被找到的機率都會很小。

  解決方法:改善Hash算法,均勻配置設定各節點到環上;[引文]使用虛拟節點的思想,為每個實體節點(伺服器)在圓上配置設定100~200個點。這樣就能抑制分布不均勻,最大限度地減小伺服器增減時的緩存重新分布。使用者資料映射在虛拟節點上,就表示使用者資料真正存儲位置是在該虛拟節點代表的實際實體伺服器上

  memcache怎麼啟動多個伺服器?

  php操作memcache可以利用Memcache::addServer添加多台memcache伺服器 $memcache = new memcahce; $memcache->addServer($ip1,11211); $memcache->addServer($ip2,11211);

  memcache實作原理:

  memcache要比傳統的關系型資料庫查詢速度要快的多,因為傳統的關系型資料庫要保持資料的持久性,是以要把資料存在硬碟裡面,導緻IO操作速度慢!!而memcache的重新開機将會意味着資料的丢失!MemCache的資料存放在記憶體中,會受到機器位數的限制,32位機器最多隻能使用2GB的記憶體空間,64位機器可以認為沒有上限!

  slab_class、slab、page、chunk的簡單介紹:

  1、MemCache将記憶體空間分為一組slab

  2、每個slab下又有若幹個page,每個page預設是1M,如果一個slab占用100M記憶體的話,那麼這個slab下應該有100個page

  3、每個page裡面包含一組chunk,chunk是真正存放資料的地方,同一個slab裡面的chunk的大小是固定的

  4、有相同大小chunk的slab被組織在一起,稱為slab_class MemCache記憶體配置設定的方式稱為allocator,slab的數量是有限的,幾個、十幾個或者幾十個,這個和啟動參數的配置相關 相鄰slab内的chunk基本以1.25為比例進行增長,MemCache啟動時可以用-f指定這個比例)

  Memcache優化

  1,-n 參數的設定,注意将此參數設定為1024可以整除的數(還要考慮48B的內插補點),否則餘下來的部分就浪費了。

  2,不要存儲超過1m的資料。因為要拆成多個chunk,計算和時間成本都成倍增加。

  3,善用stats指令檢視memcached狀态。

  4,消滅eviction(被删除的資料)。造成eviction是因為記憶體不夠,有三個思路:

     一是在CPU有餘力的情況下開啟壓縮(PHP擴充);

     二是增加記憶體;

     三是調整-f參數,減少記憶體浪費。

  5,調整業務代碼,提高命中率。

  6,緩存小資料。省帶寬,省網絡I/O時間,省記憶體。

  7,根據業務特點,為資料尺寸區間小的業務配置設定專用的memcached執行個體。這樣可以調小 -f 參數,使資料集中存在少數幾個slab上,記憶體浪費較少。

  Memcache不夠用了怎麼辦?存放的時候報一個out of memory的錯。

  MemCache會把這個slab中最近最少使用的chunk中的資料清理掉,然後放上最新的資料

  MemCache的記憶體配置設定及回收算法,總結三點:

  1、MemCache的記憶體配置設定chunk裡面會有記憶體浪費,88位元組的value配置設定在128位元組(緊接着大的用)的chunk中,就損失了30位元組,但是這也避免了管理記憶體碎片的問題

  2、MemCache的LRU算法不是針對全局的,是針對slab的

  3、應該可以了解為什麼MemCache存放的value大小是限制的,因為一個新資料過來,slab會先以page為機關申請一塊記憶體,申請的記憶體最多就隻有1M,是以value大小自然不能大于1M了

  分布式: 将不同的鍵儲存到不同的伺服器上,就實作了memcached的分布式。 memcached伺服器增多後,鍵就會分散,即使一台memcached伺服器發生故障無法連接配接,也不會影響其他的緩存,系統依然能繼續運作

  memcache的使用率為什麼是70%?怎麼提高?

  chunk塊的大小可以為64B,128B,256B...1024KB .使用何種大小的chunk塊是由memcache根據資料的長度來決定的.

  MemCache的記憶體配置設定chunk裡面會有記憶體浪費,88位元組的value配置設定在128位元組(緊接着大的用)的chunk中,就損失了30位元組

  提高: 如果預先知道用戶端發送的資料的公用大小,或者僅緩存大小相同的資料的情況下,隻要使用适合資料大小的組的清單,就可以減少浪費。以上的操作還沒有實作,但是我們可以調節slab class 的大小的差别注意:

  1. 不能往memcached存儲一個大于1MB的資料. 

  2. 往memcached存儲的所有資料,如果資料的大小分布于各種chunk大小區間,從64B到1MB都有,可能會造成記憶體的極大浪費以及memcached的異常.

    命中率

      命中:直接從緩存中讀取到想要的資料。

      不命中:緩存中沒有想要的資料,還需要到資料庫進行一次查詢才能讀取到想要的資料。

      命中率越高,資料庫查詢的次數就越少。 讀取緩存的速度遠比資料庫查詢的速度高得多。 是以命中率越高,性能越高。

  Memcached是以守護程式(監聽)方式運作于一個或多個伺服器中,随時會接收用戶端的連接配接和操作!

  注意:

    1.memcache已經配置設定的記憶體不會再主動清理。

    2. memcache配置設定給某個slab的記憶體頁不能再配置設定給其他slab。

    3. flush_all不能重置memcache配置設定記憶體頁的格局,隻是給所有的item置為過期。

    4. memcache最大存儲的item(key+value)大小限制為1M,這由page大小1M限制

    5.由于memcache的分布式是用戶端程式通過hash算法得到的key取模來實作,不同的語言可能會采用不同的hash算法,同樣的用戶端程式也有可能使用相異的方法,是以在多語言、多子產品共用同一組memcached服務時,一定要注意在用戶端選擇相同的hash算法

    6.啟動memcached時可以通過-M參數禁止LRU替換,在記憶體用盡時add和set會傳回失敗

    7.memcached啟動時指定的是資料存儲量,沒有包括本身占用的記憶體、以及為了儲存資料而設定的管理空間。是以它占用的記憶體量會多于啟動時指定的記憶體配置設定量,這點需要注意。

    8.memcache存儲的時候對key的長度有限制,php和C的最大長度都是250

  什麼樣的業務用到memcache?

  一、經常被讀取并且實時性要求不強可以等到自動過期的資料。例如網站首頁最新文章清單、某某排行等資料。也就是雖然新資料産生了,但對使用者體驗不會産生任何影響的場景。 這類資料就使用典型的緩存政策,設定一過合理的過期時間,當資料過期以後再從資料庫中讀取。當然你得制定一個緩存清除政策,便于編輯或者其它人員能馬上看到效果。

  二、經常被讀取并且實時性要求強的資料。比如使用者的好友清單,使用者文章清單,使用者閱讀記錄等。 這類資料首先被載入到memcached中,當發生更改(添加、修改、删除)時就清除緩存。在緩存的時候,我将查詢的SQL語句md5()得到它的 hash值作為key,結果數組作為值寫入memcached,并且将該SQL涉及的table_name以及hash值配對存入memcached中。 當更改了這個表時,我就将與此表相配對的key的緩存全部删除。

  三、統計類緩存,比如文章浏覽數、網站PV等 此類緩存是将在資料庫的中來累加的資料放在memcached來累加。擷取也通過memcached來擷取。但這樣就産生了一個問題,如果 memcached伺服器down掉的話這些資料就有可能丢失,是以一般使用memcached的永固性存儲,這方面我們新浪使用memcachedb。

  四、活躍使用者的基本資訊或者某篇熱門文章。 此類資料的一個特點就是資料都是一行,也就是一個一維數組,當資料被update時(比如修改昵稱、文章的評論數),在更改資料庫資料的同時,使用Memcache::replace替換掉緩存裡的資料。這樣就有效了避免了再次查詢資料庫。

  五、session資料 使用memcached來存儲session的效率是最高的。memcached本身也是非常穩定的,不太用擔心它會突然down掉引起session資料的丢失,即使丢失就重新登入了,也沒啥。

  怎麼添加緩存,清除緩存 Cmd上清除?

  flush_all 清空所有鍵值,但不會删除items,是以此時MemCache依舊占用記憶體

  quit關閉連接配接

  add  無條件地設定一個Key值,沒有就增加,有就覆寫 

  set   按照相應的Key值添加資料,如果Key已經存在則會操作失敗

  replace  按照相應的Key值替換資料,如果Key值不存在則會操作失敗

轉載于:https://www.cnblogs.com/yyjie/p/7358932.html