redis(Remote Dictionary Server)
一、原理及特性層面:
1、優勢:
1)數據加載在內存中,執行速度快, 數據結構類似於HashMap,HashMap的優勢就是查找和操作的時間復雜度都是O(1)。
2)單線程多路復用,I/O多路復用(防止 I/O 阻塞)-- 一種效率更高的 I/O 模型, 在單個線程中通過記錄跟蹤每一個sock(I/O流) 的狀態來管理多個I/O流。(相比多線程效率更高, .跟多線程相比較,線程切換需要切換到內核進行線程切換,需要消耗時間和資源, I/O多路復用不需要切換線/進程)
3)協議簡單,客戶端和服務端使用 RESP協議(容易實現、快速解析), RESP是二進制安全的而且從一個進程發塊數據給另一個進程的時候不需要做轉換,因為他會在塊數據之前加上長度。
*2
$3
GET
$4
name
2、特點及應用:
0)支持lua腳本, 在Redis中,執行Lua語言是原子性,也就是說Redis執行Lua的時候是不會被中斷的,具備原子性,這個特性有助於Redis對並發數據一致性的支持。
1)支持事務、 watch,操作命令都是原子的。
Redis
事務: Redis中的事務(transaction)是一組命令的集合。 Redis保證一個事務中的所有命令要么都執行,要么都不執行。如果在發送EXEC命令前客戶端斷線了,則Redis會清空事務隊列,事務中的所有命令都不會執行。而一旦客戶端發送了EXEC命令,所有的命令就都會被執行,即使此后客戶端斷線也沒關系,因為Redis中已經記錄了所有要執行的命令。 Redis的事務還能保證一個事務內的命令依次執行而不被其他命令插入。
注意: 和傳統的mysql事務不同的事,redis事務不支持回滾。
Redis Watch 命令用於監視一個(或多個) key ,如果在事務執行之前這個(或這些) key 被其他命令所改動,那么事務將被打斷( 為了避免競態條件,或多線程其的情況)
//偽代碼
WATCH key
isFieldExists = HEXISTS key, field
if isFieldExists is 1
MULTI
HSET key, field, value
EXEC
else
UNWATCH
return isFieldExists
2)支持管道Pipline,批量指令操作操作,能減少網絡交互時間;
缺陷:允許一定比例的寫入失敗,對可靠性要求很高的系統不適用;
3)支持消息發布與訂閱;
缺陷:相對於kafka,redis吞吐量不高,redis接收端掛掉重啟,不會接收之前發送的消息。
4)可以設置key的過期時間;
5)支持5種數據類型;
6)支持數據持久化;
7)支持主從(master-slave)復制來實現數據備份,主機會自動將數據同步到從機。
二、 基本使用
1、redis創建用戶
//創建普通用戶****
useradd -d /appdeploy -m appdeploy
//創建用戶組並加入 剛剛創建的用戶****
useradd -g appdeploy -n appdeploy(可不執行)
//修改文件或文件夾的權限,使新增用戶可以擁有該文件的查看權限****
chmod -R 777 /usr/local/soft/elasticsearch-6.4.0/
或者授權文件歸屬於另一個用戶組的用戶 (chown -R appdeploy:appdeploy /usr/local/soft/elasticsearch-6.4.0)
//將用戶添加到用戶組而不脫離該用戶原來的組
usermod -a -g groupA appdeploy(可不執行)
//將文件夾的歸屬給某個組
chown root:mygroup /user/local/soft(可不執行)
2、redis啟動
前端啟動:在redis的安裝目錄下直接啟動redis-server
./redis-server
后台啟動:
把/root/redis-3.0.0/redis.conf復制到/usr/local/redis/bin目錄下
cp redis.conf /usr/local/redis/bin/
修改配置文件:
./redis-server redis.conf
查看redis進程:
ps aux|grep redis
如下信息:
root 5190 0.1 0.3 33936 1712 ? Ssl 18:23 0:00 ./redis-server *:6379
root 5196 0.0 0.1 4356 728 pts/0 S+ 18:24 0:00 grep redis
指定端口啟動(&表示后台運行)
./redis-server --port 6380&
3、Redis-cli
//默認連接localhost運行在6379端口的redis服務。
./redis-cli
//指定IP和端口連接
//-h:連接的服務器的地址
//-p:服務的端口號
./redis-cli -h 192.168.25.153 -p 6379
關閉redis:
./redis-cli shutdown
//設置密碼的連接方式
./redis-cli -h 127.0.0.1 -p 6379 -a Passw0rd
4、五種數據類型
1). String String數據結構是簡單的key-value類型,value其實不僅可以是String,也可以是數字。
2).Hash Hash是一個string類型的field和value的映射表,hash特別適合用於存儲對象。 比如我們可以Hash數據結構來存儲用戶信息,商品信息等等。
3).List list就是鏈表,Redis list的實現為一個雙向鏈表,即可以支持反向查找和遍歷。
應用:
使用Redis實現消息隊列
普通隊列:一般使用list結構作為隊列,rpush生產消息,lpop消費消息, blpop阻塞消費。
消費多次:生產一次消費多次的情況使用發布/訂閱模式 延時隊列:使用sortedset,拿時間戳作為score,消息內容作為key調用zadd來生產消息,消費者用zrangebyscore指令獲取N秒之前的數據輪詢進行處理
4).Set set是可以自動排重的。
5).Sorted Set sorted set增加了一個權重參數score,使得集合中的元素能夠按score進行有序排列。

