簡介: Redis是一款開源的使用ANSI C語言編寫、遵守BSD協議、支持網路、可基於記憶體也可持久化的日誌型、Key-Value高性能資料庫。Redis與其他Key-Value緩存產品相比有以下三個特點: 支持數據持久化,可以將記憶體中的數據保存在磁碟中,重啟可再次載入使用 支持簡單的Key-Val ...
簡介:
Redis是一款開源的使用ANSI C語言編寫、遵守BSD協議、支持網路、可基於記憶體也可持久化的日誌型、Key-Value高性能資料庫。Redis與其他Key-Value緩存產品相比有以下三個特點:
-
支持數據持久化,可以將記憶體中的數據保存在磁碟中,重啟可再次載入使用
-
支持簡單的Key-Value類型的數據,同時還提供Str、List、Set、Zset、Hash等數據結構的存儲
-
支持數據的備份,即Master-Slave模式的數據備份
-
NoSQL資料庫
優勢:
-
讀速度為110000次/s,寫速度為81000次/s,性能極高
-
具有豐富的數據類型
-
Redis所有操作都是原子的,意思是要麼成功執行要麼失敗完全不執行,多個操作也支持事務
-
豐富的特性,比如Redis支持publish/subscribe、notify、key過期等
下載:
https://github.com/microsoftarchive/redis/releases
啟動伺服器:
redis-server redis.windows.conf #進入到解壓補錄
redis-server --service-install redis.windows.conf #redis作為windows服務啟動方式
關閉伺服器:
redis-server --service-stop
啟動客戶端
redis-cli
redis-cli -h ip -p 埠 -a 密碼
關閉客戶端:
redis-cli -p 埠號 shutdown
下載:
wget http://download.redis.io/releases/redis-5.0.7.tar.gz
解壓:
tar xzf redis-5.0.7.tar.gz
放到/usr/local目錄下麵:
mv ./redis-5.0.7/* /usr/local/redis/
進入redis目錄:
cd /usr/local/redis/
生成:
sudo make
測試:
sudo make test
安裝:
sudo make install
下載:
http://download.redis.io/releases/redis-5.0.7.tar.gz
解壓:
tar zxvf redis-4.0.10.tar.gz
編譯測試:
sudo make test
編譯安裝
sudo make install
redis.conf 常用配置:
配置 | 作用 | 預設 |
bind |
|
127.0.0.1 |
protected-mode |
protected-mode是Redis3.2之後的新特性,用於加強Redis的安全管理,當滿足以下兩種情況時,protected-mode起作用:
|
yes |
port | Redis訪問埠,由於Redis是單線程模型,因此單機開多個Redis進程的時候會修改埠,不然一般使用大家比較熟悉的6379埠就可以了 | 6379 |
timeout | 指定在一個client空閑多少秒之後就關閉它,0表示不管 | 0 |
daemonize | 指定Redis是否以守護進程的方式啟動 | no |
pidfile | 當Redis以守護進程的方式運行的時候,Redis預設會把pid寫到pidfile指定的文件中 | /var/run/redis_6379.pid |
loglevel |
指定Redis的日誌級別,Redis本身的日誌級別有notice、verbose、notice、warning四種,按照文檔的說法,這四種日誌級別的區別是: debug,非常多信息,適合開發/測試
|
notice |
logfile | 配置log文件地址,預設列印在命令行終端的視窗上 | "" |
databases | 設置Redis資料庫的數量,預設使用0號DB | 16 |
save | 把Redis數據保存到磁碟上 |
|
requirepass | 設置客戶端認證密碼 | 關閉 |
maxclients | 設置同時連接的最大客戶端數量,一旦達到了限制,Redis會關閉所有的新連接併發送一個"max number of clients reached"的錯誤 | 關閉,預設10000 |
maxmemory | 不要使用超過指定數量的記憶體,一旦達到了,Redis會嘗試使用驅逐策略來移除鍵 如果1G記憶體可以設置256-512之間 需要轉換位元組 | 關閉 |
Redis 常用命令:
-
select index #select 1 、 select 2
-
清空資料庫
flushdb
-
查看所有key
keys *
-
刪除key
del key
-
判斷key是否存在
exists key #返回1表示存在,0表示不存在
-
設置key過期時間
expire key seconds #expire key名為name 100秒
-
查看過期時間
ttl key #ttl name 返回值 -1 代表永久 -2 無效
-
移除過期時間,讓key永久有效
persist key #persist name 返回-1,表示永久
-
通配符查找key
keys pattern * 代表任意字元 ?代表一個字元
-
返回一個隨機的KEY
randomkey
-
修改key的名字
rename key newkey
-
把key移動到指定資料庫
move key db
-
查看KEY類型
type key
str數據結構常用命令
設置指定 key 的值
set key value
獲取指定 key 的值
get key
只有在 key 不存在時設置 key 的值
setnx key value
返回 key 中字元串值的截取字元串
getrange key start end #getrange name 0 3
取出指定key的值,在賦值
getset key value
返回 key 所儲存的字元串值的長度
strlen key
將 key 中儲存的數字值加一
incr key
將 key 中儲存的數字值減一
decr key
將 key 所儲存的值加上給定的增量值
incrby key increment #incrby age 10 加10
將哈希表 key 中的欄位 field 的值設為 value
hset key field value #hset user:1 age 12
獲取存儲在哈希表中指定欄位的值
hget key field #hget user:1 age
同時將多個 field-value (域-值)對設置到哈希表 key 中
hmset key field1 value1 [field2 value2 ] #hmset user:2 name zhansan age 12
獲取所有給定欄位的值
hmget key field1 [field2] #hmget user:2 name 或 hmget user:2 name age
獲取指定key所有field-value
hgetall key #hgetall user:2
獲取指定key所有的field
hkeys key #hkeys user:2
獲取指定key的field數量
hlen key
刪除一個或多個哈希表欄位
hdel key field1 [field2] #hdel user:2 name
為哈希表 key 中的指定欄位的整數值加上增量 increment
hincrby key field increment #hincrby user:2 age 1
查看哈希表 key 中,指定的欄位是否存在
hexists key field # 不存在返回0 存在返回1
應用場景:消息隊列、分頁文章列表
在左側插⼊數據
lpush key value1 value2 ... #lpush mylist 1 2 3 返回的是 3 2 1
在右側插⼊數據
rpush key value1 value2 ...
獲取數據
lrange key start stop
設置指定索引位置的元素值
lset key index value
獲取列表長度
llen key
根據索引獲取值
lindex key index
從左側刪除預設刪除一個
lpop key
從右側刪除預設刪除一個
rpop key
讓列表只保存指定區間的元素
ltrim key start stop
在列表的元素前或者後插入元素
linsert key BEFORE|AFTER pivot value
刪除指定元素
lrem key count value
Redis中的set是無序的集合,元素類型是string,元素具有唯一性,不能重覆,元素不能修改。
應用場景:通過交集、並集、差集找到愛好相同與不同的人
添加元素
sadd key member1 member2 ...
返回所有元素
smembers key
獲取集合的元素的數量
scard key
判斷 member 元素是否是集合 key 的成員
sismember key member
返回隨機元素
srandmember key count
刪除指定元素
srem key field
移除並返回集合中的一個隨機元素
spop key
將 member 元素從 source 集合移動到 destination 集合
smove source destination member
差集
sdiff key1 [key2]
#返回給定所有集合的差集並存儲在 destination 中
sdiffstore destination key1 [key2]
交集
sinter key1 [key2]
#返回給定所有集合的交集並存儲在 destination 中
sinterstore destination key1 [key2]
並集
sunion key1 [key2]
#所有給定集合的並集存儲在 destination 集合中
sunionstore destination key1 [key2]
Redis中的zset是有序的集合,元素類型是string,元素具有唯一性,不能重覆,元素不能修改。
每個元素都會關聯⼀個double類型的score,表示權重,通過權重將元素從⼩到⼤排序
應用場景:排行榜系統
添加元素
zadd key score1 member1 score2 member2 ... #zzadd zmm 7 zs 8 ls 8 ww 9 zl
獲取元素
zrange key start stop #zrange 0-1
計算在有序集合中指定區間分數的成員數
zcount key min max
獲取有序集合的成員數
zcard key
返回有序集合中指定成員的索引
zrank key member
返回有序集中指定區間內的成員,通過索引,分數從高到低
zrevrange key start stop [WITHSCORES]
刪除指定元素
zrem key member1 member2 ...
移除有序集合中給定的分數區間的所有成員
zremrangebyscore key min max
移除有序集合中給定的排名區間的所有成員
zremrangebyrank key start stop
Redis的發佈訂閱
訂閱
subscribe 頻道名稱 [頻道名稱 ...]
發佈
publish 頻道 消息
取消訂閱
unsubscribe 頻道名稱 [頻道名稱 ...]
Redis的事務
Redis事務就是一次按照順序執行多個命令,Redis事務有兩個特點:
-
按順序執行,不會被其他客戶端的命令打斷
-
原子操作,要不不執行、要不全執行(業務報錯問題除外)
命令
MULTI | 標記一個事務開始 |
EXEC | 執行事務 |
DISCARD | 取消事務 |
WATCH | 監聽KEY,如果KEY在事務執行前被改變,事務取消執行 |
UNWATCH | 取消監聽KEY |
set user:A 100 #用戶A100 set user:B 50 #用戶B50
watch user:A #監聽用戶A
umlyi #開啟事務 decrby user:A 50 #用戶A減去50 incrby user:B 50 #用戶B加50 get user:A #查看 get user:B exec #執行
Redis持久化
提供了多種不同級別的持久化方式:一種是RDB,另一種是AOF。
RDB優點:
1.體積更小:相同的數據量rdb數據比aof的小,因為rdb是緊湊型文件 2.恢復更快:因為rdb是數據的快照,基本上就是數據的複製,不用重新讀取再寫入記憶體 3.性能更高:父進程在保存rdb時候只需要fork一個子進程,無需父進程的進行其他io操作,也保證了伺服器的性能。
RDB缺點:
1.故障丟失:因為rdb是全量的,我們一般是使用shell腳本實現30分鐘或者1小時或者每天對redis進行rdb備份,(註,也可以是用自帶的策略),
但是最少也要5分鐘進行一次的備份,所以當服務死掉後,最少也要丟失5分鐘的數據。 2.耐久性差:相對aof的非同步策略來說,因為rdb的複製是全量的,即使是fork的子進程來進行備份,當數據量很大的時候對磁碟的消耗也是不可忽視的,
尤其在訪問量很高的時候,fork的時間也會延長,導致cpu吃緊,耐久性相對較差。
AOF優點:
1.數據保證:我們可以設置fsync策略,一般預設是everysec,也可以設置每次寫入追加,所以即使服務死掉了,咱們也最多丟失一秒數據 2.自動縮小:當aof文件大小到達一定程度的時候,後臺會自動的去執行aof重寫,此過程不會影響主進程,重寫完成後,新的寫入將會寫到新的aof中,
舊的就會被刪除掉。但是此條如果拿出來對比rdb的話還是沒有必要算成優點,只是官網顯示成優點而已。
AOF缺點:
1.性能相對較差:它的操作模式決定了它會對redis的性能有所損耗 2.體積相對更大:儘管是將aof文件重寫了,但是畢竟是操作過程和操作結果仍然有很大的差別,體積也毋庸置疑的更大。 3.恢復速度更慢:
Redis的過期策略
我們都知道,Redis是key-value資料庫,我們可以設置Redis中緩存的key的過期時間。Redis的過期策略就是指當Redis中緩存的key過期了,Redis如何處理。
過期策略通常有以下三種:
-
定時過期:每個設置過期時間的key都需要創建一個定時器,到過期時間就會立即清除。該策略可以立即清除過期的數據,對記憶體很友好;但是會占用大量的CPU資源去處理過期的數據,從而影響緩存的響應時間和吞吐量。
-
惰性過期:只有當訪問一個key時,才會判斷該key是否已過期,過期則清除。該策略可以最大化地節省CPU資源,卻對記憶體非常不友好。極端情況可能出現大量的過期key沒有再次被訪問,從而不會被清除,占用大量記憶體。
-
定期過期:每隔一定的時間,會掃描一定數量的資料庫的expires字典中一定數量的key,並清除其中已過期的key。該策略是前兩者的一個折中方案。通過調整定時掃描的時間間隔和每次掃描的限定耗時,可以在不同情況下使得CPU和記憶體資源達到最優的平衡效果。 (expires字典會保存所有設置了過期時間的key的過期時間數據,其中,key是指向鍵空間中的某個鍵的指針,value是該鍵的毫秒精度的UNIX時間戳表示的過期時間。鍵空間是指該Redis集群中保存的所有鍵。)
Redis中同時使用了惰性過期和定期過期兩種過期策略。
Redis的記憶體淘汰策略
Redis的記憶體淘汰策略是指在Redis的用於緩存的記憶體不足時,怎麼處理需要新寫入且需要申請額外空間的數據。
-
noeviction:當記憶體不足以容納新寫入數據時,新寫入操作會報錯。
-
allkeys-lru:當記憶體不足以容納新寫入數據時,在鍵空間中,移除最近最少使用的key。
-
allkeys-random:當記憶體不足以容納新寫入數據時,在鍵空間中,隨機移除某個key。
-
volatile-lru:當記憶體不足以容納新寫入數據時,在設置了過期時間的鍵空間中,移除最近最少使用的key。
-
volatile-random:當記憶體不足以容納新寫入數據時,在設置了過期時間的鍵空間中,隨機移除某個key。
-
volatile-ttl:當記憶體不足以容納新寫入數據時,在設置了過期時間的鍵空間中,有更早過期時間的key優先移除。
總結
主從複製
在數據為王的時代,數據的安全是顯得尤為重要,數據我們可能要複製多份。
在網路時代,數據一般的特點是一次上傳,多次讀取,也就是需要我們實現讀寫分離。
上面這兩個功能,我們都可以用Redis的主從複製來解決。
-
一個master可以擁有多個slave,一個slave又可以擁有多個slave。
-
數據在自動從master端複製到slave端
-
master用來寫數據,slave用來讀數據,來實現讀寫分離
配置
複製出一份配置文件
cp redis.conf redis.slave.conf
編輯配置文件redis.slave.conf
port 6380 replicaof 127.0.0.1 6379
啟動redis
redis-server redis.slave.conf
查看主從關係
redis-cli -h ip info Replication
進入主端
redis-cli -h 127.0.0.1 -p 6379
寫入數據
set name master
進入從端
redis-cli -h 127.0.0.1 -p 6380
取出數據
get name
Redis集群
Redis集群採用無中心結構,每個節點都保存數據和整個集群狀態。每個節點都和其他所有節點連接。Redis集群模式通常具有 高可用、可擴展性、分散式、容錯等特點。
集群模型
配置
新建文件夾redis-cluster
mkdir redis-cluster
在文件夾下新建7001、7002、7003、7004、7005、7006文件夾,在每個新文件夾下都創建一個文件:redis.conf
port 7001 # 需要更換 bind 127.0.0.1 # 不同機器換不同ip daemonize yes pidfile 7001.pid # 需要更換 cluster-enabled yes cluster-config-file 7001_node.conf # 需要更換 cluster-node-timeout 15000 appendonly yes
不同的文件夾下的配置文件,port、pidfile、cluster-config-file 7001_node.conf 值是不一樣,依次排列。然後這個bind我現在是一臺機器,如果兩台機器,可以讓一臺綁定三個。
依次啟動每個文件夾下的配置文件
redis-server 7001/redis.conf
執⾏集群
redis-cli --cluster create 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 127.0.0.1:7006 --cluster-replicas 1
連接集群
redis-cli -c -h 127.0.0.1 -p 7001
集群知識
-
redis cluster在設計的時候,就考慮到了去中⼼化,去中間件,也就是說,集群中 的每個節點都是平等的關係,都是對等的,每個節點都保存各⾃的數據和整個集 群的狀態。每個節點都和其他所有節點連接,⽽且這些連接保持活躍,這樣就保 證了我們只需要連接集群中的任意⼀個節點,就可以獲取到其他節點的數據
-
Redis集群沒有並使⽤傳統的⼀致性哈希來分配數據,⽽是採⽤另外⼀種叫做哈希 槽 (hash slot)的⽅式來分配的。redis cluster 預設分配了 16384 個 slot,當我們 set⼀個key 時,會⽤CRC16演算法來取模得到所屬的slot,然後將這個key 分到哈 希槽區間的節點上,具體演算法就是:CRC16(key) % 16384。
-
Redis 集群會把數據存在⼀個 master 節點,然後在這個 master 和其對應的salve 之間進⾏數據同步。當讀取數據時,也根據⼀致性哈希演算法到對應的 master 節 點獲取數據。 只有當⼀個master 掛掉之後,才會啟動⼀個對應的 salve 節點,充 當 master
-
需要註意的是:必須要3個或以上的主節點