網站緩存技術(Redis、Memcached、Ehcache)

Redis 是什麼?

    一般而言目前的數據庫分類有幾種,包括 SQL/NSQL,,關係數據庫,鍵值數據庫等等等. 分類的標準也不一,Redis本質上也是一種鍵值數據庫的,但它在保持鍵值數據庫簡單快捷特色的同時,又吸取了部分關係數據庫的優勢。從而使它的位置處於關係數據庫和鍵值數據庫之間。java

Redis不只能保存Strings類型的數據,還能保存Lists類型(有序)和Sets類型(無序)的數據,並且還能完成排序(SORT) 等高級功能,在實現INCR,SETNX等功能的時候,保證了其操做的原子性,除此之外,還支持主從複製等功能。

2 Redis用來作什麼?

        一般侷限點來講,Redis也以消息隊列的形式存在,做爲內嵌的List存在,知足實時的高併發需求。而一般在一個電商類型的數據處理過程之中,有關商品,熱銷,推薦排序的隊列,一般存放在Redis之中,期間也包擴Storm對於Redis列表的讀取和更新。

3 Redis的優勢

性能極高 – Redis能支持超過 100K+ 每秒的讀寫頻率。

豐富的數據類型 – Redis支持二進制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 數據類型操做。

原子 – Redis的全部操做都是原子性的,同時Redis還支持對幾個操做全並後的原子性執行。

豐富的特性 – Redis還支持 publish/subscribe, 通知, key 過時等等特性。

4 Redis的缺點

是數據庫容量受到物理內存的限制,不能用做海量數據的高性能讀寫,所以Redis適合的場景主要侷限在較小數據量的高性能操做和運算上。

    總結: Redis受限於特定的場景,專一於特定的領域之下,速度至關之快,目前還未找到能替代使用產品。mysql

 

Redis是一個開源的使用ANSI C語言編寫、支持網絡、可基於內存亦可持久化的日誌型、Key-Value數據庫,並提供多種語言的API。git

redis是一個key-value存儲系統。和Memcached相似,它支持存儲的value類型相對更多,包括string(字符串)、list(鏈表)、set(集合)、zset(sorted set --有序集合)和hash(哈希類型)。這些數據類型都支持push/pop、add/remove及取交集並集和差集及更豐富的操做,並且這些操做都是原子性的。在此基礎上,redis支持各類不一樣方式的排序。與memcached同樣,爲了保證效率,數據都是緩存在內存中。區別的是redis會週期性的把更新的數據寫入磁盤或者把修改操做寫入追加的記錄文件,而且在此基礎上實現了master-slave(主從)同步。github

Redis 是一個高性能的key-value數據庫。 redis的出現,很大程度補償了memcached這類key/value存儲的不足,在部 分場合能夠對關係數據庫起到很好的補充做用。它提供了Java,C/C++,C#,PHP,JavaScript,Perl,Object-C,Python,Ruby,Erlang等客戶端,使用很方便。web

Redis支持主從同步。數據能夠從主服務器向任意數量的從服務器上同步,從服務器能夠是關聯其餘從服務器的主服務器。這使得Redis可執行單層樹複製。存盤能夠有意無心的對數據進行寫操做。因爲徹底實現了發佈/訂閱機制,使得從數據庫在任何地方同步樹時,可訂閱一個頻道並接收主服務器完整的消息發佈記錄。同步對讀取操做的可擴展性和數據冗餘頗有幫助。redis

redis的存儲分爲內存存儲、磁盤存儲和log文件三部分,配置文件中有三個參數對其進行配置。算法

 

ü  相比memcached:sql

 

一、redis具備持久化機制,能夠按期將內存中的數據持久化到硬盤上。mongodb

memcached 的最大容量是受限的; 數據庫

二、redis具有binlog功能,能夠將全部操做寫入日誌,當redis出現故障,可依照binlog進行數據恢復。 

三、redis支持virtual memory,能夠限定內存使用大小,當數據超過閾值,則經過相似LRU的算法把內存中的最不經常使用數據保存到硬盤的頁面文件中。 

四、redis原生支持的數據類型更多,使用的想象空間更大。 

