溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Redis 4.0鮮為人知的功能將加速您的應(yīng)用程序

發(fā)布時(shí)間:2020-08-06 12:32:58 來(lái)源:網(wǎng)絡(luò) 閱讀:314 作者:中間件小哥 欄目:云計(jì)算

來(lái)源:Redislabs

作者:Kyle Davis

翻譯:Kevin?(公眾號(hào):中間件小哥)

Redis 4.0給Redis生態(tài)帶來(lái)了一個(gè)驚人的功能:Modules(模塊)。Modules是Redis的一大轉(zhuǎn)變,它是Redis內(nèi)部自定義數(shù)據(jù)類型和全速計(jì)算的開(kāi)放環(huán)境。但是,盡管對(duì)該版本的大多數(shù)關(guān)注都集中在Modules上,但新版本還引入了一個(gè)非常重要的命令,它就是游戲規(guī)則的改變者:UNLINK。

您可以使用redis-cli連接redis-server執(zhí)行info命令,去查看當(dāng)前redis版本中是否可以使用UNLINK命令。info響應(yīng)將告訴您有關(guān)服務(wù)器的所有信息。在第一部分(#Server)中,返回結(jié)果有一行值為redis_version。如果該值大于4.0,則可以使用UNLINK命令。并非所有Redis提供商都保持最新版本,因此最好在更改代碼之前檢查redis版本。

讓我們回顧一下Redis的關(guān)鍵架構(gòu)功能之一:“單線程”。Redis在大多數(shù)情況下是一個(gè)單線程應(yīng)用程序。它一次只做一件事,這樣可以把這些事做的更快。多線程有點(diǎn)復(fù)雜,并且引入了鎖和其他可能降低應(yīng)用程序速度的問(wèn)題。盡管Redis(最高4.0版)通過(guò)多線程方式執(zhí)行了少量操作,但它通常在啟動(dòng)另一個(gè)命令之前先要完成一個(gè)命令。

相比于快速讀寫,您可能會(huì)覺(jué)得使用DEL命令去刪除一個(gè)鍵值不需要考慮太多,但是在很多情況下,刪除數(shù)據(jù)同樣很重要。與Redis中的大多數(shù)命令一樣,DEL命令在單個(gè)線程中運(yùn)行,如果您獲取一個(gè)幾千字節(jié)的鍵值,花費(fèi)不到一毫秒的時(shí)間,這是您所感知不到的。然而,當(dāng)您獲取的鍵值大小是兆字節(jié)、100兆字節(jié)或者500兆字節(jié)會(huì)發(fā)生什么呢?哈希、排序、列表等數(shù)據(jù)結(jié)構(gòu)會(huì)隨著時(shí)間的推移而添加更多的數(shù)據(jù)進(jìn)去,這樣會(huì)生成一個(gè)數(shù)GB大小的數(shù)據(jù)集。然后用DEL命令去刪除大Key時(shí)會(huì)發(fā)生什么呢?由于Redis是單線程操作的,處理這種請(qǐng)求時(shí)整個(gè)服務(wù)都處于等待中,需要等待該命令執(zhí)行完成才能執(zhí)行其它操作。同時(shí),我們考慮更復(fù)雜的一種場(chǎng)景,這些鍵中保存的數(shù)據(jù)可能已經(jīng)包含數(shù)以千萬(wàn)個(gè)微小請(qǐng)求,因此應(yīng)用程序或操作員可能無(wú)法真正了解刪除這些數(shù)據(jù)需要花費(fèi)多長(zhǎng)時(shí)間。

理智會(huì)告訴我們不要在擁有100萬(wàn)元素的排序集上運(yùn)行如下這樣的命令:

> ZRANGE some-zset 0 -1

但是,在上面的some-zset集合中執(zhí)行DEL命令將花費(fèi)和上面一樣的時(shí)間-中間沒(méi)有傳輸開(kāi)銷,但是它會(huì)一直去分配內(nèi)存,而且您會(huì)一直卡死在CPU繁忙中。在使用UNLINK之前,您可能會(huì)結(jié)合SCAN命令采用非原子性的方法進(jìn)行一些少量刪除,去避免這種持續(xù)分配內(nèi)存的噩夢(mèng)。上面無(wú)論使用哪種方式,都是讓人無(wú)法接受的。

您可能已經(jīng)猜到了,就是使用UNLINK命令來(lái)替換DEL!從語(yǔ)法上講,UNLINK與DEL相同,但UNLINK提供了更為理想的解決方案。首先,它將鍵值從整個(gè)鍵值空間中刪除。然后,在另一個(gè)線程中,它開(kāi)始回收內(nèi)存。從多線程的角度來(lái)看,這是一種安全的操作,因?yàn)樗ㄔ谥骶€程中)從鍵空間中刪除了該項(xiàng),從而使Redis其它命令無(wú)法訪問(wèn)。

如果你有一個(gè)快速增長(zhǎng)的鍵值-不管鍵值的大小如何,UNLINK都是O(1)操作(每個(gè)鍵;在主線程中)。使用DEL刪除一個(gè)大值可能需要幾百毫秒或更長(zhǎng)時(shí)間,而UNLINK將在不到一毫秒的時(shí)間內(nèi)完成(包括網(wǎng)絡(luò)往返)。當(dāng)然,您的服務(wù)器仍將需要花一些時(shí)間在另一個(gè)線程中重新分配該值的內(nèi)存(其中的工作是O(N),其中N是已刪除值的分配數(shù)),但是主線程的性能不會(huì)被另一個(gè)線程中正在進(jìn)行的操作嚴(yán)重影響到。

因此,您是否應(yīng)該用UNLINK命令替換代碼中的所有DEL命令?當(dāng)然,在少數(shù)情況下,DEL正是您所需要的。這里我可以想到兩點(diǎn):

1、?? 在MULTI / EXEC或pipeline中,在添加和刪除大值時(shí)DEL命令是一種理想選擇。在這種情況下,UNLINK不會(huì)立即釋放空間,并且在處理繁忙的情況下(如果內(nèi)存已滿),您可能會(huì)遇到麻煩。

2、?? 在更緊急的情況下,在無(wú)快速響應(yīng)驅(qū)逐數(shù)據(jù)下您可以寫入數(shù)據(jù)。

在沒(méi)有極端內(nèi)存限制的理想環(huán)境中,很難想到不使用UNLINK的情況。UNLINK將提供更一致的行為,總體上具有更好的性能,并且代碼更改非常?。ㄈ绻梢栽诳蛻舳酥兄孛?,則無(wú)需更改)。如果UNLINK適合您的應(yīng)用程序,請(qǐng)就此將您的DEL更改為UNLINK,然后查看它的性能提高。

?

更多優(yōu)質(zhì)中間件技術(shù)資訊/原創(chuàng)/翻譯文章/資料/干貨,請(qǐng)關(guān)注“中間件小哥”公眾號(hào)!


向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI