MoreKey案例
大批量往redis里面插入2000W測試數(shù)據(jù)key?
Linux?Bash下面執(zhí)行,插入100W
# 生成100W條redis批量設置kv的語句(key=kn,value=vn)寫入到/tmp目錄下的redisTest.txt文件中
for((i=1;i<=100*10000;i++)); do echo "set k$i v$i" >> /tmp/redisTest.txt ;done;
通過redis提供的管道--pipe命令插入100W大批量數(shù)據(jù)
結(jié)合自己機器的地址:
cat /tmp/redisTest.txt | /opt/redis-7.0.0/src/redis-cli -h 127.0.0.1 -p 6379 -a 111111 --pipe
可通過數(shù)據(jù)插入測試機器的性能,本次測試100w數(shù)據(jù)插入redis花費5.8秒左右
某快遞巨頭真實生產(chǎn)案例新聞
新聞
keys?*?你試試100W花費多少秒遍歷查詢?
key * 這個指令有致命的弊端,在實際環(huán)境中最好不要使用?
生產(chǎn)上限制keys?*/flushdb/flushall等危險命令以防止誤刪誤用?
通過配置設置禁用這些命令,redis.conf在SECURITY這一項中
不用keys?*避免卡頓,那該用什么?
scan命令登場
英文官網(wǎng)
中文官網(wǎng)
一句話,類似mysql?limit,但不完全相同
Scan?命令用于迭代數(shù)據(jù)庫中的數(shù)據(jù)庫鍵
語法
特點
SCAN 命令是一個基于游標的迭代器,每次被調(diào)用之后, 都會向用戶返回一個新的游標,?用戶在下次迭代時需要使用這個新游標作為 SCAN 命令的游標參數(shù), 以此來延續(xù)之前的迭代過程。
SCAN 返回一個包含兩個元素的數(shù)組,?
第一個元素是用于進行下一次迭代的新游標,?
第二個元素則是一個數(shù)組, 這個數(shù)組中包含了所有被迭代的元素。如果新游標返回零表示迭代已結(jié)束。
SCAN的遍歷順序
非常特別,它不是從第一維數(shù)組的第零位一直遍歷到末尾,而是采用了高位進位加法來遍歷。之所以使用這樣特殊的方式進行遍歷,是考慮到字典的擴容和縮容時避免槽位的遍歷重復和遺漏。
使用
BigKey案例?
多大算Big?
參考《阿里云Redis開發(fā)規(guī)范》
string和二級結(jié)構(gòu)
string是value,最大512MB但是≥10KB就是bigkey
list、hash、set和zset,個數(shù)超過5000就是bigkey(疑問???)
哪些危害
- 內(nèi)存不均,集群遷移困難
- 超時刪除,大key刪除作梗
- 網(wǎng)絡流量阻塞
如何產(chǎn)生(案例)
社交類:某明星粉絲列表,典型案例粉絲逐步遞增
匯總統(tǒng)計:某個報表,月日年經(jīng)年累月的積累
如何發(fā)現(xiàn)
redis-cli?--bigkeys
好處,見最下面總結(jié)
給出每種數(shù)據(jù)結(jié)構(gòu)Top 1 bigkey,同時給出每種數(shù)據(jù)類型的鍵值個數(shù)+平均大小
不足
想查詢大于10kb的所有key,--bigkeys參數(shù)就無能為力了,需要用到memory usage來計算每個鍵值的字節(jié)數(shù)
redis-cli --bigkeys -a 111111?
redis-cli -h 127.0.0.1 -p 6379 -a 111111 --bigkeys
|
每隔 100 條 scan 指令就會休眠 0.1s,ops 就不會劇烈抬升,但是掃描的時間會變長
redis-cli -h 127.0.0.1 -p 7001 –-bigkeys -i 0.1
|
MEMORY?USAGE?鍵?
計算每個鍵值的字節(jié)數(shù)
官網(wǎng)?
如何刪除
參考《阿里云Redis開發(fā)規(guī)范》
官網(wǎng)?
普通命令
String
一般用del,如果過于龐大unlink
hash
使用hscan每次獲取少量field-value,再使用hdel刪除每個field
命令
阿里手冊
list?
使用ltrim漸進式逐步刪除,直到全部刪除完成
命令
阿里手冊
set
使用sscan每次獲取部分元素,再使用srem命令刪除每個元素
命令
?
阿里手冊
zset
使用zscan每次獲取部分元素,再使用ZREMRANGEBYRANK命令刪除每個元素
命令
阿里手冊
BigKey生產(chǎn)調(diào)優(yōu)?
redis.conf配置文件LAZY?FREEING相關(guān)說明
阻塞和非阻塞刪除命令
優(yōu)化配置?
惰性釋放
都說 redis 是單線程的,其實并不是說 redis 只有一個線程,單線程指的是 所有的執(zhí)行命令在一個線程中進行,這個線程也就是主線程,不過它還存在其他后臺線程,比如關(guān)閉文件后臺線程,AOF 日志同步寫回后臺線程,惰性刪除執(zhí)行內(nèi)存釋放后臺線程等。
因為執(zhí)行命令只在主線程中進行,這就要求單個命令的執(zhí)行時間不能太長,否則會影響后續(xù)執(zhí)行命令的響應時效性。在發(fā)生數(shù)據(jù)刪除的時候,當然也要避免對主線程長時間的阻塞,下面就來討論下如何避免數(shù)據(jù)刪除給主線程造成的阻塞影響。
數(shù)據(jù)刪除場景
涉及到數(shù)據(jù)刪除的場景有很多,盤點有如下場景:
??? 場景一:客戶端執(zhí)行的顯示刪除/清除命令,比如 del,flushdb 等;
??? 場景二:某些指令帶有的隱式刪除命令,比如 move , rename 等;
??? 場景三:到達過期時間的數(shù)據(jù)需要刪除;
??? 場景四:使用內(nèi)存達到 maxmemory 后被選出來要淘汰的數(shù)據(jù)需要刪除;
??? 場景五:在主從同步全量同步階段,從庫收到主庫的 RDB 文件后要先刪除現(xiàn)有的數(shù)據(jù)再加載 RDB 文件;
而這些刪除場景其實都存在阻塞主線程的風險:
big-key 帶來的阻塞風險:在刪除單個鍵值對的場景下,如果這個鍵值對小一般沒什么問題,但是如果要刪除的是一個 big-key,阻塞時間可能比較長,這對于響應時效性要求高的場景是不可以接受的;
同時刪除多個 key 帶來的阻塞風險:即使沒有 big-key 的存在,如果同一時間要刪除的是多個鍵,阻塞時間也不可忽略。
要怎么避免阻塞主線程?
首先,在使用上肯定要避免 big-key 的存在,它帶來的影響不僅僅是在數(shù)據(jù)刪除時存在阻塞風險, 在 AOF 文件的重寫,RDB 文件的生成中都存在阻塞風險。
其次,對于同時刪除多個 key 的需求,在主動刪除的場景下,我們其實是有辦法的 -- 分批刪除,比如對于一個大的集合,我們可以通過 scan 以循環(huán)的方式每次掃描 100 個鍵然后刪除,對于多個 key 的刪除,就直接按 key 分批處理就行了,雖然是麻煩了點,卻是可以保證不對主線程造成影響;然而分批刪除卻沒法應用于被動刪除的場景。
為了解決以上問題,在 redis 4.0 以后,redis 新增了異步刪除的功能 : lazy free,也叫 惰性刪除,它可以 將 “數(shù)據(jù)刪除” 放到后臺線程中去執(zhí)行,進而避免對主線程的阻塞。
lazy free
概念
redis 是用 c 語言實現(xiàn)的,而我們知道 c 語言是沒有垃圾回收的,也就說對于程序申請的內(nèi)存是需要程序來釋放的,因此,在 redis 中刪除數(shù)據(jù)包含兩個步驟:
??? 步驟一:將待刪除數(shù)據(jù)對從字典表中刪除;
??? 步驟二:釋放待刪除數(shù)據(jù)所占用的內(nèi)存空間。
如果這兩個步驟同步執(zhí)行,就叫 同步刪除;而如果只執(zhí)行步驟一,將來通過后臺線程來執(zhí)行步驟二,就叫 異步刪除。而惰性刪除 里的惰性其實指的就是 刪除時只執(zhí)行步驟一,而將步驟二 "延遲" 到后臺線程執(zhí)行。
配置
對應到之前盤點的刪除場景,redis 提供了對應的配置項來控制對應場景下是否啟用惰性刪除:
??? lazyfree-lazy-user-del / lazyfree_lazy_user_flush (6.0 新增): 對應場景一顯示刪除/清除命令場景;
??? lazyfree-lazy-server-del:對應場景二會隱式進行刪除操作的命令執(zhí)行場景;
??? lazyfree-lazy-expire:對應場景三過期數(shù)據(jù)的刪除場景;
??? lazyfree-lazy-eviction:對應場景四緩存淘汰時的數(shù)據(jù)刪除場景。
??? replica-lazy-flush:對應場景五從節(jié)點完成全量同步后,刪除原有舊數(shù)據(jù)的場景。
但你要知道的是,即使開啟了惰性刪除,并不代表著就一定會執(zhí)行異步刪除,redis 還會先評估刪除開銷,如果開銷較小,會直接做同步刪除。
源碼剖析(版本 6.2.6)
刪除數(shù)據(jù)包含的兩個步驟在源碼中合在一個函數(shù)里:?dictGenericDelete() 函數(shù),通過參數(shù)?nofree 來控制是否執(zhí)行步驟二:
刪除邏輯比較簡單:首先根據(jù) key 值定位到哈希桶,哈系桶存儲的是一個鏈表,所以還要沿著這個鏈表逐個比對 key 值;找到 key 以后,首先執(zhí)行步驟一,將 key 從鏈表中刪除,然后根據(jù)參數(shù) nofree 決定是否要執(zhí)行步驟二,如果 nofree = 0,則執(zhí)行步驟二,如果 nofree= 1,則不執(zhí)行。
在該函數(shù)的基礎(chǔ)上,redis 又提供了兩個封裝函數(shù)?dictDelete?和?dictUnlink:
兩個函數(shù)都調(diào)用 dictGenericDelete() 執(zhí)行刪除,區(qū)別就是 nofree 的值不同,以后刪除 key 的時候只會調(diào)用這兩個函數(shù)。
場景一:客戶端執(zhí)行的顯示刪除/清除命令?
DEL / UNLINK 命令
兩個命令都是通過調(diào)用 delGenericCommand() 函數(shù)來執(zhí)行刪除的,是否執(zhí)行惰性刪除取決于函數(shù)的 lazy 參數(shù):UNLINK 命令傳遞固定值 1;而 DEL 命令則是傳遞的配置項 lazyfree_lazy_user_del (6.0 新增)。
代碼很簡單:
如果 lazy = 1,則調(diào)用 dbAsyncDelete() 執(zhí)行惰性刪除, 否則調(diào)用 dbSyncDelete() 執(zhí)行同步刪除,繼續(xù)看下 dbAsyncDelete() 是怎么執(zhí)行惰性刪除的:
惰性刪除包含三步操作:
??? 調(diào)用 dictDelete() 從過期表中刪除數(shù)據(jù),從過期表中刪除數(shù)據(jù)只會減小引用計數(shù),不會真正刪除數(shù)據(jù);
??? 調(diào)用 dictUnlink() 從全局表中刪除數(shù)據(jù),該函數(shù)只執(zhí)行步驟一,不執(zhí)行步驟二,即不會釋放待刪除數(shù)據(jù)的占用內(nèi)存;
??? 調(diào)用 lazyfreeGetFreeEffort() 評估釋放內(nèi)存開銷,如果開銷超過門限值 LAZYFREE_THRESHOLD(默認 64),則通過 bioCreateBackgroundJob() 創(chuàng)建一個新的刪除任務,由后臺線程來執(zhí)行內(nèi)存釋放;如果開銷較小,則直接調(diào)用 dictFreeUnlinkedEntry() 函數(shù)執(zhí)行內(nèi)存釋放。
可以看到,即使開啟了惰性刪除,在實際執(zhí)行過程中,redis 也會先評估刪除數(shù)據(jù)的開銷,然后再決定是執(zhí)行異步刪除還是同步刪除。
我們繼續(xù)看下 lazyfreeGetFreeEffort() 函數(shù)是怎么評估刪除開銷的:
可以看到,當鍵值對類型屬于List、Hash、Set 和 Sorted Set,并且沒有使用緊湊型內(nèi)存結(jié)構(gòu)來保存的時候,這個鍵值對的刪除開銷就等于集合中的元素個數(shù),不屬于以上情況的刪除開銷就等于1。也就是說,即使開啟了惰性刪除,針對 String(不管內(nèi)存占用多大)、List(少量元素)、Set(int 編碼存儲)、Hash/ZSet(ziplist 編碼存儲)這些情況下的 key,在對刪除數(shù)據(jù)做開銷評估時因為小于門限值,依舊會在主線程中進行同步刪除。
此外,你可能注意到,? delGenericCommand() 在執(zhí)行刪除前還調(diào)用了函數(shù) expireIfNeeded(),從名字來看它是用來判斷 key 是否已經(jīng)過期的,此時你是否有疑問,為什么這個 key 都要被刪除了,還要判斷它是否已經(jīng)過期呢?不是直接刪除就好了嗎?
我們進入這個函數(shù)看看:
函數(shù)很簡短:
- 先判斷是否過期,如果沒有過期,直接返回 0 表示沒有過期;
- 如果已經(jīng)過期,繼續(xù)判斷是否是主庫,如果不是主庫,直接返回已過期;
- 如果已經(jīng)過期且是主庫,繼續(xù)調(diào)用 deleteExpiredKeyAndPropagate():
deleteExpiredKeyAndPropagate() 先根據(jù)配置項 lazyfree_lazy_expire 來決定是否執(zhí)行惰性刪除,這個其實屬于場景三過期鍵刪除的一種方式,這個待會我們再分析?,F(xiàn)在我們只需要知道,在執(zhí)行刪除命令的時候,也會先判斷這個 key 是否已經(jīng)過期,如果已經(jīng)過期,則會按照過期鍵刪除的策略對 key 進行刪除;然后它還會繼續(xù)調(diào)用 propagateExpire() 函數(shù)將刪除動作傳遞到 AOF文件 或 從節(jié)點。
所以,從這個過程我們又了解到,在執(zhí)行刪除命令的時候,redis 會優(yōu)先判斷 key 是否已經(jīng)過期,如果 已經(jīng)過期且是主庫,則按照過期鍵刪除策略對 key 進行刪除,然后還要將同步刪除命令到 AOF文件 和 從節(jié)點。而對于從庫上的刪除操作,即使已經(jīng)過期,也不會做過期處理。
為什么要區(qū)分主從庫
因為 redis 主從模式采用的是讀寫分離方式,也就是說 從庫只進行讀操作,所有的數(shù)據(jù)修改都應該交由主庫發(fā)送同步命令。因此,如果刪除命令發(fā)生在主庫,要先檢測 key 是否過期,如果過期要將過期的 key 同步一個刪除命令到 AOF 文件和從庫,同步到 AOF 文件是為了以后做恢復時保證數(shù)據(jù)一致性,而同步到從節(jié)點當然是為了保證主從一致性;而如果發(fā)生在從庫,可以認為該命令是從主庫同步過來的,只要將數(shù)據(jù)刪除即可。
最后,我們也順便看下同步刪除 dbSyncDelete() 函數(shù),邏輯很簡單,直接看下源碼注釋就可以了。
到此為止,整個刪除命令的執(zhí)行過程全部結(jié)束了,這個過程講的特別詳細,其實它包含了后面其他場景都會涉及到的一些共有的邏輯,后續(xù)我們看其他的刪除場景的時候會看到有很多函數(shù)都在這里出現(xiàn)過,所以理清這一個過程后,看其他的就會比較簡單了。
這里畫了一個流程圖描述整個刪除過程,可以參考下:
?
flushdb [sync/async] 命令
這個命令本身可以通過參數(shù) sync/async 來指定是否執(zhí)行惰性刪除;如果沒有攜帶參數(shù)執(zhí)行,它才會根據(jù)配置項 lazyfree_lazy_user_flush 來決定刪除策略。過程很簡單:
1、 根據(jù)命令參數(shù)/配置項 獲取惰性刪除標識;
2、根據(jù)刪除標識決定是否采用異步刪除的方式清空數(shù)據(jù)庫。
場景二:某些指令帶有的隱式刪除命令?
以 move 命令為例,看下執(zhí)行過程:
??? 在 源庫中查詢 key 是否存在,如果不存在直接返回;
??? 在目的庫中查詢 key 是否存在,如果存在直接返回;如果不存在則添加到目的庫;
??? 從源庫中刪除。根據(jù)配置項 lazyfree_lazy_server_del 決定執(zhí)行 惰性刪除還是同步刪除。
在以上第一步和第二步調(diào)用 lookupKeyWrite() 函數(shù)查詢 key 的過程中,其實也會調(diào)用到 expireIfNeeded() 函數(shù)來判斷是否過期并做相應的處理,忘記了的也可以回頭去看看處理過程。
場景三:刪除過期數(shù)據(jù)?
針對過期數(shù)據(jù)的刪除,redis 提供兩種刪除策略:
??? 請求時刪除:執(zhí)行命令時,先檢查 key 是否過期,若過期則刪除,反之繼續(xù)操作;
??? 定期刪除:每隔一段時間,檢查并刪除已過期的 key。
分別看下兩種策略下是如何執(zhí)行刪除的:
請求時刪除
我們在之前的刪除命令中已經(jīng)看到過請求時刪除的調(diào)用時機,你還記得嗎?其實就是 expireIfNeeded() 函數(shù)的調(diào)用時機,在這個函數(shù)里面就是根據(jù)配置項 lazyfree-lazy-expire 來決定是否執(zhí)行惰性刪除的 。
這里我們再以查詢一個 key 為例看下:在對某個 key 執(zhí)行查詢時,會調(diào)用到 lookupKeyReadWithFlags() 函數(shù),它首先就會調(diào)用 expireIfNeeded() 函數(shù)來查詢這個 key 是否已經(jīng)過期,有區(qū)別是,這里接收了該函數(shù)的返回值,通過返回值判斷 key 是否已經(jīng)過期:
對于主庫, expireIfNeeded() 函數(shù)會執(zhí)行刪除操作,然后同步刪除命令到 AOF 文件和從庫,最后返回 key 已過期, lookupKeyReadWithFlags() 判斷 key 已過期,返回客戶端 key 不存在;
對于從庫,expireIfNeeded() 只檢測到 key 已過期就直接返回, 然后 lookupKeyReadWithFlags() 判斷 key 已過期,返回客戶端 key 不存在; 也就是說,對于從庫而言,即使這個過期鍵還存在于數(shù)據(jù)庫(它還再等待主庫同步過來的刪除命令),也會返回客戶端 key 不存在。
從這里我們看到 redis 真的是超級精細了,即使主從庫在數(shù)據(jù)同步上存在一定的延遲性,但是通過區(qū)分讀寫操作可以盡量保證在讀操作上的數(shù)據(jù)準確性。
定期刪除
定期刪除位于主循環(huán)中,在 beforeSleep() 函數(shù)中調(diào)用 activeExpireCycle() 函數(shù),這個函數(shù)的主要作用是:在一定的時間內(nèi),從過期字典中隨機的選出一定量的過期鍵,調(diào)用 activeExpireCycleTryExpire() 函數(shù)執(zhí)行刪除。
場景四:內(nèi)存淘汰數(shù)據(jù)刪除
當使用內(nèi)存達到 maxmemory 后,redis 會根據(jù)配置的內(nèi)存淘汰策略選出一定量的數(shù)據(jù)進行刪除,關(guān)于數(shù)據(jù)淘汰相關(guān)知識可以看下 Redis 緩存淘汰策略以及 LRU、LFU 算法 。
現(xiàn)在我們先想想內(nèi)存淘汰的執(zhí)行時機,其實比較容易想到,就是處理命令之前要先檢查內(nèi)存是否查過最大限制,所以我們直接去到 processCommand() 函數(shù):
可以看到,該函數(shù)會調(diào)用 performEvictions() 函數(shù)來檢測是否超過最大使用內(nèi)存,如果已經(jīng)超過最大值,就會拒絕執(zhí)行命令直接返回,繼續(xù)看看是怎么檢測的:
過程稍微有點長,分為以下步驟:
??? 首先檢查目前的內(nèi)存使用狀態(tài),如果沒有達到最大值,直接返回,如果超過最大值,調(diào)用 getMaxmemoryState() 獲取需要釋放內(nèi)存量 mem_tofree ;
??? 循環(huán)地刪除數(shù)據(jù),直到釋放內(nèi)存達到需要釋放的內(nèi)存量或者時間執(zhí)行時間超過限制。
循環(huán)過程:
??? 根據(jù)不同的內(nèi)存淘汰策略選擇待刪除的 key;
??? 在刪除前調(diào)用 zmalloc_used_memory() 函數(shù)獲取當前的使用內(nèi)存值;
??? 調(diào)用 propagateExpire() 函數(shù)檢查該 key 是否過期,如果過期要同步刪除命令到 AOF 文件 和 從庫;
??? 刪除數(shù)據(jù),根據(jù)配置項 lazyfree_lazy_eviction 決定是否執(zhí)行惰性刪除;
??? 再次調(diào)用 zmalloc_used_memory() 函數(shù)獲取當前使用內(nèi)存,減去刪除前記錄的內(nèi)存值得到已經(jīng)釋放的內(nèi)存大小;
??? 累計已經(jīng)釋放的內(nèi)存量 mem_freed,累計刪除 key 值數(shù)量 keys_freed;
??? 每刪除16個 key 后,做提前退出檢查:如果開啟了惰性刪除,再次調(diào)用 getMaxmemoryState() 校驗當前使用內(nèi)存是否已經(jīng)沒有超過 maxmemory,如果 已經(jīng)滿足則退出循環(huán);檢查循環(huán)執(zhí)行時間,如果執(zhí)行時間超過限制值,也提前退出,由 evictionTimeProc 后臺刪除。
整個過程有 4 個地方統(tǒng)計了當前使用內(nèi)存:
??? 第一次是為了獲取要釋放的內(nèi)存量;
??? 第二次和第三次分別位于對某個key 進行刪除的前后調(diào)用,因為如果開啟了惰性刪除,刪除數(shù)據(jù)可能是在異步線程中執(zhí)行的,因此不能直接獲取刪除的內(nèi)存大小,需要通過在刪除數(shù)據(jù)的前后都獲取當前使用內(nèi)存然后計算差值得到已經(jīng)釋放的內(nèi)存量;
??? 第四次也是在執(zhí)行刪除函數(shù)后檢測的,這里也是考慮了異步刪除可能在某個時間點刪除數(shù)據(jù)后已經(jīng)滿足了最大內(nèi)存使用值,所以可以提前退出循環(huán)。
這里也畫了一個流程圖,可以參考下:
?
場景五:主從同步清空從庫
主從同步本身是一個比較復雜的過程,我們這里只簡單了解下異步刪除的配置,不做過多介紹了。
小結(jié)
本文主要介紹了 redis 刪除數(shù)據(jù)的過程,因為 redis 單線程處理命令的特性,要求所有的執(zhí)行命令都不能耗時太久,而刪除數(shù)據(jù)也是在主線程中執(zhí)行的,因此我們要避免刪除數(shù)據(jù)對主線程造成長時間的阻塞。
我們首先盤點了所有涉及到刪除數(shù)據(jù)的場景,分析了各場景對主線程的阻塞可能性,了解到 big key 和 大量key 被動刪除的時候沒有辦法在同步刪除的條件下避免阻塞,然后通過引入 redis 4.0 提供的 lazy free 惰性刪除特性來解決問題。
在講惰性刪除機制前,我們講到 redis 刪除數(shù)據(jù)是分為兩個步驟的: 從字典表中刪除數(shù)據(jù) 和 釋放數(shù)據(jù)占用內(nèi)存。
然后介紹惰性刪除,我們了解到 lazy free 不是默認開啟的,此外,對于不同場景存在對應的配置項,我們需要分別開啟對應的配置項才能在對應的場景下開啟惰性刪除,惰性刪除可以將內(nèi)存釋放動作放到后臺線程中執(zhí)行,不會阻塞主線程。
最后,我們閱讀了每個刪除場景的源碼,通過閱讀源碼得知:即使開啟了惰性刪除,redis 也不一定就會執(zhí)行異步刪除,它會先評估內(nèi)存釋放開銷,如果開銷很小,則會直接在主線程對刪除數(shù)據(jù)執(zhí)行內(nèi)存釋放,如果開銷超過門限值,才會創(chuàng)建一個新任務由后臺線程執(zhí)行內(nèi)存釋放。這里需要特別注意的是,評估開銷中對于 string 類型的 key 比較特殊,因為它不管 value 多大,開銷都是 1,所以我們一定要避免這種類型的大值存在。
此外,我們也了解了 redis 對于過期鍵的優(yōu)雅處理,不僅區(qū)分了主從庫的差異,還會根據(jù)對 key 執(zhí)行的是寫操作還是讀操作進行分別處理。
面試題?
阿里廣告平臺,海量數(shù)據(jù)里查詢某一固定前綴的key?
小紅書,你如何生產(chǎn)上限制keys?*/flushdb/flushall等危險命令以防止誤刪誤用?
美團,MEMORY?USAGE?命令你用過嗎?
BigKey問題,多大算big?你如何發(fā)現(xiàn)?如何刪除?如何處理?
BigKey你做過調(diào)優(yōu)嗎?惰性釋放lazyfree了解過嗎?
Morekey問題,生產(chǎn)上redis數(shù)據(jù)庫有1000W記錄,你如何遍歷?key?*可以嗎?文章來源:http://www.zghlxwxcb.cn/news/detail-437991.html
。。。文章來源地址http://www.zghlxwxcb.cn/news/detail-437991.html
到了這里,關(guān)于第十三章_Redis中的BigKey的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!