
資源串列:
Redis 命令參考
Commands
Redis是什么
Redis是一個開源(BSD許可)的記憶體中的資料結構存盤,用作資料庫、快取和訊息中間件,它支持多種資料結構,如字串、哈希表、串列、無序集合、有序集合的范圍查詢,位圖、基數統計和地理空間索引的與查詢,Redis內置復制、Lua腳本、LRU回收、事務和不同級別的磁盤持久化,并通過哨兵和自動磁區提供高可用性集群,
單執行緒結構
- 純記憶體資料庫,瓶頸不在記憶體,在于網路IO
- 單執行緒,避免頻繁切換背景關系
- 異步阻塞I/O(多路復用)
持久化
RDB(Redis DataBase)持久化
- 快照
- 優點:適合備份、還原、恢復資料快、最大化 Redis 的性能
- 缺點:兩次快照間的資料會丟失、資料集比較龐大時,
fork()可能會非常耗時
AOF(Append Only File)持久化
- 日志
- 優點:資料完整性高、可讀性高、可重寫(重寫后的新 AOF 檔案包含了恢復當前資料集所需的最小命令集合)
- 缺點:體積大、慢于RDB、有bug
事務
multi開啟事務,exec執行事務

可以看到,redis事務實作原理是將要執行的命令,存盤到一個佇列中,依次執行,報錯時停止并取消事務,不報錯則提交事務,
例外:不會回滾的情況:
當一個事務中某一條(多條)命令加入佇列不報錯,執行時才會報錯,則redis會忽略錯誤繼續執行,
使用watch監視一個(或多個) key ,如果在事務執行之前這個(或這些) key 被其他命令所改動,那么事務將被打斷,當exec被呼叫時, 不管事務是否成功執行, 對所有鍵的監視都會被取消,或者呼叫unwatch手動取消監控,
管道
- pipeline通過減少客戶端與redis的通信次數來實作降低往返延時時間,而且Pipeline 實作的原理是佇列,而佇列的原理是時先進先出,這樣就保證資料的順序性,
- 適用場景:批量操作、可靠性要求不高、
Lua腳本
Lua是一個高效的輕量級腳本語言,用標準C語言撰寫并以源代碼形式開放, 其設計目的是為了嵌入應用程式中,從而為應用程式提供靈活的擴展和定制功能,從定義上來說, Redis 中的腳本本身就是一種事務, 所以任何在事務里可以完成的事, 在腳本里面也能完成, 并且一般來說, 使用腳本要來得更簡單,并且速度更快,
- 通過lua腳本可以原子執行多條redis命令
- 執行lua腳本期間,會阻塞所有命令操作
使用腳本的好處
- 減少網路開銷,在Lua腳本中可以把多個命令放在同一個腳本中運行
- 原子操作,redis會將整個腳本作為一個整體執行,中間不會被其他命令插入,換句話說,撰寫腳本的程序中無需擔心會出現競態條件
- 復用性,客戶端發送的腳本會永遠存盤在redis中,這意味著其他客戶端可以復用這一腳本來完成同樣的邏輯
多資料庫支持
默認支持16個資料庫;可以理解為一個命名空間
跟關系型資料庫不一樣的點
- redis不支持自定義資料庫名詞
- 每個資料庫不能單獨設定授權
- 每個資料庫之間并不是完全隔離的, 可以通過flushall命令清空redis實體面的所有資料庫中的資料
通過 select dbid 去選擇不同的資料庫命名空間 , dbid的取值范圍默認是0 -15
分布式集群
Redis Cluster中,Sharding采用slot(槽)的概念,一共分成16384個槽,這有點兒類似前面講的pre sharding思路,對于每個進入Redis的鍵值對,根據key進行散列,分配到這16384個slot中的某一個中,使用的hash演算法也比較簡單,就是CRC16后16384取模,Redis集群中的每個node(節點)負責分攤這16384個slot中的一部分,也就是說,每個slot都對應一個node負責處理,當動態添加或減少node節點時,需要將16384個槽做個再分配,槽中的鍵值也要遷移,當然,這一程序,在目前實作中,還處于半自動狀態,需要人工介入,Redis集群,要保證16384個槽對應的node都正常作業,如果某個node發生故障,那它負責的slots也就失效,整個集群將不能作業,為了增加集群的可訪問性,官方推薦的方案是將node配置成主從結構,即一個master主節點,掛n個slave從節點,這時,如果主節點失效,Redis Cluster會根據選舉演算法從slave節點中選擇一個上升為主節點,整個集群繼續對外提供服務,這非常類似服務器節點通過Sentinel監控架構成主從結構,只是Redis Cluster本身提供了故障轉移容錯的能力,
- redis sharding
- codis
- twemproxy
支持的資料型別、常用命令、常用場景
String
默認存盤最大容量為512M
常用命令:set、get、incr、decr、append、strlen、mget、setnx
- set+get:快取、單點登錄
- bitmap:用戶上線次數統計
- incr:計數器、限速器
List
有序,可重復
常用命令:lpush、rpush、lpop、rpop、llen、lrange、lrem、lset
- lpush+lpop:Stack(堆疊)
- lpush+rpop:Queue(佇列)
- lpush+ltrim:Capped Collection(有限集合)
- lpush+brpop:Message Queue(訊息佇列)
- blpop:事件提醒(替代輪詢)
Hash
不支持資料型別的嵌套
適合存盤物件
常用命令:hset、hget、[hmset](http://doc.redisfans.com/hash/hmset
,.html)、hmget、hgetall、hexists、hincrby、hsetnx、hdel
Set
無序、不重復
常用命令:sadd、srem、smembers、sdiff、sunion、sinter
- sadd:標簽
- sinter:交集
- sunion:并集
SortedSet
有序、不重復
常用命令:zadd、zrange
- zcount:統計資訊
- zrevrange:排行榜
key
常用命令:expire、ttl
Script
常用命令:eval
Redis安裝
安裝
首先,到redis官網找到要安裝的redis版本,Redis下載頁,我們這里選用v4.0.11,依次執行下面命令:
# wget http://download.redis.io/releases/redis-4.0.11.tar.gz
# tar xzf redis-4.0.11.tar.gz
# cd redis-4.0.11
# make
到此安裝完成,然后可以通過make test測驗編譯狀態
# make test
無報錯完成編譯應該會有這樣的輸出:

