pymong elimina archivos mongogridfs en lotes

pymong elimina el archivo mongogridfs

1. Antecedentes:

Almacenamiento del servidor de imágenes de Gridfs

GridFS es una especificación para almacenar y consultar sobre el límite de tamaño de archivo BSON (16 M) en MongoDB. A diferencia de los archivos BSON que almacenan archivos en un documento separado, GridFS divide los archivos en varios bloques, y cada bloque es un documento separado. De forma predeterminada, cada bloque de GridFS tiene 255 kB, lo que significa que, excepto el último bloque (según el tamaño de archivo restante), los documentos se almacenan en varios tamaños de bloque de 255 kB.

GridFS usa dos colecciones para almacenar datos, una colección para almacenar bloques de archivos (fs.chunks) y la otra para almacenar metadatos de archivos (fs.files). El tamaño de cada fragmento en fs.chunks es de 256 KB. El conjunto de réplicas y la arquitectura de fragmentación de Mongo proporcionan a GridFS capacidades de expansión de lectura y escritura eficientes y capacidades de alta disponibilidad. Tiene un alto nivel de almacenamiento para imágenes, videos y otros archivos grandes. Rendimiento [Los archivos pequeños, los archivos pequeños (< 16M) se almacenan en binario Bson, los archivos grandes se almacenan en gridfs].

inserte la descripción de la imagen aquí

El servidor de imágenes del proyecto de la compañía se implementa utilizando las cuadrículas del conjunto de réplicas de mongo, que almacena imágenes jpg, audio mp3, video y archivos de mapa del sitio Recientemente, el servidor de imágenes tiene lotes de imágenes ilegales que deben limpiarse de manera centralizada. archivos en lotes.

2. Problemas actuales:

Plan de funcionamiento de la red de Mongofs:

Durante el uso de gridfs del sistema de archivos mongo, mongo proporciona comandos mongofilespara la administración.

[root@bj-test-wlj-2-132 twj]# mongofiles --help
Browse and modify a GridFS filesystem.

usage: mongofiles [options] command [gridfs filename]
command:
  one of (list|search|put|get)
  list - list all files.  'gridfs filename' is an optional prefix 
         which listed filenames must begin with.
  search - search all files. 'gridfs filename' is a substring 
           which listed filenames must contain.
  put - add a file with filename 'gridfs filename'
  get - get a file with filename 'gridfs filename'
  delete - delete all files with filename 'gridfs filename'
