首頁  >  文章  >  Java  >  redis要怎麼刪除資料?

redis要怎麼刪除資料?

藏色散人
藏色散人原創
2019-05-20 14:33:5715786瀏覽

由於需求的更改,之前做的一個專案需要對redis中儲存的資料格式進行修改。為防止新包發布後,舊數據會導致新資料無法插入。所以,必須在發布前刪除掉所有的老數據。目前redis是一個公用的集群,裡面涉及好幾個業務。那麼問題來了,如何刪除大量的老數據(目前庫中的key總數為1200w),而又不影響其他業務的使用。

redis要怎麼刪除資料?

常見批次刪除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)

如果待刪除資料的key是未知的,只知道滿足特定模式的key。在這種情況下,就需要使用redis的keys 指令找出滿足特定模式的key

找到滿足前綴是video的所有key

/usr/local/redis/bin/redis-cli keys video_*

可以使用linux的xargs來完成批次刪除/ usr/local/redis/bin/redis-cli keys video* | xargs /usr/local/redis/bin/redis-cli del 3. 如果待刪除的資料是庫中所有的數據,可以使用flushdb清除整個庫/ usr/local/redis/bin/redis-cli flushdb

#幾種方法的說明

第一種方法需要明確知道特定的key

使用keys指令,當庫中資料量過大,keys指令會阻塞redis的其他所有請求。無疑,這種方式對公用redis群集是不可取的。當然,具體得考慮業務的需要。實在不行,也可以把刪除腳本放到業務訪問量比較小的時間點上執行。

使用flushdb這種方式,會對整個庫中的資料進行清理。

我的解決方法 線上redis叢集使用的是matser-slave的結構。所以可以把阻塞請求的keys指令放到slave節點上執行,找出所有符合特定前綴的key。然後使用shell腳本或高階語言在master節點上刪除資料。

#取得前綴是video,album,actor所有的key,並把這些key追加匯出到檔案/data/keys.txt中

#!/bin/bash

keys=('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;

腳本2由於是逐條發送del指令,執行效率相當的低。測試中大概是1小時刪除120w條資料。 1200w條要刪除10小時! ! !考慮到每次發送請求的耗時,想到可以使用redis的pipeline來實現批量提交。 ###
__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'
###改進後的腳本2在線上執行時間只需要2min左右! ! ###

以上是redis要怎麼刪除資料?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn