En raison de changements dans les exigences, un projet précédent nécessitait des modifications du format de données stocké dans Redis. Pour empêcher les anciennes données d'être insérées dans de nouvelles données après la publication du nouveau package. Par conséquent, toutes les anciennes données doivent être supprimées avant la publication. Actuellement, Redis est un cluster public impliquant plusieurs entreprises. Se pose alors la question de savoir comment supprimer une grande quantité d'anciennes données (le nombre total de clés dans la bibliothèque est actuellement de 12 millions) sans affecter l'utilisation d'autres entreprises.
###Moyens courants de supprimer les données Redis par lots :
Si la clé des données à supprimer est connue , vous pouvez utiliser la commande del de redis-cli /usr/local/redis/bin/redis-cli del key ou vous pouvez également utiliser le package redis ou la bibliothèque correspondant à d'autres langages de haut niveau. Par exemple, jedis sous java et bibliothèque redis sous python
java: jdeis.del(key) python: redis.delete(key)
Si la clé des données à supprimer est inconnue, seule la clé qui satisfait un modèle spécifique est connue. Dans ce cas, vous devez utiliser la commande keys de redis pour trouver les clés qui répondent au modèle spécifique
Trouver toutes les clés qui répondent au préfixe de vidéo
/usr/local/redis/bin/redis-cli keys video_*
Vous pouvez utiliser xargs de Linux pour terminer la suppression par lots/usr/local/redis/bin/redis-cli keys video* | xargs /usr/local/redis/bin/redis-cli del 3. Si les données à supprimer sont toutes les données de la bibliothèque, vous pouvez utiliser flushdb pour effacer toute la bibliothèque/usr/local/redis/bin/redis-cli flushdb
###Explication de plusieurs méthodes
La première méthode nécessite une connaissance claire de la clé spécifique
Utilisez la commande Keys Lorsque la quantité de données dans la bibliothèque est trop importante, la commande Keys bloquera toutes les autres demandes de Redis. Sans aucun doute, cette approche n’est pas recommandée pour les clusters Redis publics. Bien entendu, les besoins spécifiques de l’entreprise doivent être pris en compte. Si cela ne fonctionne pas, vous pouvez également exécuter le script de suppression à un moment où le trafic professionnel est relativement faible.
En utilisant flushdb, les données de toute la bibliothèque seront nettoyées.
###Ma solution Le cluster redis en ligne utilise la structure matser-slave. Par conséquent, la commande key qui bloque la requête peut être exécutée sur le nœud esclave pour trouver toutes les clés correspondant au préfixe spécifique. Utilisez ensuite un script shell ou un langage de haut niveau pour supprimer les données sur le nœud maître.
# Récupérez toutes les clés dont le préfixe est vidéo, album, acteur, puis ajoutez et exportez ces clés dans le fichier /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;
Puisque le script 2 envoie les commandes del une par une, l'efficacité d'exécution est assez faible. Lors du test, environ 1,2 million de données ont été supprimées en une heure. 12 millions d’éléments doivent être supprimés en 10 heures ! ! ! Compte tenu du temps nécessaire pour envoyer chaque requête, j'ai pensé à utiliser le pipeline Redis pour implémenter la soumission par lots.
__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'
Le script amélioré 2 ne prend que 2 minutes environ pour s'exécuter en ligne ! !
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!