Redis 快速入门
簡介
Redis 是一個 Key-Value 存儲系統(tǒng)。和 Memcached 類似,它支持存儲的 value 類型相對更多,包括 string(字符串)、 list(鏈表)、 set(集合)和 zset(有序集合)。這些數(shù)據(jù)類型都支持 push/pop、add/remove 及取交集并集和差集及更豐富的操作,而且這些操作都是原子性的。在此基礎(chǔ)上, Redis 支持各種不同方式的排序。與 memcached 一樣,為了保證效率,數(shù)據(jù)都是緩存在內(nèi)存中。區(qū)別的是 Redis 會周期性的把更新的數(shù)據(jù)寫入磁盤或者把修改操作寫入追加的記錄文件,并且在此基礎(chǔ)上實(shí)現(xiàn)了 master-slave(主從)同步。
原子性:一個操作的不可以再分,操作要么執(zhí)行,要么不執(zhí)行。
初識 Redis
Redis 是一個開源的使用 ANSI C 語言編寫、支持網(wǎng)絡(luò)、可基于內(nèi)存亦可持久化的日志型、Key-Value數(shù)據(jù)庫,并提供多種語言的API。
數(shù)據(jù)類型
作為 Key-value 型數(shù)據(jù)庫, Redis 也提供了鍵(Key)和鍵值(Value)的映射關(guān)系。但是,除了常規(guī)的數(shù)值或字符串, Redis 的鍵值還可以是以下形式之一:
- Lists (列表)
- Sets (集合)
- Sorted sets (有序集合)
- Hashes (哈希表)
鍵值的數(shù)據(jù)類型決定了該鍵值支持的操作。 Redis 支持諸如列表、集合或有序集合的交集、并集、查集等高級原子操作;同時,如果鍵值的類型是普通數(shù)字,Redis 則提供自增等原子操作。
持久化
Redis 將數(shù)據(jù)存儲于內(nèi)存中,或被配置為使用虛擬內(nèi)存。通過兩種方式可以實(shí)現(xiàn)數(shù)據(jù)持久化:使用截圖的方式,將內(nèi)存中的數(shù)據(jù)不斷寫入磁盤;或使用類似 MySQL 的日志方式,記錄每次更新的日志。前者性能較高,但是可能會引起一定程度的數(shù)據(jù)丟失;后者相反。
主從同步
Redis 支持將數(shù)據(jù)同步到多臺從庫上,這種特性對提高讀取性能非常有益。
性能
相比需要依賴磁盤記錄每個更新的數(shù)據(jù)庫,基于內(nèi)存的特性無疑給 Redis 帶來了非常優(yōu)秀的性能。讀寫操作之間有顯著的性能差異。
適用場合
毫無疑問, Redis 開創(chuàng)了一種新的數(shù)據(jù)存儲思路,使用 Redis,我們不用在面對功能單調(diào)的數(shù)據(jù)庫時,把精力放在如何把大象放進(jìn)冰箱這樣的問題上,而是利用 Redis 靈活多變的數(shù)據(jù)結(jié)構(gòu)和數(shù)據(jù)操作,為不同的大象構(gòu)建不同的冰箱。
下面是 Redis 適用的一些場景:
取最新 N 個數(shù)據(jù)的操作
比如典型的取你網(wǎng)站的最新文章,通過下面方式,我們可以將最新的 5000 條評論的 ID 放在Redis 的 List 集合中,并將超出集合部分從數(shù)據(jù)庫獲取。
使用 LPUSH latest.comments<ID>命令,向 list 集合中插入數(shù)據(jù)
插入完成后再用 LTRIM latest.comments 0 5000 命令使其永遠(yuǎn)只保存最近 5000 個 ID
排行榜應(yīng)用,取 TOP N 操作
需要使用到 sorted set ,將你要排序的值設(shè)置成 sorted set 的 score(僅限支持float型 ),將具體的數(shù)據(jù)設(shè)置成相應(yīng)的 value,每次只需要執(zhí)行一條 ZADD 命令即可。
需要精準(zhǔn)設(shè)定過期時間的應(yīng)用
比如你可以把上面說到的 sorted set 的 score 值設(shè)置成過期時間的時間戳,那么就可以簡單地通過過期時間排序,定時清除過期數(shù)據(jù)了,不僅是清除 Redis 中的過期數(shù)據(jù),你完全可以把 Redis 里這個過期時間當(dāng)成是對數(shù)據(jù)庫中數(shù)據(jù)的索引,用 Redis 來找出哪些數(shù)據(jù)需要過期刪除,然后再精準(zhǔn)地從數(shù)據(jù)庫中刪除相應(yīng)的記錄。
計數(shù)器應(yīng)用
Redis 的命令都是原子性的,你可以輕松地利用 INCR, DECR 命令來構(gòu)建計數(shù)器系統(tǒng)。
redis中incr、incrby、decr、decrby屬于string數(shù)據(jù)結(jié)構(gòu),它們是原子性遞增或遞減操作。
- incr遞增1并返回遞增后的結(jié)果;
- incrby根據(jù)指定值做遞增或遞減操作并返回遞增或遞減后的結(jié)果(incrby遞增或遞減取決于傳入值的正負(fù));
- decr遞減1并返回遞減后的結(jié)果;
- decrby根據(jù)指定值做遞增或遞減操作并返回遞增或遞減后的結(jié)果(decrby遞增或遞減取決于傳入值的正負(fù));
Uniq 操作,獲取某段時間所有數(shù)據(jù)排重值
這個使用 Redis 的 set 數(shù)據(jù)結(jié)構(gòu)最合適了,只需要不斷地將數(shù)據(jù)往 set 中扔就行了, set 集合會自動排重。
實(shí)時系統(tǒng),反垃圾系統(tǒng)
通過上面說到的 set 功能,你可以知道一個終端用戶是否進(jìn)行了某個操作,可以找到其操作的集合并進(jìn)行分析統(tǒng)計對比等。
Pub/Sub 構(gòu)建實(shí)時消息系統(tǒng)
Redis 的 Pub/Sub 系統(tǒng)可以構(gòu)建實(shí)時的消息系統(tǒng),比如很多用 Pub/Sub 構(gòu)建的實(shí)時聊天系統(tǒng)的例子。
構(gòu)建隊(duì)列系統(tǒng)
使用 list 可以構(gòu)建隊(duì)列系統(tǒng),使用 sorted set 甚至可以構(gòu)建有優(yōu)先級的隊(duì)列系統(tǒng)
緩存
數(shù)據(jù)都是緩存在內(nèi)存中,效率更高。
Redis 安裝
使用 Docker 安裝方式,運(yùn)行下面命令:
# 安裝命令 docker run -itd --name redis -p 6379:6379 redis # 查看 Redis 運(yùn)行信息 docker ps # 連接 redis 服務(wù) docker exec -it redis /bin/bash redis-cliRedis 配置
-
daemonize:
默認(rèn)情況下, redis 不是在后臺運(yùn)行的,如果需要在后臺運(yùn)行,把該項(xiàng)的值更改為 yes。 -
pidfile
當(dāng) Redis 在后臺運(yùn)行的時候, Redis 默認(rèn)會把 pid 文件放在/var/run/redis.pid,你可以配置到其他地址。當(dāng)運(yùn)行多個 redis 服務(wù)時,需要指定不同的 pid 文件和端口。 -
bind
指定 Redis 只接收來自于該 IP 地址的請求,如果不進(jìn)行設(shè)置,那么將處理所有請求,在生產(chǎn)環(huán)境中最好設(shè)置該項(xiàng)。 -
port
監(jiān)聽端口,默認(rèn)為 6379。 -
timeout
設(shè)置客戶端連接時的超時時間,單位為秒。當(dāng)客戶端在這段時間內(nèi)沒有發(fā)出任何指令,那么關(guān)閉該連接。 -
loglevel
log 等級分為 4 級,debug, verbose, notice, 和 warning。生產(chǎn)環(huán)境下一般開啟 notice。 -
logfile
配置 log 文件地址,默認(rèn)使用標(biāo)準(zhǔn)輸出,即打印在命令行終端的窗口上。 -
databases
設(shè)置數(shù)據(jù)庫的個數(shù),可以使用 SELECT <dbid>命令來切換數(shù)據(jù)庫。默認(rèn)使用的數(shù)據(jù)庫是 0。 -
save
設(shè)置 Redis 進(jìn)行數(shù)據(jù)庫鏡像的頻率。
if(在 60 秒之內(nèi)有 10000 個 keys 發(fā)生變化時){
進(jìn)行鏡像備份
}else if(在 300 秒之內(nèi)有 10 個 keys 發(fā)生了變化){
進(jìn)行鏡像備份
}else if(在 900 秒之內(nèi)有 1 個 keys 發(fā)生了變化){
進(jìn)行鏡像備份
} -
rdbcompression
在進(jìn)行鏡像備份時,是否進(jìn)行壓縮。 -
dbfilename
鏡像備份文件的文件名。 -
dir
數(shù)據(jù)庫鏡像備份的文件放置的路徑。這里的路徑跟文件名要分開配置是因?yàn)?Redis 在進(jìn)行備份時,先會將當(dāng)前數(shù)據(jù)庫的狀態(tài)寫入到一個臨時文件中,等備份完成時,再把該該臨時文件替換為上面所指定的文件,而這里的臨時文件和上面所配置的備份文件都會放在這個指定的路徑當(dāng)中。 -
slaveof
設(shè)置該數(shù)據(jù)庫為其他數(shù)據(jù)庫的從數(shù)據(jù)庫。 -
masterauth
當(dāng)主數(shù)據(jù)庫連接需要密碼驗(yàn)證時,在這里指定。 -
requirepass
設(shè)置客戶端連接后進(jìn)行任何其他指定前需要使用的密碼。警告:因?yàn)?redis 速度相當(dāng)快,所以在一臺比較好的服務(wù)器下,一個外部的用戶可以在一秒鐘進(jìn)行 150K 次的密碼嘗試,這意味著你需要指定非常非常強(qiáng)大的密碼來防止暴力破解。
-
maxclients
限制同時連接的客戶數(shù)量。當(dāng)連接數(shù)超過這個值時, redis 將不再接收其他連接請求,客戶端嘗試連接時將收到 error 信息。 -
maxmemory
設(shè)置 redis 能夠使用的最大內(nèi)存。當(dāng)內(nèi)存滿了的時候,如果還接收到 set 命令, redis 將先嘗試剔除設(shè)置過 expire 信息的 key,而不管該 key 的過期時間還沒有到達(dá)。**在刪除時,將按照過期時間進(jìn)行刪除,最早將要被過期的 key 將最先被刪除。如果帶有 expire 信息的 key 都刪光了,那么將返回錯誤。**這樣, redis 將不再接收寫請求,只接收 get 請求。maxmemory 的設(shè)置比較適合于把 redis 當(dāng)作于類似 memcached 的緩存來使用。 -
appendonly
默認(rèn)情況下, redis 會在后臺異步的把數(shù)據(jù)庫鏡像備份到磁盤,但是該備份是非常耗時的,而且備份也不能很頻繁,如果發(fā)生諸如拉閘限電、拔插頭等狀況,那么將造成比較大范圍的數(shù)據(jù)丟失。所以 redis 提供了另外一種更加高效的數(shù)據(jù)庫備份及災(zāi)難恢復(fù)方式。開啟 append only 模式之后, redis 會把所接收到的每一次寫操作請求都追加到appendonly.aof 文件中,當(dāng) redis 重新啟動時,會從該文件恢復(fù)出之前的狀態(tài)。但是這樣會造成 appendonly.aof 文件過大,所以 redis 還支持了 BGREWRITEAOF 指令,對appendonly.aof 進(jìn)行重新整理。所以我認(rèn)為推薦生產(chǎn)環(huán)境下的做法為關(guān)閉鏡像,開啟appendonly.aof,同時可以選擇在訪問較少的時間每天對 appendonly.aof 進(jìn)行重寫一次。 -
appendfsync
設(shè)置對 appendonly.aof 文件進(jìn)行同步的頻率。 always 表示每次有寫操作都進(jìn)行同步,everysec 表示對寫操作進(jìn)行累積,每秒同步一次。這個需要根據(jù)實(shí)際業(yè)務(wù)場景進(jìn)行配置 -
vm-enabled
是否開啟虛擬內(nèi)存支持。因?yàn)?redis 是一個內(nèi)存數(shù)據(jù)庫,而且當(dāng)內(nèi)存滿的時候,無法接收新的寫請求,所以在 redis 2.0 中,提供了虛擬內(nèi)存的支持。但是需要注意的是, redis中,所有的 key 都會放在內(nèi)存中,在內(nèi)存不夠時,只會把 value 值放入交換區(qū)。這樣保證了雖然使用虛擬內(nèi)存,但性能基本不受影響,同時,你需要注意的是你要把vm-max-memory 設(shè)置到足夠來放下你的所有的 key -
vm-swap-file
設(shè)置虛擬內(nèi)存的交換文件路徑 -
vm-max-memory
這里設(shè)置開啟虛擬內(nèi)存之后, redis 將使用的最大物理內(nèi)存的大小。默認(rèn)為 0, redis 將把他所有的能放到交換文件的都放到交換文件中,以盡量少的使用物理內(nèi)存。在生產(chǎn)環(huán)境下,需要根據(jù)實(shí)際情況設(shè)置該值,最好不要使用默認(rèn)的 0 -
vm-page-size
設(shè)置虛擬內(nèi)存的頁大小,如果你的 value 值比較大,比如說你要在 value 中放置博客、新聞之類的所有文章內(nèi)容,就設(shè)大一點(diǎn),如果要放置的都是很小的內(nèi)容,那就設(shè)小一點(diǎn)。 -
vm-pages
設(shè)置交換文件的總的 page 數(shù)量,需要注意的是, page table 信息會放在物理內(nèi)存中,每8 個 page 就會占據(jù) RAM 中的 1 個 byte。總的虛擬內(nèi)存大小 = vm-page-size * vm-pages。 -
vm-max-threads
設(shè)置 VM IO 同時使用的線程數(shù)量。因?yàn)樵谶M(jìn)行內(nèi)存交換時,對數(shù)據(jù)有編碼和解碼的過程,所以盡管 IO 設(shè)備在硬件上本上不能支持很多的并發(fā)讀寫,但是還是如果你所保存的 vlaue 值比較大,將該值設(shè)大一些,還是能夠提升性能的。 -
glueoutputbuf
把小的輸出緩存放在一起,以便能夠在一個 TCP packet 中為客戶端發(fā)送多個響應(yīng),具體原理和真實(shí)效果我不是很清楚。所以根據(jù)注釋,你不是很確定的時候就設(shè)置成 yes。 -
hash-max-zipmap-entries
在 redis 2.0 中引入了 hash 數(shù)據(jù)結(jié)構(gòu)。當(dāng) hash 中包含超過指定元素個數(shù)并且最大的元素沒有超過臨界時, hash 將以一種特殊的編碼方式(大大減少內(nèi)存使用)來存儲,這里可以設(shè)置這兩個臨界值 -
activerehashing
開啟之后, redis 將在每 100 毫秒時使用 1 毫秒的 CPU 時間來對 redis 的 hash 表進(jìn)行重新 hash,可以降低內(nèi)存的使用。當(dāng)你的使用場景中,有非常嚴(yán)格的實(shí)時性需要,不能夠接受 Redis 時不時的對請求有 2 毫秒的延遲的話,把這項(xiàng)配置為 no。如果沒有這么嚴(yán)格的實(shí)時性要求,可以設(shè)置為 yes,以便能夠盡可能快的釋放內(nèi)存。
簡單操作數(shù)據(jù)庫
-
插入數(shù)據(jù)
127.0.0.1:6379> set name Jacob OK -
查詢數(shù)據(jù)
127.0.0.1:6379> get name "Jacob" -
刪除數(shù)據(jù)
127.0.0.1:6379> del name (integer) 1127.0.0.1:6379> del name3 (integer) 0其中 integer 表示:被刪除 key 的數(shù)量。
-
驗(yàn)證 key 是否存在
127.0.0.1:6379> exists name (integer) 1127.0.0.1:6379> exists name2 (integer) 0其中 0,代表此 key 不存在; 1 代表存在。
總結(jié)
以上是生活随笔為你收集整理的Redis 快速入门的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 前端学习(11):标题和段落
- 下一篇: Redis 中常用命令