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
二、特色及應用:html
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)複製來實現數據備份,主機會自動將數據同步到從機。
2、 基本使用前端
一、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(可不執行)
二、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&
三、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
四、五種數據類型
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進行有序排列。
五、 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 返回數據類型
六、持久化方案:
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持久化同步,但若是主從都掛掉,影響較大。
3、Redis緩存、ehcache、memcached比較
特色:
ehcache直接在jvm虛擬機中緩存,速度快,效率高;可是緩存共享麻煩,集羣分佈式應用不方便。
memcache保存在內存,支持分佈式,只存儲String類型數據,不支持持久化。
redis是經過socket訪問到緩存服務,效率比ecache低(相差一個數量級),比數據庫要快不少,支持數據類型較爲豐富,支持集羣和分佈式緩存,有成熟的方案。
技術選型:
單個應用,下降應用的複雜性或者對緩存訪問要求很高的應用,用ehcache。
若是是大型系統,存在緩存共享、分佈式部署、緩存內容很大的,建議用redis。
memcache,老牌緩存服務,相關領域支持比較豐富,window和linux均可以使用。
補充下:ehcache也有緩存共享方案,不過是經過RMI或者Jgroup多播方式進行廣播緩存通知更新,緩存共享複雜,維護不方便;簡單的共享能夠,可是涉及到緩存恢復,大數據緩存,則不合適。
4、擴展
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區)。