tutorial query queries multi modify how for existing all python mongodb python-2.7 rethinkdb nosql

python - query - multi insert mongodb



Comparando el rendimiento de inserciĆ³n masiva de MongoDB y RethinkDB (4)

Esta es mi primera pregunta oficial aquí; Doy la bienvenida a todas las críticas a mi publicación para que pueda aprender cómo ser un mejor ciudadano de SO.

Estoy investigando el DBMS no relacional para almacenar listas de exclusión de correo electrónico potencialmente grandes, inclinado hacia MongoDB o RethinkDB, utilizando sus respectivas bibliotecas de cliente de Python. El punto clave de mi aplicación es el rendimiento de la inserción masiva, por lo que he configurado dos scripts de Python para insertar 20,000 registros en lotes de 5,000 en una colección de MongoDB y RethinkDB.

La secuencia de comandos MongoDB python mongo_insert_test.py:

NUM_LINES = 20000 BATCH_SIZE = 5000 def insert_records(): collection = mongo.recips i = 0 batch_counter = 0 batch = [] while i <= NUM_LINES: i += 1 recip = { ''address'': "test%d@test%d.com" % (i, i) } if batch_counter <= BATCH_SIZE: batch.append(recip) batch_counter += 1 if (batch_counter == BATCH_SIZE) or i == NUM_LINES: collection.insert(batch) batch_counter = 0 batch = [] if __name__ == ''__main__'': insert_records()

El script python RethinkDB casi idéntico rethink_insert_test.py:

NUM_LINES = 20000 BATCH_SIZE = 5000 def insert_records(): i = 0 batch_counter = 0 batch = [] while i <= NUM_LINES: i += 1 recip = { ''address'': "test%d@test%d.com" % (i, i) } if batch_counter <= BATCH_SIZE: batch.append(recip) batch_counter += 1 if (batch_counter == BATCH_SIZE) or i == NUM_LINES: r.table(''recip'').insert(batch).run() batch_counter = 0 batch = [] if __name__ == ''__main__'': insert_records()

En mi entorno de desarrollo, el script MongoDB inserta 20,000 registros en menos de un segundo:

$ time python mongo_insert_test.py real 0m0.618s user 0m0.400s sys 0m0.032s

En el mismo entorno, la secuencia de comandos RethinkDB se ejecuta mucho más lentamente, insertando 20,000 registros en más de 2 minutos:

$ time python rethink_insert_test.py real 2m2.502s user 0m3.000s sys 0m0.052s

¿Me estoy perdiendo algo enorme aquí con respecto a cómo funcionan estos dos DBMS? ¿Por qué RethinkDB funciona tan mal con esta prueba?

Mi máquina de desarrollo tenía aproximadamente 1,2 GB de memoria disponible para estas pruebas.


Dejando de lado lo que coffemug publicó:

  1. dependiendo de la versión del controlador que esté utilizando y cómo configure la conexión a mongodb, es posible que el servidor ni siquiera reconozca esas inserciones. Si está utilizando la última versión del controlador de Python, esas operaciones solo esperan un acuse de recibo del servidor (lo que no significa que los datos se hayan escrito siquiera en la memoria). Para más detalles sobre a qué me refiero, revisa la configuración de preocupación de escribir de Mongodb

  2. podría acelerar el caso de Rethinkdb al paralelizar las inserciones. Básicamente, si ejecuta múltiples procesos / subprocesos, verá que la velocidad aumenta. En el caso de Mongo, debido a las cerraduras involucradas, el paralelismo no ayudará.

Dicho esto, RethinkDB podría mejorar la velocidad de las escrituras.

PD: Estoy trabajando para Rethink, pero los puntos anteriores se basan en mi conocimiento imparcial de ambos sistemas.


Desarrollador de Pymongo aquí: en caso de que no lo esté haciendo, asegúrese de estar utilizando la última versión de MongoClient y MongoClient o MongoRepicaSetClient para que sus MongoRepicaSetClient sean reconocidas y no MongoRepicaSetClient y olvidadas. Como @Alex dice, lo más probable es que sean lo que necesita.

Otras consideraciones que me gustaría tener son: ¿es este el caso de uso principal para la base de datos o simplemente el punto de dolor central? Es posible que desee considerar otros patrones de datos, consultar los datos, facilidad de uso y mantenimiento antes de tomar su decisión.


Por favor, perdonen la analogía, sin embargo, aclara mi punto.

No lleva mucho tiempo bloquear algo valioso en una caja fuerte, pero hacerlo miles de veces más de voluntad. Si, en cambio, publicó en la bóveda de un banco, tenga en cuenta el momento en que su valor no es seguro durante su viaje a su banco; esa parcela probablemente sería apilada con muchas otras parcelas, desde un depositante de ideas afines. Alguien se abrirá para abrir su paquete y luego lo apilará con otras cosas para colocarlo en una bóveda segura.

Ahí radica la diferencia entre las confirmaciones regulares de datos en el disco y la creación de lotes o la escritura perezosa de datos en el disco. Es una compensación entre una mayor integridad de datos y un rendimiento de escritura mejorado. Si la pérdida de datos no importa tanto, entonces es perfectamente aceptable sincronizar al disco con menos frecuencia, por lotes o escribir actualizaciones de forma perezosa. Hacer la elección incorrecta te morderá en el trasero un día, ¡así que elige sabiamente!


RethinkDB actualmente implementa inserciones por lotes haciendo una sola inserción a la vez en el servidor. Dado que Rethink vacía cada registro en el disco (porque está diseñado pensando primero en la seguridad), esto tiene un efecto realmente negativo en las cargas de trabajo como esta.

Estamos haciendo dos cosas para abordar esto:

  1. Las inserciones masivas se implementarán a través de un algoritmo de inserción masiva en el servidor para evitar hacer una inserción a la vez.
  2. Le daremos la opción de relajar las restricciones de durabilidad para permitir que la memoria caché absorba las inserciones de alto rendimiento si lo desea (a cambio de no sincronizar con el disco con tanta frecuencia).

Esto se solucionará definitivamente en 4-12 semanas (y si necesita esto lo antes posible, siéntase libre de enviarme un correo electrónico a [email protected] y veré si podemos volver a priorizar).

Aquí están los problemas relevantes de github:

https://github.com/rethinkdb/rethinkdb/issues/207

https://github.com/rethinkdb/rethinkdb/issues/314

Espero que esto ayude. No dude en contactarnos si necesita ayuda.