五、前面有位朋友所說起的一致性哈希,用在redis的sharding中,通常是在負載很是高須要水平擴展時使用。咱們尚未用到這方面的功能,通常的項目,單機足夠支撐併發了。redis 3.0將推出cluster,功能更增強大。

 

Redis相對Memcached來講功能和特性上的優點已經很明顯了。而對於性能,Redis做者的說法是平均到單個核上的性能,在單條數據不大的狀況下Redis更好。爲何這麼說呢,理由就是Redis是單線程運行的。

  由於是單線程運行,因此和Memcached的多線程相比,總體性能確定會偏低。

  由於是單線程運行,因此IO是串行化的,網絡IO和內存IO,所以當單條數據太大時,因爲須要等待一個命令的全部IO完成才能進行後續的命令,因此性能會受影響 

memcached是一種高性能的分佈式內存緩存系統,經過將數據存儲在內存中減小讀取數據庫的次數; 

許多Web應用都將數據保存到RDBMS中,應用服務器從中讀取數據並在瀏覽器中顯示。但隨着數據量的增大、訪問的集中,就會出現RDBMS的負擔加劇、數據庫響應惡化、網站顯示延遲等重大影響。  這時就該memcached大顯身手了。memcached是高性能的分佈式內存緩存服務器。通常的使用目的是,經過緩存數據庫查詢結果,減小數據庫訪問次數,以提升動態Web應用的速度、提升可擴展性。

 

網站技術高速發展的今天,緩存技術已經成爲大型網站的一個關鍵技術,緩存設計好壞直接關係的一個網站訪問的速度,以及購置服務器的數量,甚至影響到用戶的體驗。

網站緩存按照存放的地點不一樣,能夠分爲客戶端緩存、服務端緩存。

客戶端緩存

客戶端緩存又可分爲:瀏覽器緩存、網關或代理服務器緩存

網關或代理服務器緩存是將網頁緩存中網關服務器上,多用戶訪問同一個頁面時,將直接從網關服務器把頁面傳送給用戶。

瀏覽器緩存是最靠近用戶的緩存,若是啓用緩存,用戶在訪問同一個頁面時,將再也不從服務器下載頁面,而是從本機的緩存目錄中讀取頁面,而後再瀏覽器中展示這個頁面。

瀏覽器緩存的控制,能夠設置meta標籤,能夠設置數字,也能夠設置時間,以下:

<Meta http-equiv=」Expires」 Content=」3600″>

<Meta http-equiv=」Expires」 Content=」Wed, 26 Feb 1997 08:21:57 GMT」>

HTTP頭信息以下:

HTTP/1.1 200 OK

Date: Fri, 30 Oct 1998 13:19:41 GMT

Server: Apache/1.3.3 (Unix)

Cache-Control: max-age=3600, must-revalidate

Expires: Fri, 30 Oct 1998 14:19:41 GMT

Last-Modified: Mon, 29 Jun 1998 02:28:12 GMT

不過如今的網站爲了保證用戶訪問到最新的內容,通常不多采用瀏覽器緩存,取而代之的是更加靈活的服務器緩存。

服務端緩存

服務端緩存分爲:頁面緩存、數據緩存、數據庫緩存

一、頁面緩存

頁面緩存是將動態頁面直接生成靜態的頁面放在服務器端,用戶調取相同頁面時,靜態頁面將直接下載到客戶端,再也不須要經過程序的運行和數據庫的訪問,大大節約了服務器的負載。

早期的網站不少使用發佈系統來完成這個功能,在後臺發佈時將數據和頁面模板整合成靜態頁面,存放在硬盤中。但這樣的缺陷很明顯,一是後臺的程序的編寫很 複雜,二是緩存的控制只能經過人爲的方式來控制,這對一些更新十分頻繁的網站就是一個噩夢,網站可能在不停的作緩存的刪除和重建。固然後來出現了一些自動 更新這些緩存的框架,好比PHP的SMARTY模板技術,能夠定義緩存過時的時間,自動去更新這些緩存。這對一些信息發佈類網站已經確實適用了。

除了整個頁面的緩存技術,還有一種技術叫作「網頁片斷緩存技術」,將頁面的部分而不是所有進行緩存。表明做有ESI cache。

