事務提供了一種將多個命令請求打包,而後一次性、按順序地執行多個命令的機制。
而且在事務執行期間,服務器不會中斷事務而改去執行其餘客戶端的命令請求,它會將事務中的全部命令都執行完畢,而後纔去處理其餘客戶端的命令請求。redis
知足事務一致性和隔離性算法
非原子性
在redis事務中若是有某一條命令執行失敗,其後的命令仍然會被繼續執行,並不會回滾。數據庫
非持久性
在 RDB 模式下,服務器可能在事務執行以後、RDB文件更新以前的這段時間失敗,因此RDB模式下的Redis事務也是不持久的;在AOF的」老是SYNC「模式下,事務的每條命令在執行成功以後,都會當即調用fsync或fdatasync將事務數據寫入到AOF文件。可是,這種保存是由後臺線程進行的,主線程不會阻塞直到保存成功。因此從命令執行成功到數據保存到硬盤之間,仍是有一段很是小的間隔,因此這種模式下的事務也是不持久的。服務器
遇到有查詢的狀況穿插在事務中間,不會返回結果:設置事務開始標誌後,全部的命令都是queued,即便是查詢指令。 若是後續的更新操做須要依賴於前面的查詢指令,那redis事務就沒法有效的完成任務。網絡
事實上,事務中的每條命令都與redis服務器進行了一次網絡交互。併發
小優化:
對於全部的get/set操做,可以使用現有的mget/mset指令;對於各類不一樣類型的更新操做,可以使用lua腳本將命令打包後,發送到服務器端一次執行。dom
multi -> 啓動一個事務 incr t1 -> 添加該命令到隊列中 incr t2 -> 添加該命令到隊列中 discard -> 事務回滾 exec -> 執行
在multi命令執行以前,能夠指定待監控的Keys,然而在執行exec時,若是被監控的Keys發生修改,exec將放棄執行該事務隊列中的全部命令。async
多客戶端併發執行狀況下出現競態爭用,僞代碼以下:性能
val = get mykey val = val + 1 set mykey $val
客戶端A和B都在同一時刻讀取了mykey的原有值,假設該值爲10,此後兩個客戶端又均將該值加1後set回Redis服務器,這樣就會致使mykey的結果爲11,而不是咱們認爲的12。優化
watch命令可用於提供基於CAS的樂觀鎖,僞代碼以下:
watch mykey val = get mykey val = val + 1 multi set mykey $val exec
若是當前鏈接獲取的mykey的值被其它鏈接的客戶端修改,那麼當前鏈接的exec命令將執行失敗。
在讀取一個鍵以後(讀操做和寫操做都要對鍵進行讀取),服務器會根據鍵是否存在來更新服務器的鍵空間命中(hit) 次數或鍵空間不命中(miss)次數,這兩個值能夠在INFO stats 命令的keyspace_hits屬性和keyspace_misses屬性中查看。
在讀取一個鍵以後,服務器會更新鍵的LRU(最後一次使用)時間,這個值能夠用於計算鍵的閒置時間,使用Object idletime <key> 命令能夠查看鍵key的閒置時間。
若是服務器在讀取一個鍵時發現該鍵已通過期,那麼服務器會先刪除這個過時鍵,而後才執行餘下的其餘操做。
服務器每次修改一個鍵以後,都會對髒( dirty ) 鍵計數器的值增1 ,這個計數器會觸發服務器的持久化操做。
若是服務器開啓了數據庫通知功能,那麼在對鍵進行修改以後,服務器將按配置發送相應的數據庫通知。
redis使用惰性刪除
和按期刪除
兩種策略來刪除過時的鍵:惰性刪除策略只在碰到過時鍵時才進行刪除操做,按期刪除策略則每隔一段時間主動查找並刪除過時鍵。經過配合使用這兩種策略,服務器能夠很好地在合理使用CPU時間和避免浪費內存空間之間取得平衡。
可讓客戶端經過訂閱通知的方式,來獲知數據庫中鍵的變化,以及數據庫中命令的執行狀況。通知有兩種類型:
鍵空間通知(關注某個鍵執行了什麼命令)
subscribe __keyspace@0__:aaa //客戶端訂閱鍵空間通知,0指0號數據庫
鍵事件通知(關注某個命令被什麼鍵執行了)
subscirbe __keyevent@0__:set //客戶端訂閱鍵事件通知
服務器配置的notify-keyspace-events選項決定了服務器所發送通知的類型:
想讓服務器發送全部類型的鍵空間通知和鍵事件通知,能夠將選項的值設置爲AKE。
想讓服務器發送全部類型的鍵空間通知,能夠將選項的值設置爲AK。
想讓服務器發送全部類型的鍵事件通知,能夠將選項的值設置爲AE。
想讓服務器只發送和字符串鍵有關的鍵空間通知,能夠將選項的值設置爲K$。
想讓服務器只發送和列表鍵有關的鍵事件通知,能夠將選項的值設置爲El。
redis默認配置不會回收key,當redis內存使用率超過可用內存的95%時,會觸發內存交換(嚴重影響性能);經過設置maxmemory爲系統可用內存的45%或95%和設置maxmemory-policy能夠比較準確的限制redis最大內存使用率,在絕大多數場景下可確保redis不會進行內存交換。
如果啓用了rdb持久化功能,應該設置maxmemory值爲系統可以使用內存的45%。由於rdb須要一倍的內存來複制整個數據集,也就是說若是當前已使用45%,在持久化期間會變成95%(45%+45%+5%),其中5%是預留給其餘的開銷。 若是沒開啓rdb持久化功能,maxmemory最高能設置爲系統可用內存的95%。
當used_memory達到最大閾值maxmemory時,會觸發數據淘汰,即回收key。
info evicted_keys能夠看到淘汰的key數量。淘汰策略取決於maxmemory-policy:
volatile-lru: //使用LRU算法從已設置過時時間的數據集合中淘汰數據 volatile-ttl: //從已設置過時時間的數據集合中挑選即將過時的數據淘汰 volatile-random: //從已設置過時時間的數據集合中隨機挑選數據淘汰 allkeys-lru: //使用LRU算法從全部數據集合中淘汰數據 allkeys-random: //從數據集合中任意選擇數據淘汰 noenviction: //禁止淘汰數據