Bruce Lindsay dijo una vez"Hay tres cosas importantes en el mundo de las bases de datos: Rendimiento, rendimiento y rendimiento". La mayoría de los arquitectos de empresa saben que, a medida que avanzamos en características y arquitecturas de bases de datos, es importante medir el rendimiento de forma abierta para poder comparar el coste total de propiedad de forma fiable.
YCSB hizo un gran trabajo de evaluación comparativa de los almacenes de datos que servían a las aplicaciones "Cloud OLTP". Estos almacenes de datos eran sencillos, con operaciones simples de obtención, colocación y eliminación. El YCSB punto de referencia consiste en operaciones simples de inserción, actualización, eliminación y escaneo en un documento simple de 10 valores clave; las cargas de trabajo se definen con una mezcla de estas operaciones con diversos porcentajes.
JSON bases de datos como Couchbase y MongoDB tienen un modelo de datos más avanzado con escalares, objetos anidados, matrices, matrices de objetos, matrices y matrices de objetos. Las bases de datos JSON también tienen consulta lenguaje, índices y capacidades. Además de las operaciones CRUD, las aplicaciones utilizan habitualmente los lenguajes de consulta declarativos de estas bases de datos para buscar, paginar y ejecutar informes. Por tanto, para ayudar a los arquitectos a evaluar las plataformas de forma eficaz, necesitamos una referencia adicional que mida estas capacidades además de las operaciones CRUD básicas. Este tutorial de YCSB explica sus capacidades para colmar esta laguna.
Documento YCSB estados: También esperamos fomentar el desarrollo de otras suites de evaluación comparativa de la nube que representen otras clases de aplicaciones poniendo a disposición nuestra herramienta de evaluación comparativa a través de código abierto. En este sentido, una característica clave del marco/herramienta YCSB es que es extensible: permite definir fácilmente nuevas cargas de trabajo, además de facilitar la evaluación comparativa de nuevos sistemas.
Este benchmark extiende YCSB a las bases de datos JSON mediante la ampliación de las operaciones existentes a JSON y la posterior definición de nuevas operaciones y nuevas cargas de trabajo.
Este es el esquema.
- Introducción
- Modelo de datos
- Operaciones de referencia
- Cargas de trabajo de referencia
- Implementación de YCSB-JSON
- ¿Cómo se ejecuta YCSB-JSON?
- Referencias
1. Introducción
YCSB se desarrolló para medir el rendimiento de los almacenes de datos escalables NoSQL clave-valor. La infraestructura de YCSB hace bien ese trabajo. YCSB utiliza un simple clave-valor plano. Couchbase utiliza un modelo JSON, que los clientes utilizan para aplicaciones masivamente interactivas. Hemos incorporado y estamos incorporando funciones al producto para que los clientes puedan crear estas aplicaciones de forma eficaz. Necesitamos mediciones de rendimiento para estos casos de uso.
Existen otras bases de datos compatibles con el modelo JSON: MongoDB, DocumentDB, DynamoDB, RethinkDB, Oracle NoSQL. Cuando se ejecuta YCSB en bases de datos JSON (Couchbase, MongoDB, etc), el controlador simplemente almacena y recupera cadenas en la estructura clave-valor JSON. Todas estas bases de datos requieren un nuevo punto de referencia para medir el procesamiento de la rica estructura de JSON (objetos anidados, matrices) y operaciones como paginación, agrupación, agregaciones.
El propósito de YCSB-JSON es ampliar el benchmark YCSB para medir la capacidad de las bases de datos JSON para cubrir estas dos cosas:
- Operaciones representativas de aplicaciones interactivas masivas.
- Operaciones sobre el modelo de datos JSON, incluyendo objetos anidados, arrays.
- Crear cargas de trabajo que representen operaciones de estas aplicaciones.
Vea estos casos de uso de clientes:
- Marriott construyó su sistema de reservas en IBM Mainframe y DB2. Se han encontrado con problemas de costes y rendimiento, ya que cada vez más clientes intentan consultar el inventario disponible. Los sistemas en DB2 se crearon originalmente para aceptar reservas de un sistema telefónico o de agentes. La proporción entre reservas y consultas era baja. Hoy en día, este ratio es alto, ya que el número de solicitudes de búsqueda ha aumentado exponencialmente. Esto también ha aumentado drásticamente el coste de la base de datos. Marriott trasladó todos sus datos de inventario a Couchbase con sincronización continua desde sus sistemas mainframe; las aplicaciones web utilizan Couchbase para las operaciones de consulta/búsqueda.
- Coches.com es un portal para listar y vender coches. Tienen los datos de la lista en Oracle. Cuando los publican en la web, no sólo tienen que presentar la información básica sobre el coche, sino también proporcionar información adicional, como cuántos usuarios están buscando un coche o lo han guardado en su lista de deseos. Es una forma de aumentar el compromiso y la sensación de urgencia. Todos los datos necesarios para estas operaciones interactivas se almacenan en Couchbase.
En términos más generales, las aplicaciones interactivas masivas incluyen las siguientes:
- Ver disponibilidad de habitaciones, precios y servicios (búsquedas por cliente final)
- Buscar información sobre marcas/modelos de coches o talleres de reparación (habilitar a los consumidores y socios a escala web)
- Proporcionar información al cliente en su contexto (servicios de localización)
- Servir tanto datos maestros como transaccionales (a escala)
Para cumplir estos requisitos, las aplicaciones y bases de datos hacen lo siguiente:
- Descarga de consultas de bases de datos de sistemas de registro de alto coste (mainframe, Oracle)
- (aplicaciones de reservas e ingresos)
- Apertura de las funciones de back-office al acceso web/móvil
- (permite a los internautas consultar los datos de la habitación)
- Escalar bases de datos/consultas con un mejor coste total de propiedad
- (escalar mainframes con servidores básicos)
- Modernizar los sistemas heredados con las capacidades que exigen las nuevas aplicaciones de colaboración/compromiso
- (consultar inventario, vuelos, disponibilidad de habitaciones, análisis por departamentos)
La nueva referencia debe medir el rendimiento de las consultas que implementan estas operaciones.
2. Modelo de datos
Hemos tomado cliente y pedidos como dos colecciones distintas de documentos JSON. Cada pedido tiene una referencia a su cliente.
A continuación se muestra el ejemplo de cliente y el documento de pedido. Se ha generado mediante el generador de datos fakeit. Esta herramienta está disponible en: https://github.com/bentonam/fakeit
Consulte en el apéndice el archivo YAML utilizado para definir el modelo de datos y el dominio.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
Sample customer document Document Key: 100_advjson { "_id": "100_advjson", "doc_id": 100, "gid": "48a8e177-15e5-5116-95d0-41478601bbdd", "first_name": "Stella", "middle_name": "Jackson", "last_name": "Toy", "ballance_current": "$1084.94", "dob": "2016-05-11", "email": "Alysson83@yahoo.com", "isActive": true, "linear_score": 31, "weighted_score": 40, "phone_country": "fr", "phone_by_country": "01 80 03 25 39", "age_group": "child", |
3. Operaciones de referencia:
Las cuatro primeras operaciones son las mismas que las del YCSB estándar, salvo que se trata de documentos JSON. El resto de las operaciones son nuevas.
- Inserte: Inserta un nuevo documento JSON.
- Actualización: Actualiza un documento JSON reemplazando el valor de un campo escalar.
- Leer: Lee un documento JSON, ya sea un campo elegido al azar o todos los campos.
- Borrar: Elimina un documento JSON con una clave dada.
- Escanear: Escanea documentos JSON en orden, empezando por una clave de registro elegida aleatoriamente. El número de registros a escanear se elige aleatoriamente (LIMIT).
- Buscar en: Búsqueda de documentos JSON basada en predicados de rango en 3 campos (personalizable a n campos).
- Página: Paginar el conjunto de resultados de una consulta con predicado sobre un campo del documento.
- Todos los clientes en zip con OFFSET y LIMIT elegidos al azar en SQL, N1QL.
- NestScan: Consulta documentos JSON basándose en un predicado sobre un campo anidado de 1 nivel.
- ArrayScan: Consulta documentos JSON basados en un predicado dentro del campo de matriz de un solo nivel.
- ArrayDeepScan: Consulta documentos JSON basándose en un predicado dentro de un campo array de dos niveles (array de arrays).
- Informe: Consulte los detalles de los pedidos de los clientes de un código postal específico.
- Cada cliente tiene varios pedidos.
- El documento de pedido contiene los datos del pedido.
- Informe2: Generar resumen de pedidos de venta para un día determinado, agrupar por zip.
- Carga: Carga de datos.
- Sincroniza: Transmisión y sincronización de datos desde otro sistema.
- Agregado: Agrupar y agregar.
Para Couchbase: Ejemplos de implementación de Benchmark Operations
Las cuatro primeras operaciones son las mismas que las del YCSB estándar, salvo que se trata de documentos JSON. El resto de las operaciones son nuevas.
Couchbase implementa YCSB en dos modos.
KV=verdadero. KV significa clave-valor. Las operaciones simples de YCSB INSERT, UPDATE y DELETE pueden implementarse a través de APIs KV en lugar de consultas. Establecer KV=true significa utilizar la API KV y KV=false significa utilizar la API N1QL (SQL para JSON). Consulte el tutorial de N1QL en https://query-tutorial.couchbase.com
- Inserte: Inserta un nuevo documento JSON.
|
1 2 |
KV=true: KV call to insert KV=false: INSERT INTO customer VALUES(...) |
2. Actualice: Actualiza un documento JSON reemplazando el valor de un campo escalar.
|
1 2 3 4 |
KV=true: KV call to UPDATE a single document. KV=false: UPDATE customer SET field1 = value USE KEYS [documentkey]<span style="font-weight: 400"><strong>Read</strong>: Read a JSON document, either one randomly chosen field in the document or all the fields.</span> |
|
1 2 3 4 |
KV=true: KV call to fetch a single document. KV=false: SELECT * FROM customer USE KEYS [documentkey] |
3. Lee: Obtener un documento JSON con una clave dada.
|
1 2 3 4 |
KV=true: KV call to fetch a single document. KV=false: SELECT * FROM customer USE KEYS [documentkey] |
4. Borrar: Elimina un documento JSON con una clave dada.
|
1 2 3 4 |
KV=true: KV call to fetch a single document. KV=false: DELETE FROM customer USE KEYS [documentkey] |
5. Escanear: Escanea documentos JSON en orden, empezando por una clave de registro elegida aleatoriamente. El número de registros a escanear se elige aleatoriamente (LIMIT).
|
1 2 3 4 5 6 7 |
KV=TRUE: SELECT META().id FROM customer WHERE META().id > “val” ORDER BY META().id LIMIT <num> Fetch the actual documents directly using KV calls from the benchmark driver. KV=false: SELECT * FROM customer WHERE META().id > “val” ORDER BY META().id LIMIT <num> |
6. Página: Paginar el conjunto de resultados de una consulta con predicado sobre un campo del documento.
|
1 2 3 4 5 6 7 8 9 10 |
All customers in address.zip with randomly chosen OFFSET and LIMIT in SQL, N1QL KV=TRUE: SELECT META().id FROM customer WHERE address.zip = “value” OFFSET <num> LIMIT <num> Fetch the actual documents directly using KV calls from the benchmark driver. KV=false: SELECT * FROM customer WHERE address.zip = “value” OFFSET <num> LIMIT <num> |
7. Buscar en: Búsqueda de documentos JSON basada en predicados de rango en 3 campos (personalizable a n campos).
|
1 2 3 4 5 6 7 8 9 10 11 12 |
All customers WHERE (country = “value1” AND age_group = “value2” and YEAR(dob) = “value” ) All customers retrieved with randomly chosen OFFSET and LIMIT in SQL, N1QL KV=TRUE: SELECT META().id FROM customer WHERE country = “value1” AND age_group = “value2” and YEAR(dob) = “value” ORDER BY country, age_group, YEAR(dob) OFFSET <num> LIMIT <num> Fetch the actual documents directly using KV calls from the benchmark driver. KV=false: SELECT * FROM customer WHERE WHERE country = “value1” AND age_group = “value2” and YEAR(dob) = “value” ORDER BY country, age_group, YEAR(dob) OFFSET <num> LIMIT <num> |
8. NestScan: Consulta documentos JSON basándose en un predicado sobre un campo anidado de 1 nivel.
|
1 2 3 4 5 6 7 8 9 |
KV=TRUE: SELECT META().id FROM customer WHERE address.prev_address.zip = “value” LIMIT <num> Fetch the actual documents directly using KV calls from the benchmark driver. KV=false: SELECT * FROM customer WHERE address.prev_address.zip = “value” LIMIT <num> |
9. ArrayScan: Consulta documentos JSON basados en un predicado dentro del campo de matriz de un solo nivel.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
Find all customers who have devices with a value. E.g. FF-012 Sample devices field "devices": [ "EE-245", "FF-012", "GG-789", "HH-246" ], KV=TRUE: SELECT META().id FROM customer WHERE ANY v IN devices SATISFIES v = “FF-012” END ORDER BY META().id LIMIT <num> Fetch the actual documents directly using KV calls from the benchmark driver. KV=false: SELECT * FROM customer WHERE ANY v IN devices SATISFIES v = “FF-012” ORDER BY META().id END LIMIT <num> |
10. ArrayDeepscan: Consulta documentos JSON basándose en un predicado dentro de un campo array de dos niveles (array de arrays).
- Consígueme la lista de todos los clientes que han visitado París, Francia.
KV=verdadero:
|
1 2 3 4 5 6 7 8 |
SELECT META().id FROM customer WHERE ANY v in visited_places SATISFIES v.country = “France” AND ANY c in v.cities SATISFIES c = “Paris” END ORDER BY META().id LIMIT <num> |
Obtenga los documentos reales directamente mediante llamadas KV desde el controlador de referencia.
KV=falso:
|
1 2 3 4 5 6 7 8 |
SELECT * FROM customer WHERE ANY v in visited_places SATISFIES v.country = “France” AND ANY c in v.cities SATISFIES c = “Paris” END END ORDER BY META().id LIMIT <num> |
11. Informe: Consulte los detalles de los pedidos de los clientes de un código postal específico.
-
123456789101112131415161718Each customer has multiple orders.Order document has order details.KV=TRUE:Not possible (easily without significant perf impact.KV=false:SELECT *FROM customer c INNER JOIN orders oON (META(id) IN c.order_list)WHERE address.zip = "val"ANSI JOIN with HASH join:SELECT *FROM customer c INNER JOIN orders o USE HASH (probe)ON (META(id) IN c.order_list)WHERE address.zip = “val”
12. Informe2: Generar resumen de pedidos de venta para un día determinado, agrupar por zip.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
KV=TRUE: Need to write a program KV=false: SELECT o.day, c.zip, SUM(o.salesamt) FROM customer c INNER JOIN orders o ON (META(id) IN c.order_list) WHERE c.zip = “value” AND o.day = “value” GROUP BY c.day, c.zip ORDER BY SUM(o.sales_amt) ----ANSI join SELECT o.day, c.zip, SUM(o.salesamt) FROM customer c INNER JOIN orders o ON (META(id) IN c.order_list) WHERE c.zip = “value” AND o.day = “value” GROUP BY c.day, c.zip ORDER BY SUM(o.sales_amt) ------ANSI join with HASH join SELECT o.day, c.zip, SUM(o.salesamt) FROM customer c INNER JOIN orders o USE HASH (probe) ON (META(id) IN c.order_list) WHERE c.zip = “value” AND o.day = “value” GROUP BY c.day, c.zip ORDER BY SUM(o.sales_amt) |
13. Carga: Carga de datos.
- CARGAR 1 millón de documentos.
- CARGAR 10 millones de documentos.
14. Sincronizar: Transmisión y sincronización de datos desde otro sistema
- Necesidad de medir el rendimiento de la sincronización de datos.
- Sincroniza 1 millón de documentos. 50% actualizar, 50% insertar.
- Sincronización de 10 millones de documentos. Actualización 80%, inserción 20%.
- Idealmente, esta sincronización se realizaría desde Kafka o algún otro conector que extraiga datos de una fuente diferente.
15. Agregado: Agrupar y agregar.
|
1 2 3 4 5 6 |
---Group Query 1 SELECT c.zip, COUNT(1) FROM customer c WHERE c.zip between "value1" and "value2" GROUP BY c.zip |
|
1 2 3 4 5 6 7 8 9 10 |
---GROUP BY query 2 SELECT o.day, SUM(o.salesamt) FROM orders o WHERE o.day between “value1” and “value2” GROUP BY o.day; |
4. Cargas de trabajo de referencia
Las cargas de trabajo son una combinación de estas operaciones.
Para empezar, la definición de la carga de trabajo puede reutilizar las definiciones de la definición YCSB: carga de trabajo-A a carga de trabajo-E. Los detalles están disponibles en https://github.com/brianfrankcooper/YCSB/wiki/Core-Workloads. Necesitaremos definir cargas de trabajo adicionales con una combinación de las operaciones definidas anteriormente.
La carga de trabajo SA es la misma que la carga de trabajo A en el nuevo modelo. Lo mismo ocurre con las cargas de trabajo B a F. Las llamaremos SB a SF para diferenciarlas de las cargas de trabajo B a F.
| Carga de trabajo | Operaciones | Selección de discos | Ejemplo de aplicación |
| SA - Actualización pesada | Leer: 50%
Actualización 50% |
Zipfian | Almacén de sesión que registra las acciones recientes en una sesión de usuario |
| SB - Leer pesado | Leer: 95%
Actualización: 5% |
Zipfian | Etiquetado de fotos; añadir una etiqueta es una actualización, pero la mayoría de las operaciones
Actualización: 5% son para leer etiquetas |
| SC - Sólo lectura | Leer: 100% | Zipfian | Caché de perfiles de usuario, donde los perfiles se construyen en otro lugar (por ejemplo, Hadoop). |
| SD - Leer lo último | Leer: 95%
Inserto 5% |
Última | Actualizaciones de estado de los usuarios; la gente quiere leer los últimos estados |
| SE - Rangos cortos | Escanear: 95%
Inserto: 5% |
Zipfian/Uniforme | Conversaciones en hilos, donde cada búsqueda es para los mensajes de un hilo determinado (se supone que se agrupan por identificador de hilo). |
| SF - Leer, modificar, escribir | Leer: 50%
Escribe: 50% |
Zipfian | base de datos de usuarios, donde el usuario lee y modifica los registros de usuario o para registrar la actividad del usuario. |
| SG - Página pesada | Página: 90%
Inserto: 5% Actualización:5% |
Zipfian | Base de datos de usuarios, donde se añaden nuevos usuarios, se actualizan los registros existentes y se realizan consultas de paginación en el sistema. |
| SH - Búsqueda pesada | Buscar: 90%
Inserto: 5% Actualización: 5% |
Zipfian | Base de datos de usuarios, donde se añaden nuevos usuarios, se actualizan los registros existentes y se realizan consultas de búsqueda en el sistema. |
| SI - NestScan pesado | Nestscan: 90%
Inserto: 5% Actualización: 5% |
Zipfian | Base de datos de usuarios, donde se añaden nuevos usuarios, se actualizan los registros existentes, se anidan las consultas sobre el sistema. |
| SJ - Arrayscan pesado | Arrayscan: 90%
Inserto: 5% Actualización: 5% |
Zipfian | |
| SK - ArrayDeepscan pesado | ArrayDeepScan: 90%
Inserto: 5% Actualización: 5% |
Zipfian | |
| SL - Informe | Informe: 100% | ||
| SL - Informe2 | Informe2: 100% | ||
| SLoad - Carga | Carga: 100% | Todo | Carga de datos para configurar SoE |
| SN - Agregado
(SN1, SN2) |
Agregación: 90%
Inserto: 5% Actualización: 5% |
||
| SMIX - Carga de trabajo mixta | Página:20%
Búsqueda:20% Arrayscan:15% ArrayDeepscan:10% Agregado: 10% Informe: 10% |
Véase más abajo. | |
| SSync - Sincronización | Sincronización: 100%
Fusión/Actualización: 70% Nuevo/Inserto: 30% |
Sincronización continua de datos de otros sistemas con los sistemas de compromiso. Véase más abajo. |
Ejemplo de configuración para la carga de trabajo YCSB/JSON
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
recordcount=1000 operationcount=1000 workload=com.yahoo.ycsb.workloads.CoreWorkload Filternumlow = 2 Filternumhigh = 14 Sortnumlow = 3 Sortnumhigh = 6 page1propotion=0.95 insertproportion=0.05 requestdistribution=zipfian maxscanlength=100 scanlengthdistribution=uniform |
Agradecimientos
Gracias a Raju Suravarjjala, Couchbase Senior director for QE and Performance, por empujarnos a hacer esto y a todo el equipo de rendimiento por apoyar este esfuerzo. El benchmark YCSB-JSON fue desarrollado en colaboración con Alex Gyryk, Ingeniero principal de rendimiento de Couchbase. Desarrolló los modelos de datos para clientes y pedidos utilizados en este artículo e implementó las operaciones y cargas de trabajo en YCSB-JSON para Couchbase y MongoDB. La implementación de YCSB-JSON está disponible en: https://github.com/couchbaselabs/YCSB
Gracias a Aron Benton, Couchase Solution Architect, por desarrollar un generador de datos JSON fácil de usar y eficiente, fakeit. Lo desarrolló antes de unirse a Couchbase. Está disponible en: https://github.com/bentonam/fakeit
Parte siguiente
En el próximo artículo sobre YCSB-JSON, Alex explicará las implementaciones de este benchmark para Couchbase y MongoDB. El código fuente de la implementación está disponible en: https://github.com/couchbaselabs/YCSB
Referencias
- Evaluación comparativa de sistemas de servicio en nube con YCSB: https://www.cs.duke.edu/courses/fall13/cps296.4/838-CloudPapers/ycsb.pdf
- JSON: https://json.org
- Generador JSON: https://www.json-generator.com/
- Implementación de YCSB-JSON: https://github.com/couchbaselabs/YCSB
Anexo
YAML para generar el conjunto de datos de clientes.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
name: AdvJSON type: object key: _id data: fixed: 10000 properties: _id: type: string data: post_build: "return '' + this.doc_id + '_advjson';" doc_id: type: integer description: The document id data: build: "return document_index + 1" gid: type: description: "guid" data: build: "return chance.guid();" first_name: type: string description: "First name - string, linked to url as the personal page" data: |
Hola. ¿Existe YAML para pedidos para generar el conjunto de datos de pedidos?
También estoy buscando esto. En el YAML del apéndice falta la clave "order_list".
Hola, ¡gran trabajo! ¿Podría por favor proporcionar más instrucciones sobre cómo llegar a la aplicación mencionada aquí? Acabo de comprobar la rama maestra de https://github.com/couchbaselabs/YCSB y no consigo encontrar ni las cargas de trabajo mencionadas aquí ni la implementación de las nuevas operaciones.
Consulte los detalles en el artículo de seguimiento: https://www.couchbase.com/ycsb-json-implementation-for-couchbase-and-mongodb/
¡Genial, gracias!
Muchas gracias,
Por favor, tengo una pregunta, ¿Cómo podemos generar una nueva carga de trabajo basada en nuevos requisitos? por favor, necesitamos un ejemplo.