二、數據緩存

可是當WEB2.0興起的今天,信息的發佈已經再也不是管理員統一發布的了,而是全部的用戶都在發佈信息,用戶發佈完信息後固然是想看到這些信息,而不是等到緩存時間到刷新後纔看到這些數據,因而數據緩存的相關技術也就應運而生了。

比較有名的數據緩存框架有ehcache和 memcached。

ehcache有不少緩存的分支(包括頁面緩存的模塊),但最核心的模塊仍是它的數據緩存部分,好比,當ehcache和hibernate進行整合 時,能將查詢出的對象集合放入內存中,下次若是再查詢這個查詢,將直接從內存中返回這個數據集合,不須要再進行數據庫的查詢,同時,你能夠配置緩存的刷新 模式,有read-only,nonstrict-read-write,read-write 幾種模式,其中read-only表示緩存是不刷新的(要刷新就只有重啓了),nonstrict-read-write表示刷新是不及時的,你能夠設置 超時的時間去刷新,read-write表示在數據發生變化時緩存都會發生刷新,具體怎麼配置可能就要根據具體業務了。

Memcached大 致的原理也和ehcache 相同,將數據採用鍵值的形式存放在內存中,使用時能夠將查詢的md5做爲鍵,查詢的結果做爲值。相對ehcache而言,memcached是一個工 具,ehcache是一個框架,memcached更加底層更加靈活,固然你也要寫相應的代碼去使用它。

這是一張網上的memcached圖,說明了memcached在系統中的位置。

近幾年興起的NOSQL技術,雖然如今歸於數據庫的一種,但其本質也是緩存技術和數據庫技術的一種融合產物。

目前緩存的作法分爲兩種模式:

內存緩存:緩存數據存放在服務器的內存空間中。

優勢:速度快 缺點:資源有限

文件緩存:緩存數據存放在服務器的硬盤空間中。

優勢:容量大 缺點:速度偏慢,尤爲在緩存數量巨大時

數據庫緩存

數據庫的緩存通常由數據庫提供,好比ORACLE,能夠對錶創建高速緩存,提升對常常訪問的數據的訪問速度。

總結

究竟怎樣去使用緩存,使用哪一層次的緩存,是由網站自己的具體業務來決定的。緩存技術的一個原則是:讓數據更靠近用戶。緩存技術是一門博大精深的藝術,我也是隻知些皮毛。

最近項目組有用到這三個緩存,去各自的官方看了下,以爲還真的各有千秋!今天特地概括下各個緩存的優缺點,僅供參考!

Ehcache

在java項目普遍的使用。它是一個開源的、設計於提升在數據從RDBMS中取出來的高花費、高延遲採起的一種緩存方案。正由於Ehcache具備健壯性(基於java開發)、被認證(具備apache 2.0  license)、充滿特點(稍後會詳細介紹),因此被用於大型複雜分佈式web application的各個節點中。

什麼特點?

1.  夠快

Ehcache的發行有一段時長了,通過幾年的努力和不可勝數的性能測試,Ehcache終被設計於large, high concurrency systems.

2. 夠簡單

開發者提供的接口很是簡單明瞭,從Ehcache的搭建到運用運行僅僅須要的是你寶貴的幾分鐘。其實不少開發者都不知道本身用在用Ehcache,Ehcache被普遍的運用於其餘的開源項目

好比:hibernate

3.夠袖珍

關於這點的特性,官方給了一個很可愛的名字small foot print ,通常Ehcache的發佈版本不會到2M,V 2.2.3  才 668KB。

4. 夠輕量

核心程序僅僅依賴slf4j這一個包,沒有之一!

5.好擴展

Ehcache提供了對大數據的內存和硬盤的存儲,最近版本容許多實例、保存對象高靈活性、提供LRU、LFU、FIFO淘汰算法,基礎屬性支持熱配置、支持的插件多

6.監聽器

緩存管理器監聽器 (CacheManagerListener)和 緩存監聽器(CacheEvenListener),作一些統計或數據一致性廣播挺好用的

如何使用?

夠簡單就是Ehcache的一大特點,天然用起來just so easy!

貼一段基本使用代碼

