問題
del 和 unlink 有啥區別啊?為什么String類型刪除不會做異步刪除?
彬彬回答
DEL 和 UNLINK 都是同步的釋放 key 對象,區別是怎么釋放后面的 value 對象
DEL 每次都是同步釋放 value 部分,如果 value 很大,例如一個 list 里很多元素,這會阻塞 Redis 工作線程。
為了規避這個問題,4.0 里引出了 UNLINK 命令,可以異步釋放 value 對象,放到一個子線程中。
這邊需要引出一個釋放的閾值,見后面解釋。
目前默認的閾值是 64,例如只有一個 list 里面含有超過 64 個元素,才會異步釋放,否則也是會同步釋放不同的數據結構的計算閾值的方式不一樣,不過大致遵循一個原則:就是要釋放多少塊內存即在小對象上使用 UNLINK 效果等同于 DEL,也是同步釋放,區別就是要多走幾個函數調用,例如判斷 list 里需要判斷列表的長度等
大 value 對象的釋放是異步的,放在一個子線程上,小對象之所以不異步釋放,是因為異步釋放,主線程和子線程之間需要做一些同步操作(這是有代價的),然后小對象釋放,本身也很快就也不值得進行異步釋放,內存釋放也更及時。
即可能異步釋放,實際上會比同步釋放更慢,所以作者設置了個 64 的經驗值
所以如果是一個小對象,DEL 和 UNLINK 其實一樣;如果是一個大對象,UNLINK 會更加好。
所以大部分情況下都可以用 UNLINK 代替 DEL,而 Redis 其實也有個配置項,可以控制將 DEL 默認轉換為 UNLINK(實現上都是同一個函數,只是入口 async 參數不同)不過我們需要知道異步釋放的好處(不阻塞主線程)和它的壞處(需要進行一些線程同步相關的操作,內存釋放不及時)。
至于說 string 為啥不異步釋放,主要是作者認為它是一整塊內存空間,計算閾值的時候 string 的結果固定是 1,那么就 <= 64,就是同步釋放。
在補充一點,前面舉例是說的 list,底層是用的 quicklist,嚴格來說統計的是 quicklistNode 的節點數量,就不是列表元素數量。
像 zset 那些如果用的 ziplist/listpack 編碼的話,這種計算出來的閾值是 1,就也不是元素數量。如果是跳表編碼的話就是統計的元素數量。
然后至于選擇的話,大部分情況可以無腦用 UNLINK,不過需要知道壞處。
例如對于每一次的 async delete,主線程給子線程提交任務時需要加鎖解鎖,bio 子線程消費任務的時候也要加鎖解鎖,要做一些線程同步,還有線程上下文切換,這些都是可能會有的潛在的問題,如果小元素都異步釋放的話,的確代價可能會大,多線程做事情的確是會有這些麻煩。
可以多做壓測來驗證環境里到底哪個好,不過大部分情況這些我們不用關系,只要寫代碼的時候有意識的注意大 key 的釋放就好。
審核編輯:劉清
-
Del
+關注
關注
0文章
3瀏覽量
6571 -
Redis
+關注
關注
0文章
381瀏覽量
11230
原文標題:Redis 刪除 key用 del 和 unlink 有啥區別?
文章出處:【微信號:小林coding,微信公眾號:小林coding】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
Linux系統中unlink命令的使用
請問如何用f_unlink刪除一個文件夾?
為什么YouTask自己刪除自己不會顯示多次?
如何刪除網卡驅動(徹底刪除)
重要機密文檔該刪除還是粉碎?

linux如何復原已經刪除的文件
拼多多被曝遠程刪除用戶照片
刪除網絡失敗的問題處理

評論