由於需求的更改,之前做的一個專案需要對redis中儲存的資料格式進行修改。為防止新包發布後,舊數據會導致新資料無法插入。所以,必須在發布前刪除掉所有的老數據。目前redis是一個公用的集群,裡面涉及好幾個業務。那麼問題來了,如何刪除大量的老數據(目前庫中的key總數為1200w),而又不影響其他業務的使用。
常見批次刪除redis資料的方法:
如果待刪除資料的key是已知的,可以使用redis-cli的del指令/usr/local/redis/bin/redis-cli del key 或也可以使用其他高階語言對應的redis套件或函式庫。如java下的jedis,python下的redis庫java: jdeis.del(key) python: redis.delete(key)
/usr/local/redis/bin/redis-cli keys video_*
#幾種方法的說明
第一種方法需要明確知道特定的key
使用keys指令,當庫中資料量過大,keys指令會阻塞redis的其他所有請求。無疑,這種方式對公用redis群集是不可取的。當然,具體得考慮業務的需要。實在不行,也可以把刪除腳本放到業務訪問量比較小的時間點上執行。
使用flushdb這種方式,會對整個庫中的資料進行清理。
我的解決方法 線上redis叢集使用的是matser-slave的結構。所以可以把阻塞請求的keys指令放到slave節點上執行,找出所有符合特定前綴的key。然後使用shell腳本或高階語言在master節點上刪除資料。 #取得前綴是video,album,actor所有的key,並把這些key追加匯出到檔案/data/keys.txt中#!/bin/bashkeys=('video' 'album' 'actor'); host='localhost'; port='6378'; for key in ${keys[@]}; do cmd="/usr/local/redis/bin/redis-cli -h ${host} -p ${port} keys gal.video.${key}* >> /data/keys.txt"; echo ${cmd}; eval ${cmd}; done; # 根据前面生成的key,删除数据 #!/bin/bash host='localhost'; port='6378'; file="/data/keys.txt"; i=0; cat ${file} | while read key; do let i=i+1; cmd="/usr/local/redis/bin/redis-cli -h ${host} -p ${port} del ${key}"; echo "line:"${i}",cmd:"${cmd}; eval ${cmd}; done;
__author__ = 'litao' from redis import Redis host="127.0.0.1" port=6379 db=0 r =Redis(host,port,db) pl=r.pipeline() per_pipe_size=10000 count=0 file = open("/data/keys.txt") print "start del all keys in "+file.name while 1: lines = file.readlines(10000) if not lines: break for key in lines: key=key.strip('\n') pl.delete(key) count=count+1 if(count==per_pipe_size): count=0 pl.execute() pl.execute() file.close() print 'finish del all keys'
以上是redis要怎麼刪除資料?的詳細內容。更多資訊請關注PHP中文網其他相關文章!