CacheManager manager = CacheManager.newInstance("src/config/ehcache.xml");
Ehcache cache = new Cache("testCache", 5000, false, false, 5, 2); cacheManager.addCache(cache);
代碼中有個ehcache.xml文件,如今來介紹一下這個文件中的一些屬性
  1.        name:緩存名稱。
  2.        maxElementsInMemory:緩存最大個數。
  3.        eternal:對象是否永久有效,一但設置了,timeout將不起做用。
  4.        timeToIdleSeconds:設置對象在失效前的容許閒置時間(單位:秒)。僅當eternal=false對象不是永久有效時使用,可選屬性,默認值是0,也就是可閒置時間無窮大。
  5.        timeToLiveSeconds:設置對象在失效前容許存活時間,最大時間介於建立時間和失效時間之間。僅當eternal=false對象不是永久有效時使用,默認是0.,也就是對象存活時 間無窮大。
  6.        overflowToDisk:當內存中對象數量達到maxElementsInMemory時,Ehcache將會對象寫到磁盤中。
  7.        diskSpoolBufferSizeMB:這個參數設置DiskStore(磁盤緩存)的緩存區大小。默認是30MB。每一個Cache都應該有本身的一個緩衝區。
  8.        maxElementsOnDisk:硬盤最大緩存個數。
  9.        diskPersistent:是否緩存虛擬機重啓期數據 Whether the disk store persists between restarts of the Virtual Machine. The default value is false.
  10.        diskExpiryThreadIntervalSeconds:磁盤失效線程運行時間間隔,默認是120秒。
  11.        memoryStoreEvictionPolicy:當達到maxElementsInMemory限制時,Ehcache將會根據指定的策略去清理內存。默認策略是LRU。你能夠設置爲 FIFO或是LFU。
  12.        clearOnFlush:內存數量最大時是否清除。

memcache

memcache 是一種高性能、分佈式對象緩存系統,最初設計於緩解動態網站數據庫加載數據的延遲性,你能夠把它想象成一個大的內存HashTable,就是一個key-value鍵值緩存。Danga Interactive爲了LiveJournal所發展的,以BSD license釋放的一套開放源代碼軟件。

1.依賴

memcache C語言所編寫,依賴於最近版本的GCC和libevent。GCC是它的編譯器,同事基於libevent作socket io。在安裝memcache時保證你的系統同事具有有這兩個環境。

2.多線程支持

memcache支持多個cpu同時工做,在memcache安裝文件下有個叫threads.txt中特別說明,By default, memcached is compiled as a single-threaded application.默認是單線程編譯安裝,若是你須要多線程則須要修改./configure –enable-threads,爲了支持多核系統,前提是你的系統必須具備多線程工做模式。開啓多線程工做的線程數默認是4,若是線程數超過cpu數容易發生操做死鎖的機率。結合本身業務模式選擇才能作到物盡其用。

3.高性能

經過libevent完成socket 的通信,理論上性能的瓶頸落在網卡上。

簡單安裝:

1.分別把memcached和libevent下載回來,放到 /tmp 目錄下:

# cd /tmp

# wget http://www.danga.com/memcached/dist/memcached-1.2.0.tar.gz

# wget http://www.monkey.org/~provos/libevent-1.2.tar.gz

2.先安裝libevent:

# tar zxvf libevent-1.2.tar.gz

# cd libevent-1.2

# ./configure -prefix=/usr

# make (若是遇到提示gcc 沒有安裝則先安裝gcc)

# make install

3.測試libevent是否安裝成功:

# ls -al /usr/lib | grep libevent

lrwxrwxrwx 1 root root 21 11?? 12 17:38 libevent-1.2.so.1 -> libevent-1.2.so.1.0.3

-rwxr-xr-x 1 root root 263546 11?? 12 17:38 libevent-1.2.so.1.0.3

-rw-r-r- 1 root root 454156 11?? 12 17:38 libevent.a

-rwxr-xr-x 1 root root 811 11?? 12 17:38 libevent.la

lrwxrwxrwx 1 root root 21 11?? 12 17:38 libevent.so -> libevent-1.2.so.1.0.3

還不錯,都安裝上了。

4.安裝memcached,同時須要安裝中指定libevent的安裝位置:

