- redis的持久化
save和bgsave的區別,bgsave是fork了一個子線程去實現持久化,在bgsave期間,客戶端仍可以處理客戶端請求
- redis的過期策略
可以設置過期時間,但是要考慮當同一時間出現很多過期的話,會造成正常業務卡頓,redis內部每過25秒即(貪心)讀取設置了過期時間的list,如果過期佔其中超過1/4則會繼續執行去過期稀釋過期list,實際使用中最好在過期時間上加隨機數
從庫中的過期不會自動執行,是一種懶加載,根據文件刪除,或者在訪問時判斷
過期時間是對整個hash來說的而不是hash中的某個kv對
- lua腳本
redis作爲遠程字典服務,當把它看成是一個操作內存的數據庫時它滿足ACID原則,因爲本身提供了鎖(但是並不如db提供的鎖功能完善,如超時等問題)
但是當我們使用lua操作時需要注意: - 原子性
redis依賴lua,單線程只要開始執行就會將當前script執行完 - 一致性
redis沒有回滾一說,lua中先執行成功的語句不會因爲後面執行的語句的失敗而失敗 - 隔離性
- 持久性
在執行成功後纔會寫入文件
理解:redis中的事務不能完全的滿足ACID
思考?
既然redis是單線程的,爲何lua執行卡死時可以執行其他命令終止執行線程?
因爲存在鉤子設計
但是當lua中有執行寫操作,無法簡單終止
-
redis實現分佈式事務?
這裏與其說"redis實現分佈式事務"不如說redis作爲中間件幫助完成柔性事務
爲什麼選擇了redis?
是因爲單線程操作嗎?
個人理解:爲了解決應用分佈式帶來的問題,用redis作爲第三者見證人(分佈式鎖的關鍵一環)保證業務正常進行(事務的ACID特性得到滿足相對於db層面的事務處理:例如修改某賬戶的餘額,在service中查或者改在同一個事務中,是滿足原子性的,但是如果是分佈式部署的應用甚至db,就不能保證業務是正常可靠的了 而對redis作爲db而言,可以使用lua腳本保證一定的原子性(可能會出現執行中,後半部分失敗而前半部分已執行的情況);也可以使用鎖來保證一定的原子性:例如修改餘額的業務中,查時即開啓鎖,在修改完成後釋放鎖
-
分佈式事務?
面臨的主要問題:網絡分區導致的消息不確定性
業務上的原子操作無法 在數據庫層面簡單的使用事務保證原子,不同的節點應用,操作不同的數據庫兩個維度都極易產生這種需求
例如:與tcp/ip協議的三次握手情形類似
上一個應用成功,下一個應用失敗,如何保證上一個應用回滾操作
上一個應用成功,發生網絡分區,下一個應用無法判斷上一個的執行結果
上一個應用成功,下一個應用成功,發生網絡分區,上一個應用無法判斷下一個執行結果
參考mysql
柔性事務,cap中取a(高可用[應用集羣,多個copy副本])p(部署在不同的物理機上[copy副本間的同步,不同節點間的消息傳遞])而強調最終一致性
DB層面常見的實現思路有:兩階段,補償(TCC),異步確保,最大努力 來保證消息正確傳達
在消息正確傳達的基礎上,我們使用數據庫鎖來完成大事務中的部分事務,獲取到鎖(行鎖/表鎖)即可進行操作, 獲取到鎖的前提下,可以再次加鎖即可重入鎖