在個人Redis數據庫中,我有許多prefix:<numeric_id>
哈希。 redis
有時我想原子地清除它們。 如何在不使用某些分佈式鎖定機制的狀況下執行此操做? 數據庫
從redis 2.6.0開始,您能夠運行自動執行的lua腳本。 我歷來沒有寫過,可是我認爲它看起來像這樣 bash
EVAL "return redis.call('del', unpack(redis.call('keys', ARGV[1])))" 0 prefix:[YOUR_PREFIX e.g delete_me_*]
請參閱EVAL文檔 。 服務器
這是在Lua中實現的通配符刪除的徹底可行且原子的版本。 因爲來回網絡少了不少,它的運行速度比xargs版本要快得多,而且它是徹底原子的,阻止其餘任何針對redis的請求,直到完成爲止。 若是要在Redis 2.6.0或更高版本上自動刪除密鑰,絕對能夠採用如下方法: 網絡
redis-cli -n [some_db] -h [some_host_name] EVAL "return redis.call('DEL', unpack(redis.call('KEYS', ARGV[1] .. '*')))" 0 prefix:
這是@mcdizzle對這個問題的回答中的一個可行版本。 這個想法的功勞100%歸功於他。 分佈式
編輯:根據下面的Kikito的評論,若是要刪除的密鑰多於Redis服務器中的可用內存,則會遇到「要分解的元素太多」錯誤 。 在這種狀況下,請執行如下操做: 佈局
for _,k in ipairs(redis.call('keys', ARGV[1])) do redis.call('del', k) end
正如Kikito建議的那樣。 性能
窮人的原子質量刪除? 網站
也許您能夠將它們所有設置爲在同一秒內過時(例如在將來幾分鐘內),而後等到那個時候看到它們同時都在「自我毀滅」。 lua
但我不肯定這將是多麼原子。
對於那些在解析其餘答案時遇到困難的人:
eval "for _,k in ipairs(redis.call('keys','key:*:pattern')) do redis.call('del',k) end" 0
將key:*:pattern
替換爲您本身的模式,而後將其輸入redis-cli
,您就能夠開始了。
來自如下網站的信用口岸: http ://redis.io/commands/del
免責聲明:如下解決方案不提供原子性。
從v2.8開始,您確實要使用SCAN命令而不是KEYS [1]。 如下Bash腳本演示了按模式刪除密鑰:
#!/bin/bash if [ $# -ne 3 ] then echo "Delete keys from Redis matching a pattern using SCAN & DEL" echo "Usage: $0 <host> <port> <pattern>" exit 1 fi cursor=-1 keys="" while [ $cursor -ne 0 ]; do if [ $cursor -eq -1 ] then cursor=0 fi reply=`redis-cli -h $1 -p $2 SCAN $cursor MATCH $3` cursor=`expr "$reply" : '\([0-9]*[0-9 ]\)'` keys=${reply##[0-9]*[0-9 ]} redis-cli -h $1 -p $2 DEL $keys done
[1] KEYS是一種危險的命令,有可能致使DoS。 如下是其文檔頁面的引文:
警告:將KEYS視爲命令,僅應格外當心地用於生產環境。 在大型數據庫上執行時,可能會破壞性能。 此命令用於調試和特殊操做,例如更改鍵空間佈局。 不要在常規應用程序代碼中使用KEYS。 若是您正在尋找一種在鍵空間的子集中查找鍵的方法,請考慮使用集合。
更新:具備相同基本效果的一根襯板-
$ redis-cli --scan --pattern "*:foo:bar:*" | xargs -L 100 redis-cli DEL