# cd /tmp

# tar zxvf memcached-1.2.0.tar.gz

# cd memcached-1.2.0

# ./configure -with-libevent=/usr

# make

# make install

若是中間出現報錯,請仔細檢查錯誤信息,按照錯誤信息來配置或者增長相應的庫或者路徑。

安裝完成後會把memcached放到 /usr/local/bin/memcached ,

5.測試是否成功安裝memcached:

# ls -al /usr/local/bin/mem*

-rwxr-xr-x 1 root root 137986 11?? 12 17:39 /usr/local/bin/memcached

-rwxr-xr-x 1 root root 140179 11?? 12 17:39 /usr/local/bin/memcached-debug

啓動memcache服務

啓動Memcached服務:

1.啓動Memcache的服務器端:

# /usr/local/bin/memcached -d -m 8096 -u root -l 192.168.77.105 -p 12000 -c 256 -P /tmp/memcached.pid

-d選項是啓動一個守護進程,

-m是分配給Memcache使用的內存數量,單位是MB,我這裏是8096MB,

-u是運行Memcache的用戶,我這裏是root,

-l是監聽的服務器IP地址,若是有多個地址的話,我這裏指定了服務器的IP地址192.168.77.105,

-p是設置Memcache監聽的端口,我這裏設置了12000,最好是1024以上的端口,

-c選項是最大運行的併發鏈接數,默認是1024,我這裏設置了256,按照你服務器的負載量來設定,

-P是設置保存Memcache的pid文件,我這裏是保存在 /tmp/memcached.pid,

2.若是要結束Memcache進程,執行:

# cat /tmp/memcached.pid 或者 ps -aux | grep memcache   (找到對應的進程id號)

# kill 進程id號

也能夠啓動多個守護進程,不過端口不能重複。

memcache 的鏈接

telnet  ip   port

注意鏈接以前須要再memcache服務端把memcache的防火牆規則加上

-A RH-Firewall-1-INPUT -m state –state NEW -m tcp -p tcp –dport 3306 -j ACCEPT

從新加載防火牆規則

service iptables restart

OK ,如今應該就能夠連上memcache了

在客戶端輸入stats 查看memcache的狀態信息

pid              memcache服務器的進程ID

uptime      服務器已經運行的秒數

time           服務器當前的unix時間戳

version     memcache版本

pointer_size         當前操做系統的指針大小(32位系統通常是32bit)

rusage_user          進程的累計用戶時間

rusage_system    進程的累計系統時間

curr_items            服務器當前存儲的items數量

total_items           從服務器啓動之後存儲的items總數量

bytes                       當前服務器存儲items佔用的字節數

curr_connections        當前打開着的鏈接數

total_connections        從服務器啓動之後曾經打開過的鏈接數

connection_structures          服務器分配的鏈接構造數

cmd_get get命令          (獲取)總請求次數

cmd_set set命令          (保存)總請求次數

get_hits          總命中次數

get_misses        總未命中次數

evictions     爲獲取空閒內存而刪除的items數(分配給memcache的空間用滿後須要刪除舊的items來獲得空間分配給新的items)

bytes_read    讀取字節數(請求字節數)

bytes_written     總髮送字節數(結果字節數)

limit_maxbytes     分配給memcache的內存大小(字節)

threads         當前線程數

redis

redis是在memcache以後編寫的,你們常常把這二者作比較,若是說它是個key-value store 的話可是它具備豐富的數據類型,我想暫時把它叫作緩存數據流中心,就像如今物流中心那樣,order、package、store、classification、distribute、end。如今還很流行的LAMP PHP架構 不知道和 redis+mysql 或者 redis + mongodb的性能比較(聽羣裏的人說mongodb分片不穩定)。

先說說reidis的特性

1. 支持持久化

redis的本地持久化支持兩種方式:RDB和AOF。RDB 在redis.conf配置文件裏配置持久化觸發器,AOF指的是redis沒增長一條記錄都會保存到持久化文件中(保存的是這條記錄的生成命令),若是不是用redis作DB用的話還會不要開AOF ,數據太龐大了,重啓恢復的時候是一個巨大的工程!

2.豐富的數據類型