報錯:需要tcl 8.5以上來運行redis test
You need tcl 8.5 or newer in order to run the Redis test
make: *** [test] Error 1
下面安裝tcl8.6.1:
# wget http://downloads.sourceforge.net/tcl/tcl8.6.1-src.tar.gz
# sudo tar xzvf tcl8.6.1-src.tar.gz
# cd tcl8.6.1/unix/
# sudo ./configure
# sudo make
# sudo make install
再次運行make test,沒問題之后,運行最后一步,完成安裝:
# make install

直接啟動:
# ./redis-server ../redis.conf

后臺啟動redis,只需修改redis.conf組態檔的daemonize yes,再次啟動即可,

安裝啟動相關命令
啟動redis服務器:
# ./redis-server ../redis.conf
停止redis服務:
# ./redis-cli shutdown
連接本地啟動好的redis:
# redis-cli
根據ip埠連接redis:
# redis-cli -h 127.0.0.1 -p 6379
查看當前是否設定了密碼
127.0.0.1:6379> config get requirepass
1) "requirepass"
2) ""
設定密碼
127.0.0.1:6379> config set requirepass 123456 //密碼是123456
OK
使用總結
關于key
- 建議key不要太長,不要超過1024位元組,占用記憶體且會降低查詢效率
- 建議統一命名規則,例如:String:001:zhangsan:age
使用 bitmap 實作用戶上線次數統計
Bitmap 對于一些特定型別的計算非常有效,
假設現在我們希望記錄自己網站上的用戶的上線頻率,比如說,計算用戶 A 上線了多少天,用戶 B 上線了多少天,諸如此類,以此作為資料,從而決定讓哪些用戶參加 beta 測驗等活動 —— 這個模式可以使用 SETBIT 和 BITCOUNT 來實作,
比如說,每當用戶在某一天上線的時候,我們就使用 SETBIT ,以用戶名作為 key ,將那天所代表的網站的上線日作為 offset 引數,并將這個 offset 上的為設定為 1 ,
舉個例子,如果今天是網站上線的第 100 天,而用戶 peter 在今天閱覽過網站,那么執行命令 SETBIT peter 100 1 ;如果明天 peter 也繼續閱覽網站,那么執行命令 SETBIT peter 101 1 ,以此類推,
當要計算 peter 總共以來的上線次數時,就使用 BITCOUNT 命令:執行 BITCOUNT peter ,得出的結果就是 peter 上線的總天數,
更詳細的實作可以參考博文(墻外) Fast, easy, realtime metrics using Redis bitmaps ,
快取
快取一致性
- 先更新庫資料,再洗掉快取
快取擊穿和快取雪崩
分布式鎖的實作
setnx+lua實作
public class RedisTool {
private static final String LOCK_SUCCESS = "OK";
private static final String SET_IF_NOT_EXIST = "NX";
private static final String SET_WITH_EXPIRE_TIME = "PX";
private static final Long RELEASE_SUCCESS = 1L;
// 獲取鎖
public static boolean getLock(Jedis jedis, String lockKey, String requestId, int expireTime) {
String result = jedis.set(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime);
if (LOCK_SUCCESS.equals(result)) {
return true;
}
return false;
}
// 釋放鎖
public static boolean releaseLock(Jedis jedis, String lockKey, String requestId) {
String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
Object result = jedis.eval(script, Collections.singletonList(lockKey), Collections.singletonList(requestId));
if (RELEASE_SUCCESS.equals(result)) {
return true;
}
return false;
}
}
搶紅包,秒殺的實作
incr+lua腳本實作
參考鏈接:
http://doc.redisfans.com
https://blog.csdn.net/liqingtx/article/details/60330555
更多資訊可以關注我的個人博客:逸竹小站
也歡迎關注我的公眾號:yizhuxiaozhan,二維碼:
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/234701.html
標籤:其他

