redis是如何持久化的?怎麼用redis來處理分佈式事務的?lua腳本怎麼用?

  • 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),異步確保,最大努力 來保證消息正確傳達
在消息正確傳達的基礎上,我們使用數據庫鎖來完成大事務中的部分事務,獲取到鎖(行鎖/表鎖)即可進行操作, 獲取到鎖的前提下,可以再次加鎖即可重入鎖

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章