options:
  --help                                produce help message
  -v [ --verbose ]                      be more verbose (include multiple times
                                        for more verbosity e.g. -vvvvv)
  --version                             print the program's version and exit
  -h [ --host ] arg                     mongo host to connect to ( <set 
                                        name>/s1,s2 for sets)
  --port arg                            server port. Can also use --host 
                                        hostname:port
  --ipv6                                enable IPv6 support (disabled by 
                                        default)
  -u [ --username ] arg                 username
  -p [ --password ] arg                 password
  --authenticationDatabase arg          user source (defaults to dbname)
  --authenticationMechanism arg (=MONGODB-CR)
                                        authentication mechanism
  --dbpath arg                          directly access mongod database files 
                                        in the given path, instead of 
                                        connecting to a mongod  server - needs 
                                        to lock the data directory, so cannot 
                                        be used if a mongod is currently 
                                        accessing the same path
  --directoryperdb                      each db is in a separate directly 
                                        (relevant only if dbpath specified)
  --journal                             enable journaling (relevant only if 
                                        dbpath specified)
  -d [ --db ] arg                       database to use
  -c [ --collection ] arg               collection to use (some commands)
  -l [ --local ] arg                    local filename for put|get (default is 
                                        to use the same name as 'gridfs 
                                        filename')
  -t [ --type ] arg                     MIME type for put (default is to omit)
  -r [ --replace ]                      Remove other files with same name after
                                        PUT

Entre ellos, la operación de eliminación de archivos:

mongofiles eliminar nombre de archivo --port port --db nombre de biblioteca

mongofiles delete xxx.jpg --port 30000 --db pics

Caso de archivo de eliminación por lotes:

Dado que los archivos que se eliminarán son enormes, puede haber de 5 a 600 mil en un lote. Cada vez que elimine un archivo con el comando mongofiles, debe establecer una conexión tcp. Así que coloque temporalmente la URL en el archivo, luego diff los archivos y ejecute +sleep en un bucle para facilitar El puerto tcp está lleno:

for file in `ls`;do  for i in `cat 31aa*`;do echo " mongofiles delete $i --port 30000 --db pics" >> 2021-8-31.log && mongofiles delete $i --port 30000 --db pic  sleep 0.1 ;done ; echo sleep 60 ;sleep 120 ;done

punto de riesgo:

  • Use el comando mongofiles para eliminar temporalmente una pequeña cantidad de datos y la operación es lenta
  • Existe el riesgo de que la cantidad de tcpdumps esté llena y la cantidad de conexiones mongo esté llena
  • Durante el uso, se descubre que si la cantidad de archivos eliminados en lotes supera los 10 000, la eliminación fallará.mongofiles indica que la operación se realizó correctamente, pero los archivos aún existen

3. Soluciones:

Solución temporal de desarrollo:

Debido al procesamiento por lotes de archivos anómalos por parte del comando shell, se descubrió que muchos archivos no funcionaban y se le pidió temporalmente al desarrollador que los procesara. Después de la comprensión, el desarrollo adopta el lenguaje Java para usar el método de encapsulación del módulo del controlador mongo remove para eliminar archivos directamente.

import com.mongodb.DB;
import com.mongodb.DBObject;
import com.mongodb.Mongo;
import com.mongodb.gridfs.GridFS;
import com.mongodb.gridfs.GridFSDBFile;



public class MyGridFsTest {
    
    
	private String host = "127.0.0.1";
	private int port = 27017;
	private String dbName = "demogridfs";



	@Test
	public void testFindFile() throws IOException{
    
    
		Mongo connection = new Mongo(host, port);
		DB db = connection.getDB(dbName);
		GridFS gridFs = new GridFS(db);

		DBObject query = new BasicDBObject("filename", fileName);
		gridFs.remove(query);

El paquete secundario del controlador Mongo de Java elimina directamente los archivos y utiliza el conjunto de subprocesos de Mongo, pero no ocupa demasiados recursos, como la cantidad de conexiones de Mongo.

solución de python pymongo:

dirección oficial
inserte la descripción de la imagen aquí

(pymongo) [root@bj-redis-slave02-10-8-2-245 history]# python delete-pic.py > 2021-8.log &

(pymongo) [root@bj-redis-slave02-10-8-2-245 history]# tail -f 2021-8.log 

4. Anexo: Código:

#!/usr/bin/python
# -*- encoding: utf-8 -*-
import pymongo
import json
import os
from pymongo import MongoClient
from gridfs import GridFS
class GFS(object):
    def __init__(self, file_db,file_table):
        self.file_db = file_db
        self.file_table = file_table
 
    def createDB(self): #连接数据库,并创建文件数据库与数据表
        client = MongoClient('10.8.2.237',30000)
        db = client[self.file_db]
        file_table = db[self.file_table]
        return (db,file_table)
 
    def insertFile(self,db,filePath,query): #将文件存入数据表
        fs = GridFS(db,self.file_table)
        if fs.exists(query):
            print('已经存在该文件')
        else:
            with open(filePath,'rb') as fileObj:
                data = fileObj.read()
                ObjectId = fs.put(data,filename = filePath.split('/')[-1])
                print(ObjectId)
                fileObj.close()
            return ObjectId
 
    def getID(self,db,query,pic): #通过文件属性获取文件ID,ID为文件删除、文件读取做准备
        try:
            fs=GridFS(db, self.file_table)
            ObjectId=fs.find_one(query)._id
            msg=pic,'ObjectId',ObjectId
            print (msg)
            return ObjectId
        except AttributeError as e: #AttributeError为错误类型,此种错误的类型赋值给变量e;当try与except之间的语句触发
                                    # AttributeError错误时程序不会异常退出而是执行except AttributeError下面的内容
            print("AttributeError错误,图片不存在:",e)
            
    def remove(self,db,id): #文件数据库中数据的删除
        fs = GridFS(db, self.file_table)        
        fs.delete(id) #只能是id
        del_msg= id,'正在删除!!!'
        print (del_msg)
 
    def getFile(self,db,id): #获取文件属性,并读出二进制数据至内存
        fs = GridFS(db, self.file_table)
        gf=fs.get(id)
        bdata=gf.read() #二进制数据
        attri={
    
    } #文件属性信息
        attri['chunk_size']=gf.chunk_size
        attri['length']=gf.length
        attri["upload_date"] = gf.upload_date
        attri["filename"] = gf.filename
        attri['md5']=gf.md5
        print(attri)
        return (bdata, attri)
    def Writ_log(self,File,msg):
        f=open(File,'a')
        f.write(msg)
        f.close()
 
    def listFile(self,db): #列出所有文件名
        fs = GridFS(db, self.file_table)
        gf = fs.list()
 
    def findFile(self,db,file_table): #列出所有文件二进制数据
        fs = GridFS(db, table)
        for file in fs.find():
            bdata=file.read()
 
    def write_2_disk(self,bdata, attri): #将二进制数据存入磁盘
        name = "get_"+attri['filename']
        if name:
            output = open(name, 'wb')
        output.write(bdata)
        output.close()
        print("fetch image ok!")
 
if __name__=='__main__':
    gfs=GFS('pics','fs')
    (file_db,fileTable) = gfs.createDB() #创建数据库与数据表
    dir_list = os.listdir('2021-8')
    print (dir_list)
    for filePath in dir_list:
        filePath='2021-8/'+filePath
        lines = open(filePath,'r').readlines()
        for file in lines:
            pic =file.splitlines()[0]
            query = '{"filename": "%s"}' %(pic)
            query = json.loads(query)
            id=gfs.getID(file_db,query,pic)
            gfs.remove(file_db,id) #删除数据库中文件


    #filePath = '10.txt' #插入的文件
    #query = {'filename': '745082993188.jpg'}
    #id=gfs.getID(file_db,query,pic)
    #gfs.remove(file_db,id) #删除数据库中文件
    
    #id=gfs.insertFile(file_db,filePath,query) #插入文件 
    #(bdata,attri)=gfs.getFile(file_db,id) #查询并获取文件信息至内存    
    #gfs.write_2_disk(bdata,attri) #写入磁盘
    #gfs.remove(file_db,id) #删除数据库中文件

referencia:

pymongo tiene muchos tutoriales sobre el funcionamiento de mongo nosql, y hay muchas introducciones a la carga y descarga de múltiples sistemas de archivos gridfs. Pero hay menos introducción a la operación de eliminación de gridfs. La operación principal importante es obtener primero la identificación del archivo y luego eliminar la identificación del archivo a través del método de eliminación. (el método de eliminación de archivos solo acepta la identificación del archivo)

Oficial: https://pymongo.readthedocs.io/en/stable/tutorial.html

Gridfs elimina oficial: https://pymongo.readthedocs.io/en/stable/api/gridfs/index.html?highlight=delete#gridfs.GridFS.delete

https://blog.csdn.net/qq_30852577/article/details/84645693

https://blog.csdn.net/weiyuanke/article/details/7717476

Supongo que te gusta

Origin blog.csdn.net/weixin_43423965/article/details/128563115
Recomendado
Clasificación