redis 支持 String 、Lists、sets、sorted sets、hashes 多種數據類型,新浪微博會使用redis作nosql主要也是它具備這些類型,時間排序、職能排序、個人微博、發給個人這些功能List 和 sorted set

的強大操做功能息息相關

3.高性能

這點跟memcache很想象,內存操做的級別是毫秒級的比硬盤操做秒級操做天然高效很多,較少了磁頭尋道、數據讀取、頁面交換這些高開銷的操做!這也是NOSQL冒出來的緣由吧,應該是高性能

是基於RDBMS的衍生產品,雖然RDBMS也具備緩存結構,可是始終在app層面不是咱們想要的那麼操控的。

4.replication

redis提供主從複製方案,跟mysql同樣增量複製並且複製的實現都很類似,這個複製跟AOF有點相似複製的是新增記錄命令,主庫新增記錄將新增腳本發送給從庫,從庫根據腳本生成記錄,這個過程很是快,就看網絡了,通常主從都是在同一個局域網,因此能夠說redis的主從近似及時同步,同事它還支持一主多從,動態添加從庫,從庫數量沒有限制。 主從庫搭建,我以爲仍是採用網狀模式,若是使用鏈式(master-slave-slave-slave-slave·····)若是第一個slave出現宕機重啓,首先從master 接收 數據恢復腳本,這個是阻塞的,若是主庫數據幾TB的狀況恢復過程得花上一段時間,在這個過程當中其餘的slave就沒法和主庫同步了。

5.更新快

這點好像從我接觸到redis到目前爲止 已經發了大版本就4個,小版本沒算過。redis做者是個很是積極的人,不管是郵件提問仍是論壇發帖,他都能及時耐心的爲你解答,維護度很高。有人維護的話,讓咱們用的也省心和放心。目前做者對redis 的主導開發方向是redis的集羣方向。

redis的安裝

redis的安裝其實仍是挺簡單的,總的來講就三步:下載tar包,解壓tar包,安裝。

不過最近我在2.6.7後用centos 5.5 32bit 時碰到一個安裝問題,下面我就用圖片分享下安裝過程碰到的問題,在redis 文件夾內執行make時有個以下的錯 undefined reference to ‘__sync_add_and_fetch_4′

上網找了了好多最後在  https://github.com/antirez/redis/issues/736 找到解決方案,write CFLAGS= -march=i686 on src/Makefile head!

記得要把剛安裝失敗的文件刪除,從新解壓新的安裝文件,修改Makefile文件,再make安裝。就不會發現原來那個錯誤了

關於redis的一些屬性註釋和基本類型操做在上一篇redis 的開胃菜有詳細的說明,這裏就再也不重複累贅了(實質是想偷懶 ,哈哈!)

最後,把memcache和redis放在一塊兒不得不會讓人想到二者的比較,誰快誰好用啊,羣裏面已經爲這個事打架好久了,我就把我看到的在這裏跟你們分享下。

在別人發了一個memcache性能比redis好不少後,redis 做者 antirez 發表了一篇博文,主要是說到如何給redis 和 memcache 作壓力測試,文中講到有我的說許多開源軟件都應該丟進廁所,由於他們的壓力測試腳本太2了,做者對這個說明了一番。redis  vs  memcache is  definitely an apple to apple comparison。 呵呵,很明確吧,二者的比較是否是有點雞蛋挑骨頭的效果,做者在相同的運行環境作了三次測試取多好的值,獲得的結果以下圖:

須要申明的是這次測試在單核心處理的過程的數據,memcache是支持多核心多線程操做的(默認沒開)因此在默認狀況下上圖具備參考意義,若然則memcache快於redis。那爲何redis不支持多線程多核心處理呢?做者也發表了一下本身的見解,首先是多線程不變於bug的修復,實際上是不易軟件的擴展,還有數據一致性問題由於redis全部的操做都是原子操做,做者用到一個詞nightmare 噩夢,呵呵!  固然不支持多線程操做,確定也有他的弊端的好比性能想必必然差,做者從2.2版本後專一redis cluster的方向開發來緩解其性能上的弊端,說白了就是縱向不行,橫向提升。

相關文章
相關標籤/搜索