Redis 管道(Pipelining)
Redis 管道(Pipelining):一次請求/響應服務器能實現處理新的請求即使舊的請求還未被響應。這樣就可以將多個命令發送到服務器,而不用等待回覆,最後在一個步驟中讀取該答覆。
管道的作用,降低通信成本。
linux下 : echo -e "set k2 100\n get k2" | nc localhost 6379
\n 會自動識別爲多條命令。
例如:啓動的時候需要冷加載大量的數據到redis中。
Pub/Sub 消息訂閱
publish : 推送
subscribe : 訂閱
PUBLISH number1 "get is reply": 推送消息 "get is reply" 到 number1頻道
開啓兩個客戶端。A未進行訂閱,B先於發送,這時A端接收不到,因爲沒進行任何的訂閱。
A進行訂閱 number1 ,B進行發送,,可以看到已經接收成功了。
訂閱多個頻道
PSUBSCRIBE 通配符訂閱
PSUBSCRIBE number* : 訂閱 number 開頭的所有頻道
事務相關命令
MULTI、EXEC、DISCARD、WATCH
MULTI:標記一個事務塊的開始。 隨後的指令將在執行EXEC時作爲一個原子執行。
DISCARD:取消事務
WATCH:監控一個或多個key,如果在執行事務前這些key被更改,則事務被打斷。先watch key,然後 multi,然後exec。
爲什麼 Redis 不支持回滾(roll back)
如果你有使用關係式數據庫的經驗, 那麼 “Redis 在事務失敗時不進行回滾,而是繼續執行餘下的命令”這種做法可能會讓你覺得有點奇怪。
以下是這種做法的優點:
- Redis 命令只會因爲錯誤的語法而失敗(並且這些問題不能在入隊時發現),或是命令用在了錯誤類型的鍵上面:這也就是說,從實用性的角度來說,失敗的命令是由編程錯誤造成的,而這些錯誤應該在開發的過程中被發現,而不應該出現在生產環境中。
- 因爲不需要對回滾進行支持,所以 Redis 的內部可以保持簡單且快速。
1. 不支持事務回滾所以redis比較快
2. redis只會因爲錯誤的語法而失敗,而這些編程中的錯誤應該在被開發中發現,而不應該出現在生產中。
1. A端查詢keys 爲空,B端開啓事務MULTI,set k1 ,k2。這時A端繼續get k1,但是沒查詢到。因爲B端沒有EXEC提交事務。
2. B端提交,A端查詢。
事務處理順序
B端先開啓事務,設置k1 111,A端查詢k1,開啓事務,設置k1 999,A端提交事務。查詢k1。B端提交事務。
exec 誰先提交算誰的。不會回滾。
EXPIRE key seconds
ex
set k1 ddd ex 5 : 設置 k1 過期時間爲 5秒, EX 後面跟秒
修改k1 的時候不會延長過期時間,但是會影響使過期時間失效
EXPIREAT
EXPIREAT k1 1592354325: 設置k1 在某個時間戳的時候過期。
persist key : 清除某個key的過期時間
ttl
ttl k1 查看過期時間(秒)。 返回 -2 :過期,-1 :永不過期,大於0則是剩餘的有效期秒數
px
set k2 aaa px 500000 : 設置過期時間 px 後面跟毫秒
nx
當則會個key不存在的時候也可以成功,即沒有就新增
xx
當這個key不存在的時候失敗,即key必須存在
Redis如何淘汰過期的keys
Redis keys過期有兩種方式:被動和主動方式。
當一些客戶端嘗試訪問它時,key會被發現並主動的過期。
當然,這樣是不夠的,因爲有些過期的keys,永遠不會訪問他們。 無論如何,這些keys應該過期,所以定時隨機測試設置keys的過期時間。所有這些過期的keys將會從密鑰空間刪除。
具體就是Redis每秒10次做的事情:
- 測試隨機的20個keys進行相關過期檢測。
- 刪除所有已經過期的keys。
- 如果有多於25%的keys過期,重複步奏1.
過期判斷原理:
1.被動訪問時判定。即在訪問時發現過期了才做判定。
2.週期輪詢判定(增量)。即使用上方的淘汰機制隨機判定。
目的:稍微犧牲下內存,但是保住了redis性能爲王。
將redis當做使用LRU算法的緩存來使用
回收策略
當maxmemory限制達到的時候Redis會使用的行爲由 Redis的maxmemory-policy配置指令來進行配置
策略:
當作爲數據庫的時候不推薦使用,否則會造成數據丟失
- noeviction:返回錯誤當內存限制達到並且客戶端嘗試執行會讓更多內存被使用的命令(大部分的寫入指令,但DEL和幾個例外)
作爲緩存的時候可以考慮(前二)
- allkeys-lru: 嘗試回收所有數據中最少使用的鍵(LRU),使得新添加的數據有空間存放。釋放使用不多的鍵
- volatile-lru: 嘗試回收已經過期的數據中最少使用的鍵(LRU),使得新添加的數據有空間存放。多久沒使用
- allkeys-random: 回收所有數據中隨機的鍵使得新添加的數據有空間存放。太隨意不推薦
- volatile-random: 回收過期的數據中隨機的鍵使得新添加的數據有空間存放。太隨意不推薦
- volatile-ttl: 回收在過期集合的鍵,將要過期的鍵,存活時間(TTL)較短的鍵,使得新添加的數據有空間存放。 時間成本太高
redis作爲數據庫/緩存的區別
1.key的有效期。發生寫,會影響過期時間倒計時,且redis不能延長定時。
2.內存是有限的,隨着訪問的變化應該淘汰掉冷數據。
管道批量獲取數據並清除
/**
* 批量獲取數據並清除
*/
List<Person> people = redisTemplate.executePipelined(new SessionCallback<List>() {
@Override
public <K, V> List<Person> execute(RedisOperations<K, V> operations) throws DataAccessException {
operations.multi();
List<Person> people = redisTemplate.opsForList().range("lists",0,500);
redisTemplate.opsForList().trim("lists",0,500);
return people;
}
});
https://cloud.tencent.com/developer/article/1554080
redis中文站 : http://redis.cn/topics/pipelining.html