Redis特點
- 高效能的key/value資料庫
- 基於記憶體
- 資料型別豐富
- 持久化
- 單執行緒
- 訂閱/釋出模型
對比memcached
- 不僅支援簡單k/v型別資料,還提供list、set、hash等資料結構儲存
- 支援資料的主從複製
- 支援資料的持久化,可以將記憶體中的資料儲存到磁碟,重啟的時候再次載入原有資料
- 單個value最新限制1GB,memcached智慧儲存1MB的資料
應用場景
- 叢集環境下的session管理
- 充當web快取
- 充當訊息佇列
redis部署
# 手動安裝
下載 redis-*.tar.gz
# tar zxf redis-*.tar.gz
# cd redis-*.tar.gz
# make PREFIX=/usr/local/redis install
# mkdir /usr/local/redis/etc
# cp redis.conf /usr/local/redis/etc/
啟動
1. /usr/local/redis/bin/server
1. /usr/local/redis/bin/server /usr/local/redis/etc/redis.conf
# 自動安裝的話,一行命令即可
管理命令
save 將資料同步儲存在磁碟
bgsave 將資料非同步儲存到磁碟
lastsave 返回上次成功將資料儲存到磁碟的UNIX時間戳
shutdown 將資料同步儲存到磁碟,然後關閉服務
info 提供伺服器的資訊和統計
monitor 實時轉儲收單的請求
slaveof 改變複製策略設定
config 在執行時配置伺服器
quit 關閉連線
auth 簡單密碼認證
資料型別及操作
- string 字串
- hash 鍵值都為字串的雜湊表
- list 字串列表
- set 無序不重複的字串集合
- zset 有序…
字串型別是 Redis 提供的最基本的資料型別,對應的結構是 key-value。
set key value
get key
雜湊(hash)提供了欄位和欄位值的對映,對應的結構是 key-field-value。
hset user1 username zhangfei
hset user1 age 28
Hmset user1 username zhangfei age 28
hget key field
hget user1 username
hmget key field[field...]
hmget user1 username age
字串列表(list)的底層是一個雙向連結串列結構,所以我們可以向列表的兩端新增元素,時間複雜度都為 O(1),同時我們也可以獲取列表中的某個片段。
向列表左側增加元素可以使用:LPUSH key value [...]
LPUSH heroList zhangfei guanyu liubei
RPUSH key value [...]向列表右側新增元素
RPUSH heroList dianwei lvbu
想要獲取列表中某一片段的內容,使用LRANGE key start stop
LRANGE heroList 0 4
字串集合(set)是字串型別的無序集合,與列表(list)的區別在於集合中的元素是無序的,同時元素不能重複。
在集合中新增元素,可以使用SADD key member [...]
SADD heroSet zhangfei guanyu liubei dianwei lvbu
在集合中刪除某元素,可以使用SREM key member [...]
SREM heroSet liubei lvbu
獲取集合中所有的元素,可以使用SMEMBERS key
SMEMBERS heroSet
判斷集合中是否存在某個元素,可以使用SISMEMBER key member
SISMEMBER heroSet zhangfei
SISMEMBER heroSet liubei
我們可以把有序字串集合(SortedSet,簡稱 ZSET)理解成集合的升級版。
實際上 ZSET 是在集合的基礎上增加了一個分數屬性,這個屬性在新增修改元素的時候可以被指定。
每次指定後,ZSET 都會按照分數來進行自動排序,也就是說我們在給集合 key 新增 member 的時候,可以指定 score。
在有序集合中新增元素和分數,使用ZADD key score member [...]
ZADD heroScore 8341 zhangfei 7107 guanyu 6900 liubei 7516 dianwei 7344 lvbu
獲取某個元素的分數,可以使用ZSCORE key member
ZREM heroScore gu獲取某個範圍的元素列表。
如果想要分數從小到大進行排序,使用ZRANGE key start stop [WITHSCORES],
如果分數從大到小進行排序,使用ZREVRANGE key start stop [WITHSCORES]。
需要注意的是,WITHSCORES 是個可選項,如果使用 WITHSCORES 會將分數一同顯示出來anyu
ZREVRANGE heroScore 0 2 WITHSCORES
除了這 5 種資料型別以外,Redis 還支援點陣圖(Bitmaps)資料結構,
在 2.8 版本之後,增加了基數統計(HyperLogLog),
3.2 版本之後加入了地理空間(Geospatial)以及索引半徑查詢的功能,
在 5.0 版本引用了資料流(Streams)資料型別。
Redis 的事務處理機制
Redis 的事務處理與 RDBMS 的事務有一些不同。
首先 Redis 不支援事務的回滾機制(Rollback),這也就意味著當事務發生了錯誤(只要不是語法錯誤),
整個事務依然會繼續執行下去,直到事務佇列中所有命令都執行完畢。
在Redis 官方文件中說明了為什麼 Redis 不支援事務回滾。
只有當程式設計語法錯誤的時候,Redis 命令執行才會失敗。這種錯誤通常出現在開發環境中,而很少出現在生產環境中,沒有必要開發事務回滾功能。
另外,Redis 是記憶體資料庫,與基於檔案的 RDBMS 不同,通常只進行記憶體計算和操作,無法保證永續性。
不過 Redis 也提供了兩種持久化的模式,分別是 RDB 和 AOF 模式。
RDB(Redis DataBase)持久化可以把當前程式的資料生成快照儲存到磁碟上,觸發 RDB 持久化的方式分為手動觸發和自動觸發。
因為持久化操作與命令操作不是同步進行的,所以無法保證事務的永續性。
AOF(Append Only File)持久化採用日誌的形式記錄每個寫操作,彌補了 RDB 在資料一致性上的不足,
但是採用 AOF 模式,就意味著每條執行命令都需要寫入檔案中,會大大降低 Redis 的訪問效能。
啟用 AOF 模式需要手動開啟,有 3 種不同的配置方式,預設為 everysec,也就是每秒鐘同步一次。
其次還有 always 和 no 模式,分別代表只要有資料發生修改就會寫入 AOF 檔案,以及由作業系統決定什麼時候記錄到 AOF 檔案中。
雖然 Redis 提供了兩種持久化的機制,但是作為記憶體資料庫,永續性並不是它的擅長。
Redis 是單執行緒程式,在事務執行時不會中斷事務,其他客戶端提交的各種操作都無法執行,
因此可以理解為 Redis 的事務處理是序列化的方式,總是具有隔離性的。
Redis 的事務處理的命令
MULTI:開啟一個事務;
EXEC:事務執行,將一次性執行事務內的所有命令;
DISCARD:取消事務;
WATCH:監視一個或多個鍵,如果事務執行前某個鍵發生了改動,那麼事務也會被打斷;
UNWATCH:取消 WATCH 命令對所有鍵的監視。
需要說明的是 Redis 實現事務是基於 COMMAND 佇列,
如果 Redis 沒有開啟事務,那麼任何的 COMMAND 都會立即執行並返回結果。
如果 Redis 開啟了事務,COMMAND 命令會放到佇列中,並且返回排隊的狀態 QUEUED,
只有呼叫 EXEC,才會執行 COMMAND 佇列中的命令。
玩家排行榜案例
統計全部玩家的排行榜
ZREVRANGE user_score 0 -1 WITHSCORES
按名次查詢排名前 N 名的玩家
統計前 10 名玩家,可以使用:ZREVRANGE user_score 0 9
查詢某個玩家的分數
查詢玩家 10001 的分數可以使用:ZSCORE user_score 10001
查詢某個玩家的排名
查詢玩家 10001 的排名可以使用:ZREVRANK user_score 10001
對玩家的分數和排名進行更新
對玩家 10001 的分數減 1,可以使用:ZINCRBY user_score -1 10001
查詢指定玩家前後 M 名的玩家
查詢玩家 10001 前後 5 名玩家都是誰,當前已知玩家 10001 的排名是 18036,
那麼可以使用:ZREVRANGE user_score 18031 18041
增加或移除某個玩家,並對排名進行更新
刪除玩家 10001,可以使用:ZREM user_score 10001
查詢下排名在 18031 到 18041 的玩家是誰,使用:ZREVRANGE user_score 18031 18041
把玩家 10001 的資訊再增加回來,使用:ZADD user_score 93.1504697596 10001
看下排名在 18031 到 18041 的玩家是誰,使用:ZREVRANGE user_score 18031 18041
本作品採用《CC 協議》,轉載必須註明作者和本文連結