Memcache和Redis復習總結
Memcache
Memcache是一個高性能的分布式的內存對象緩存系統,主要是用來緩存從MySQL數據庫中查詢的數據,減少對mysql數據庫的壓力。
Memcache的工作流程:
當用戶發生一個動態請求的時候,先去Memcache服務器裏面查詢緩存數據,當首次查詢的時候,Memcache裏面肯定是沒有數據的,這個時候需要php程序去MySQL數據庫裏面獲取數據,將獲取先緩存一份到Memcache服務器裏面,在把數據返回給用戶。當第二次發生相同的動態的請求的時候,這個時候由於上一次上Memcache 裏面已經緩存了對應的查詢數據,這個Memcache就可以直接的返回數據,而不需要MySQL數據庫的參與,減少了MySQL數據庫的壓力。?對於這種架構來說,由於Memcache是處於旁邊的,這種緩存系統叫做旁路式緩存系統。
Memcache使用了一個預分配的機制來管理自己的內存單元。Memcache的這一套分配機制主要是為了解決Memcache的一個內存碎片化的問題。??
Memcache的基本命令:
add 添加一個key
replace 更新(update)
set 如果一個不存在則添加如果存在則更新
delete 刪除一個key
get 獲取一個指定key的值
prepend 在一個值的前面追加
stats 查看memcache的狀態
flush_all 清空memcache裏面的所有
Memcache分布式:Memcache是一個高性能、開放源代碼、分布式緩存系統。由於單臺Memcache服務的能力有限,這個時候就可以使用多臺Memcache來完成服務,形成的架構就叫做Memcache的分布式(多臺)緩存系統。
Memcache安全問題:
1. Memcache在使用過程中,是沒有用戶名的驗證操作的。所以一般在使用Memcache的時候都是在內網使用,不要使用公網IP。
2. 如果真的要在公網IP使用,可以寫一個專門的防火墻驗證規則,只允許規定的IP去操作Memcache服務器。
Memcache雪崩:當使用Memcache緩存系統全部崩潰的時候,這個時候所有的壓力全部加在了MySQL服務器上,MySQL服務器無法支撐其訪問,會立馬的崩潰,這種現象叫做Memcache的雪崩現象。為了防止此類問題的發送,需要對Memcache的緩存系統做優化處理(使用一致性hash算法來實現緩存系統)。
? Memcache總結:
1、Memecache把數據全部存在內存之中,斷電後會掛掉,數據不能超過內存大小。
2、Memcache使用了SlabAllocator的內存分配機制:按照預先規定的大小,將分配的內存分割成特定長度的塊,以完全解決內存碎片問題。
3、Memcache存在內存中,分配的內存滿後,會按一定的規則刪除一些k/v數據,重啟後自然全部丟失。
4、過期策略--Memcache在set時就指定,例如set key1 0 08,即永不過期。Redis可以通過例如expire 設定。
5、首先要說明的是Memcached支持最大的存儲對象為1M。它的內存分配比較特殊,但是這樣的分配方式其實也是基於性能考慮的,簡單的分配機制可以更容易回收再分配,節省對CPU的使用。大於1M需要拆分。
6、Memcached能接受的key的最大長度是,255字符。
7、同一份數據同時發送了一個set命令和一個get命令,它們不會影響對方,但是get以後,處理期間可能先被其他Set了,後面的Set會覆蓋前面的,但是Memcached1.2.5以及更高版本,提供了gets和cas命令,它們可以解決上面的問題。如果您使用gets命令查詢某個key的item,Memcached會給您返回該item當前值的唯一標識。如果您覆寫了這個item並想把它寫回到Memcached中,您可以通過cas命令把那個唯一標識一起發送給Memcached。如果該item存放在Memcached中的唯一標識與您提供的一致,您的寫操作將會成功。如果另一個進程在這期間也修改了這個item,那麽該item存放在Memcached中的唯一標識將會改變,您的寫操作就會失敗。
8、無身份驗證,認為身份驗證是更高層的問題。
9、刪除Delete操作只是將該chunk置為刪除狀態,這樣在下次使用將優先利用這樣的chunk。
10、Flush操作相當於將所有的item失效的一個動作。並不會改變Memcache內存分配情況。
11、Memcache已經分配的內存不會再主動清理。
12、Memcache分配給某個slab的內存頁不能再分配給其他slab。
13、flush_all不能重置Memcache分配內存頁的格局,只是給所有的item置為過期。
14、Memcache最大存儲的item(key+value)大小限制為1M,這由page大小1M限制。
15、由於Memcache的分布式是客戶端程序通過hash算法得到的key取模來實現,不同的語言可能會采用不同的hash算法,同樣的客戶端程序也有可能使用相異的方法,因此在多語言、多模塊共用同一組Memcached服務時,一定要註意在客戶端選擇相同的hash算法。
16、啟動Memcached時可以通過-M參數禁止LRU替換,在內存用盡時add和set會返回失敗。
17、Memcached啟動時指定的是數據存儲量,沒有包括本身占用的內存、以及為了保存數據而設置的管理空間。因此它占用的內存量會多於啟動時指定的內存分配量,這點需要註意。
Redis
Redis: REmoteDIctionaryServer,可以直接理解為遠程字典服務
Redis是一個key-value存儲系統。和Memcached類似,它支持存儲的value類型相對更多,包括string(字符串)、list(鏈表)、set(集合)、zset(sortedset--有序集合)和hash(哈希類型,類似php裏面的關聯數組)。與memcached一樣,為了保證效率,數據都是緩存在內存中。區別的是redis會周期性的把更新的數據寫入磁盤或者把修改操作寫入追加的記錄文件(數據持久化)。?
redis的出現很大程度補償了Memcached這類key/value(Memcache的value只能保存單一的string類型)存儲不足的問題。
Redis的特性:
1、(value可以是多種數據類型)多種數據類型存儲:字符串類型String、哈希類型(關聯數組)Hash、 列表類型List、集合類型Set、 有序集合類型
2、內存存儲與持久化
(1)、內存的讀寫速度遠快於硬盤
(2)、自身提供了持久化功能(RDB、AOF兩種方式)
RDB(快照) 持久化可以在指定的時間間隔內將內存裏面的數據保存到硬盤上。這種保存方式是有丟失數據的危險的。
AOF 持久化記錄redis服務器上所執行的所有寫操作命令(有點類似MySQL裏面的bin日誌)全部保存到磁盤文件的日誌上,並在服務器啟動時,通過重新執行這些命令來還原數據集。AOF 文件中的命令全部以Redis 協議的格式來保存,新命令會被追加到文件的末尾。
Redis 還可以同時使用 AOF 持久化和RDB 持久化。在這種情況下,當Redis 重啟時,它會優先使用AOF 文件來還原數據集,因為AOF 文件保存的數據集通常比RDB 文件所保存的數據集更完整。
甚至可以關閉持久化功能,讓數據只在服務器運行時內存中存在。等同於Memcache。
3、功能豐富
(1)、可以用作緩存、隊列(先進先出)
(2)、支持鍵的生存時間(緩存時間可以設置到毫秒級別(做秒殺應用),memcache裏面只支持到秒級別)
(3)、按照一定規則刪除相應的鍵
4、簡單穩定
(1)、相比SQL而言更加簡潔,不需要做sql語句的解析。
(2)、不同語言的客戶端豐富,支持多種語言來操作redis
(3)、基於C語言開發(效率更高),代碼量只有3萬多行
? redis多數據庫:
redis默認支持16個數據庫,對外都是以一個從0開始的遞增數字命名,可以通過參數database來修改默認數據庫個數。客戶端連接redis服務後會自動選擇0號數據庫,可以通過select命令更換數據庫,例如選擇1號數據庫。
說明:
Redis不支持自定義數據庫名稱。
Redis不支持為每個數據庫設置訪問密碼。
Redis的多個數據庫之間不是安全隔離的,FLUSHALL命令會清空所有數據庫的數據。
Redis生存時間:
Redis在實際使用過程中更多的用作緩存,然而緩存的數據一般都是需要設置生存時間的,即到期後數據銷毀。
設置生存時間語法:
EXPIRE keyseconds?:以分鐘設置生存時間
PEXPIRE keymilliseconds?:以毫秒設置生存時間,可以做到更精確的控制。
TTL查看key的剩余時間,當返回值為-2時,表示key已經過期,被刪除了。
清除生存時間語法:PERSIST key
設置新的數據時需要重新設置該key的生存時間。重新設置值也會清除生存時間。
?
Redis中的常用命令:?
客戶端連接命令: src/redis-cli
? 停止redis服務: src/redis-clishutdown?
1、發送命令: ping (返回pong)
?2、命令返回值: set KEYVALUE
3、獲取幫助命令: help?
4、數據庫切換: select 1
5、獲取符合規則的建名列表命令:
KEYS* keystest[_]* keyst[a-d] 說明: ? 匹配一個字符 * 匹配任意個(包括0個)字符 [] 匹配括號間的任一字符,可以使用“-“表示範圍。如a[a-d]匹配ab/ac/ad \x 匹配字符x,用於轉義符合,如果要匹配“?“就需要使用\?
6、EXISTS判斷命令: exists KEY
判斷一個key是否存在。如果key存在則返回整數類型1,否則返回0。
7、DEL刪除命令: del KEY
? 刪除鍵,可以刪除一個或者多個鍵,多個鍵用空格隔開,返回值是刪除的鍵的個數。
8、TYPE查看鍵值類型命令: type KEY
獲得鍵值的數據類型,返回值可能是string(字符串)、hash(散列類型)、list(列表類型)、set(集合類型)、zset(有序集合類型)。
9、FLUSHALL命令:flushall (該命令一般只在做測試的時候使用)
清空所有數據庫。(包含默認配置的16個數據庫裏面的所有的數據)
10、賦值與取值命令:
SET key value(賦值)
GET key(取值)
註意:字符中間有空格時,用單撇或者雙撇括起來。
多個msetmget
11、同時設置/獲取多個鍵值
MSET key value [keyvalue …]
MGET key[key …]
12、INCR自增實現命令: INCRBY keynumber
當存儲的字符串是整數時,redis提供了一個實用的命令INCR,其作用是讓當前鍵值遞增,並返回遞增後的值。如果key不存在,則自動會創建,如果存在自動+1。
13、DECR自減命令:
?DECR key
DECRBY key number(減少指定的整數)
14、Append追加命令: APPEND keyvalue
向尾部追加值。如果鍵不存在則創建該鍵,其值為寫的value,即相當於SET keyvalue。返回值是追加後字符串的總長度。
15、STRLEN獲取字符串長度命令: STRLENkey
字符串長度,返回數據的長度,如果鍵不存在則返回0。註意,如果鍵值為空串,返回也是0。
16、 zadd操作
zadd keyscore1 value1socre2 value2 ......
17、zrange操作
zrangekey 0 -1 (-1代表集合裏面的最後一個下標,從小到大)
? 18、zrevrange操作
zrevrangekey 0 -1 (代表反轉排序 從大大小)
19、lpush 在鏈表的左側增加元素信息
lpush link2 a d e f
20、lrange操作:獲取鏈表裏面的內容
lrangelink1 0 -1(-1代表最後一個元素下標)
21、 lrem 刪除鏈表裏面的內容
lrem link -2 b (代表的含義是從左開始刪除 2 個元素b)
lrem link 2 b(代表的含義是從右邊開始刪除2 個元素b)
??補充:如果網站處於高並發的情況下:有兩種方式擴展:1.做集群:擴展服務器2.硬件升級,在原本的項目裏面加一個隊列服務器。隊列服務器可以支持很高的並發,可以先將用戶的請求直接保存起來,後面慢慢的處理。
Redis小結:
1、Redis不僅僅支持簡單的k/v類型的數據,同時還提供list,set,hash等數據結構的存儲。
2、Redis支持數據的備份,即master-slave模式的數據備份。
3、Redis支持數據的持久化,可以將內存中的數據保持在磁盤中,重啟的時候可以再次加載進行使用。
4、Redis,具備一定的數據庫特征。
5、Redis數據可以存儲到硬盤,基本沒有過期策略。
6、redis有一個致命缺陷 當內存滿了時dump數據cpu占用100%。
Memcache和Redis區別
Redis中,並不是所有的數據都一直存儲在內存中的,這是和Memcached相比一個最大的區別。
Redis在很多方面具備數據庫的特征,或者說就是一個數據庫系統,而Memcached只是簡單的K/V緩存。
他們的擴展都需要做集群;實現方式:master-slave、Hash。
在100k以上的數據中,Memcached性能要高於Redis。
如果要說內存使用效率,使用簡單的key-value存儲的話,Memcached的內存利用率更高,而如果Redis采用hash結構來做key-value存儲,由於其組合式的壓縮,其內存利用率會高於Memcached。當然,這和你的應用場景和數據特性有關。
Memcache和Redis復習總結