5、 Key命令
設置key的過期時間。
Expire key second:設置key的過期時間
Ttl key:查看key的有效期
Persist key:清除key的過期時間。Key持久化。
> expire Hello 100
(integer) 1
> ttl Hello
(integer) 77
Incr
對 key 的值做加加操作,並返回新的值。注意 incr 一個不是 int 的 value 會返回錯誤,incr 一個不存在的 key,則設置 key 為 1
應用:
Redis實現限制訪問頻率, 限制每個用戶每分鍾最多只能訪問100個頁面。
實現思路:用戶每次訪問將value的值通過INCR命令自增1.如果自增后的值是1同時設置過期時間為1分鍾。這樣用戶每次訪問的時候都讀取該鍵的值,如果超過了100就表明該用戶的訪問頻率超過了限制,需要提示用戶稍后訪問。且該鍵每分鍾會自動被刪除。所以下一分鍾又會重新計算,也就達到了限制訪問頻率的目的。
其他命令:
incrby
同 incr 類似,加指定值 ,key 不存在時候會設置 key,並認為原來的 value 是 0
Decr
對 key 的值做的是減減操作,decr 一個不存在 key,則設置 key 為-1
Decrby
同 decr,減指定值。
Append
給指定 key 的字符串值追加 value,返回新字符串值的長度。
Strlen
取指定 key 的 value 值的長度。
persist xxx(取消過期時間)
選擇數據庫(0-15庫)
Select 0 //選擇數據庫
move age 1//把age 移動到1庫
Randomkey隨機返回一個key
Rename重命名
Type 返回數據類型
6、持久化方案:
RDB:快照形式,定期把內存中當前時刻的數據保存到磁盤,Redis默認支持的持久化方案。速度快但是服務器斷電的時候會丟失部分數據。
AOF:append only file。把所有對redis數據庫操作的命令,增刪改操作的命令。保存到文件中。數據庫恢復時把所有的命令執行一遍即可。兩種持久化方案同時開啟使用AOF文件來恢復數據庫.能保證數據的完整性,但是速度慢。
兩者如何選擇?
-
如果redis僅僅是用來做為緩存服務器的話,我們可以不使用任何的持久化(建議redis啟動時進行全量數據同步或定時全量同步);
-
一般情況下我們會將兩種持久化的方式都開啟。redis優先加載AOF文件來回復數據。RDB的好處是快速(推薦);
-
在主從節點中,RDB作為我們的備份數據,只在salve(從節點)上啟動,同步時間可以設置的長一點,只留(save 900 1)這條規則就可以了;
-
開啟AOF的情況下,主從同步是時候必然會帶來IO的性能影響,此時我們可以調大auto-aof-rewrite-min-size的值,比如5GB。來減少IO的頻率;
-
不開啟AOF的情況下,可以節省IO的性能影響,主從節點通過RDB持久化同步,但如果主從都掛掉,影響較大。
三、Redis緩存、ehcache、memcached比較
特點:
ehcache直接在jvm虛擬機中緩存,速度快,效率高;但是緩存共享麻煩,集群分布式應用不方便。
memcache保存在內存,支持分布式,只存儲String類型數據,不支持持久化。
redis是通過socket訪問到緩存服務,效率比ecache低(相差一個數量級),比數據庫要快很多,支持數據類型較為豐富,支持集群和分布式緩存,有成熟的方案。
技術選型:
單個應用,降低應用的復雜性或者對緩存訪問要求很高的應用,用ehcache。
如果是大型系統,存在緩存共享、分布式部署、緩存內容很大的,建議用redis。
memcache,老牌緩存服務,相關領域支持比較豐富,window和linux都可以使用。
補充下:ehcache也有緩存共享方案,不過是通過RMI或者Jgroup多播方式進行廣播緩存通知更新,緩存共享復雜,維護不方便;簡單的共享可以,但是涉及到緩存恢復,大數據緩存,則不合適。
四、擴展
redis內存淘汰策略:
高版本的Redis中當內存達到極限時,內存淘汰策略主要采用了6種方式進行內存對象的釋放操作
1).volatile-lru:從設置了過期時間的數據集中,選擇最近最久未使用的數據釋放
2).allkeys-lru:從數據集中(包括設置過期時間以及未設置過期時間的數據集中),選擇最近最久未使用的數據釋放
3).volatile-random:從設置了過期時間的數據集中,隨機選擇一個數據進行釋放
4).allkeys-random:從數據集中(包括了設置過期時間以及未設置過期時間)隨機選擇一個數據進行入釋放
5).volatile-ttl:從設置了過期時間的數據集中,選擇馬上就要過期的數據進行釋放操作
6).noeviction:不刪除任意數據(但redis還會根據引用計數器進行釋放呦~),這時如果內存不夠時,會直接返回錯誤
默認的內存策略是noeviction,在Redis中LRU算法是一個近似算法,默認情況下,Redis隨機挑選5個鍵,並且從中選取一個最近最久未使用的key進行淘汰,在配置文件中可以通過maxmemory-samples的值來設置redis需要檢查key的個數,但是栓查的越多,耗費的時間也就越久,但是結構越精確(也就是Redis從內存中淘汰的對象未使用的時間也就越久~)。
LRU算法簡單介紹:
1)LRU算法作為內存管理的一種有效算法,其含義是在內存有限的情況下,當內存容量不足時,為了保證程序的運行,這時就不得不淘汰內存中的一些對象,釋放這些對象占用的空間。
2)LRU (英文:Least Recently Used), 意為最近最少使用,如果一塊數據最近被訪問,那么它將來被訪問的幾率也很高,根據數據的歷史訪問來淘汰長時間未使用的數據。
3)在操作系統中LRU算法淘汰的不是內存中的對象,而是頁,當內存中數據不足時,通過LRU算法,選擇一頁(一般是4KB)將其交換到虛擬內存區(Swap區)。
借鑒了不少文章,感謝各路大神分享,轉載請注明出處,謝謝:
https://www.cnblogs.com/huyangshu-fs/p/11255410.html