Couchbase Móvil

Conflictos y resolución de documentos en Couchbase Mobile 2.0

Los conflictos entre documentos pueden ocurrir en entornos distribuidos que soportan la sincronización de datos, en los que un documento puede ser actualizado simultáneamente por uno o más escritores. Esto es especialmente común en entornos móviles, donde las conexiones de red poco fiables pueden provocar que los cambios simultáneos de varios dispositivos no se sincronicen a tiempo.

También puede ocurrir en el lado del cliente, por ejemplo, si un documento se está actualizando localmente mientras los cambios en el documento se están bajando al cliente desde un servidor remoto. De ahí la necesidad de resolver estos conflictos entre documentos.  Couchbase Móvil 2.0presenta "Resolución automática de conflictos" o un "Sin conflictos" en el que los conflictos se gestionan automáticamente y no hay revisiones de documentos en conflicto en la base de datos de Couchbase.

Como desarrollador de aplicaciones, es probable que nunca tengas que hacer nada específico en la aplicación para resolver conflictos, ya que el sistema de resolución de conflictos por defecto se encargará automáticamente de ello. Sin embargo, si lo necesitas, tienes la opción de ser notificado de los conflictos y tomar las medidas oportunas. Este post discutirá los fundamentos de cómo los conflictos de documentos son manejados automáticamente en Couchbase Mobile 2.0 usando el "resolución automática de conflictos" o "sin conflictos ".

 

Supuestos

Este post asume que usted está familiarizado con la arquitectura de la pila de Couchbase Mobile que incluye el Couchbase Lite base de datos integrada para sus clientes móviles, el Pasarela de sincronización y Servidor Couchbase. Si eres nuevo en la plataforma, te recomiendo que empieces por estos recursos.

Fondo

Si aún no lo ha hecho, le recomendamos que lea esto antes. desmitificar la resolución de conflictos post que discute los fundamentos de cómo se maneja la resolución de conflictos en modo "no libre de conflictos" en Couchbase Mobile, incluyendo una visión general del sistema de Control de Concurrencia Multi-Versión (MVCC).

Árbol de revisión de documentos

Para entender el proceso de resolución de conflictos, tendrías que tener una comprensión básica de cómo se almacenan los documentos. En Couchbase Mobile, a cada documento se le asigna un único ID de revisión generado por el sistema o revID. Este identificador se añade al identificador del documento, que es el mismo para todas las revisiones. Cada cambio en un documento, ya sea una modificación o una eliminación, se trata como una nueva revisión del documento y, por tanto, se le asigna un nuevo ID de revisión.

Además, cada revisión de documento tiene un "generationID"asociada a ella. La primera vez que se crea un documento, se crea una revisión con un "generationID" de 1. Cada actualización de revisión posterior incrementará este número.

Cada vez que se va a realizar un cambio (edición o eliminación) en un documento existente, el autor debe incluir el ID de revisión de la revisión actual del documento que se está actualizando. Se crea una nueva revisión para el cambio y se añade como nodo hijo a la revisión actual que se estaba actualizando, dando lugar a un Árbol de Revisión para el documento.

NOTA "revID" debe ser tratado por la aplicación como un objeto opaco y la aplicación no debe intentar generar el objeto "revID".

Cómo se producen los conflictos de documentos

A alto nivel, un conflicto se produce cuando varios redactores realizan cambios en la misma revisión principal de un documento.

Conflictos en Couchbase Lite

La siguiente ilustración describe un escenario en el que una aplicación está actualizando una revisión de documento en memoria mientras que la misma revisión se está actualizando como resultado de una replicación pull.

Conflictos en la pasarela de sincronización

La siguiente ilustración describe una situación en la que dos clientes introducen cambios en la misma revisión del documento.

Resolución de conflictos en Couchbase Mobile 2.0

En "Sin conflictos el Sync Gateway rechaza todas las actualizaciones conflictivas. Los conflictos se resuelven automáticamente en el momento en que se crea, actualiza o elimina el documento.
Esto implica que no hay documentos conflictivos almacenados en la base de datos y es efectivamente, "Sin conflictos". Vamos a ver cómo funciona.

Resolución automática de conflictos en Couchbase Lite 2.0

Cada documento en Couchbase Lite 2.0 está asociado a un "resolución de conflictos" que se ejecuta si se produce un conflicto cuando se intenta guardar o borrar un documento. La función de resolución de conflictos elige un "ganador" entre las revisiones en conflicto y este ganador se añade como hijo al árbol de revisiones del documento.

Hay dos políticas de control de concurrencia soportadas por Couchbase Lite.

Política de control de concurrencia

La última escritura siempre gana (por defecto):

Esta es también la política de resolución de conflictos por defecto. En este caso, siempre gana la última actualización de la base de datos.

Cuando llame guardarDocumento sin el argumento Control de concurrencia, ésta es la política que se aplica por defecto.

Este es un ejemplo de la llamada en swift.

Los siguientes ejemplos deberían aclarar las implicaciones de esta política

  •  Por ejemplo, nuestra petición de guardar/actualizar tiene éxito aunque el documento en la base de datos haya sido actualizado desde la última vez que leímos el documento. El documento en la base de datos podría haber sido actualizado por un hilo diferente en la aplicación como resultado de algún desencadenante externo, como una replicación pull o una obtención de datos de un servidor remoto. La implicación es que cualquier cambio realizado en el documento entre el momento en que lo leímos y lo actualizamos se sobrescribiría.
  • Como se muestra a continuación, nuestra solicitud de guardar / actualizar tiene éxito a pesar de que el documento en la base de datos se ha eliminado desde la última vez que leímos el documento. El documento en la base de datos podría haber sido actualizado por un hilo diferente en la aplicación como resultado de algún desencadenante externo, como una replicación pull o una obtención de datos de un servidor remoto. La implicación es que un documento borrado podría ser resucitado como resultado del guardado.
Fracasar en el conflicto

Aunque anticipamos que la política de control de concurrencia por defecto de "la última escritura gana" debería funcionar para la mayoría de los casos, puede anular el comportamiento por defecto especificando que desea ser notificado en caso de conflicto al guardar el documento. Esto puede hacerse incluyendo la opción ControlConcurrente como parte de la solicitud de almacenamiento.

Un valor de retorno falso con un Control de concurrencia política failOnConflict indica que el documento guardado falló como resultado de un conflicto. A continuación examinaremos cómo puede gestionar los errores de conflicto.

Gestión de fallos en los conflictos

La forma de manejar los conflictos depende de la semántica de la aplicación. Aquí hay ejemplos de cómo se puede manejar en swift (que puede ser fácilmente mapeado a otros lenguajes)

  • Opción 1: Fusionar las versiones en conflicto del documento y guardar

Este es un ejemplo de cómo fusionar las revisiones en conflicto. Una vez más, la forma de hacerlo depende enteramente de su aplicación. Esto pretende ser una implementación de referencia sobre cómo usted podría manejarlo.

  • Opción 2: Fuerza tu salvación para ganar

Esta opción es efectivamente la misma que la política de concurrencia por defecto de "las escrituras siempre ganan". Excepto que en este caso, se examina el contenido del documento actualmente guardado y luego se determina si se debe forzar el guardado utilizando un comando guardarDocumento.
Tenga en cuenta que aún podría correr el riesgo de una condición de carrera en la que el documento podría ser actualizado de nuevo antes de guardarlo.

  • Opción 3: Saltar la parada

En este caso, podría examinar el contenido del documento guardado actualmente y, a continuación, determinar que prefiere conservar la versión guardada actualmente del documento.

Implicaciones en la creación de documentos con el mismo Id.

Dado que la política de resolución de conflictos por defecto en guardarDocumento es que la última escritura siempre gana, si se intenta crear de nuevo un documento con un docId que ya existe en la base de datos, seguirá adelante y actualizará el documento existente añadiéndole una nueva revisión.

Por lo tanto, si desea asegurarse de que no actualiza inadvertidamente un documento existente, debe especificar el valor "ConcurrenyControl argumento con failOnConflict. Esto devolverá un error que podrá gestionar adecuadamente.

Es muy similar a la opción 3 especificada anteriormente, salvo que en este caso no es necesario examinar el contenido actual del documento. Un fallo de conflicto implica que ya existe un documento con Id.

Este es un ejemplo en Swift

Modo sin conflictos en Sync Gateway 2.0

En este modo, la pasarela de sincronización rechaza las revisiones que causan un conflicto con un Error HTTP 409, asegurando así que no hay revisiones conflictivas en la base de datos. Los conflictos se gestionan en el lado del cliente durante una replicación pull.

Replicación Push

  1. El cliente envía los cambios de revisión a Sync Gateway.
  2. Sync Gateway detecta que la revisión entrante entra en conflicto con la revisión actual guardada en el servidor (es decir, el ancestro de la revisión entrante no es la revisión activa en el servidor).
  3. Sync Gateway rechaza el cambio de revisión con un 409 Error. Couchbase Lite realmente no hace nada más que registrar el error. El conflicto se resuelve posteriormente durante una replicación pull.

Replicación Pull

Durante una replicación pull, si el cliente detecta un conflicto, éste se resuelve utilizando los siguientes criterios deterministas

  • Los borrados siempre ganan. Un ejemplo de este caso es el que se muestra a continuación.

  • El cambio más reciente (el más alto ID de generación) gana o la revisión con max revID gana si las generaciones son iguales. es decir - el revID que ordena más alto en una simple comparación ASCII. A continuación se muestra un ejemplo.

 

A continuación, examinamos los casos durante la Replicación Pull.

La rama de servidores es la ganadora

  1. El cliente extrae los cambios de revisión del Sync Gateway
  2. El cliente detecta que la revisión entrante está en conflicto con la revisión guardada actual (es decir, la revisión entrante y la revisión guardada comparten un padre común).
  3. El cliente llama a la función de resolución de conflictos que determina el ganador entre la revisión actual guardada y la revisión del servidor.
    1. Dado que la revisión entrante (Rev2-B) del servidor es más reciente que la revisión local (Rev2-A), se selecciona la revisión del servidor como ganadora. Tenga en cuenta que esto también ocurriría si la revisión del servidor se borrara.
  4. La rama del servidor se injerta en el árbol de revisión local (y la rama local se tombstoned)
  5. Posteriormente, cuando los cambios se envíen al servidor, no habrá conflictos y el servidor se sincronizará con el cliente.
La sucursal local es la ganadora
  1. El cliente extrae los cambios de revisión del Sync Gateway
  2. El cliente detecta que la revisión entrante está en conflicto con la revisión guardada actual (es decir, la revisión entrante y la revisión guardada comparten un padre común).
  3. El cliente llama a la función de resolución de conflictos que determina el ganador entre la revisión actual guardada y la revisión del servidor.
    1. Dado que la revisión local (Rev2-B) es la más reciente que la revisión del servidor entrante (Rev2-A), la revisión local es seleccionada como la ganadora. Tenga en cuenta que esto también ocurriría si la revisión de la rama local fuera eliminada.
  4. La rama del servidor se injerta en el árbol de revisiones local y se crea una nueva revisión Rev3 que corresponde al contenido de la revisión ganadora, Rev2-B
  5. Posteriormente, cuando los cambios se envíen al servidor, no habrá conflictos y el servidor se sincronizará con el cliente.

NOTA: Como usted ha observado, los conflictos se resuelven en Couchbase Lite durante una replicación pull. La implicación de esto es que si el replicador está configurado para ser sólo un replicador de empuje, a continuación, la vista de Couchbase Lite de los datos divergentes de Sync Gateway (ya que algunos de los intentos de CBL escribe fallaría w / 409). Por lo tanto, si prevé que se produzcan conflictos, se recomienda que el replicador de Couchbase Lite se configure en modo push-pull cuando se utilice en modo Conflict Free.

 

Configuración del modo libre de conflictos en Sync Gateway

El modo "Sin conflictos" de Sync Gateway se puede configurar a través de permitir_conflictos en el archivo de configuración de Sync Gateway. Debe tener el valor "falso" para habilitar el modo libre de conflictos. También debe tenerse en cuenta que, independientemente de la configuración de esta propiedad, no habrá revisiones conflictivas añadidas a la puerta de enlace de sincronización cuando se sincronice con clientes Couchbase Lite 2.0. Ya hemos hablado de ello en la sección sobre Replicación. La configuración "allow_conflicts" sólo tiene implicaciones para clientes no 2.0 y clientes REST API. La siguiente tabla resume las implicaciones

allow_conflicts_configuration

Impacto del modo libre de conflictos en el tamaño de las bases de datos

El impacto de la resolución de conflictos en el tamaño de la base de datos se trató en detalle en nuestro anterior post sobre Gestión del tamaño de las bases de datos. En el sistema que permitía conflictos, a medida que crecían las revisiones en conflicto, el tamaño del árbol de revisiones podía crecer hasta afectar al tamaño de la base de datos. Por eso era importante resolver los conflictos a tiempo. Sync Gateway tiene un límite_rev que determina el tamaño del árbol de revisión. La dirección límite_rev tiene un valor predeterminado de 1000, lo que significa que los metadatos correspondientes a las últimas 1000 revisiones se almacenan en Sync Gateway antes de ser eliminados. Al establecer la propiedad límite_rev a un valor grande afectaría negativamente al tamaño de la base de datos, era importante no fijarlo a un valor muy bajo. Era importante mantener los metadatos correspondientes a las revisiones más antiguas, ya que eran necesarios para gestionar la resolución de conflictos; de lo contrario, se corría el riesgo de tener un bosque de árboles de revisiones desconectados para un documento. Así que el valor mínimo permitido de límite_rev es 20.

Sin embargo, con el modo libre de conflictos, no hay necesidad real de guardar los metadatos correspondientes a las revisiones más antiguas. Esto implica que el límite_rev podría ser sólo 1. Esto implica que sólo se almacena la última revisión/activa. Esto supone un gran ahorro en el tamaño de la base de datos.

Agradecimientos

Un agradecimiento especial a Pasin Suriyentrakorn del equipo de ingeniería móvil por sus comentarios sobre las secciones de Couchbase Lite, a Adam Fraser, también del equipo de Ingeniería de Móviles, por sus comentarios sobre las secciones de Sync Gateway y a Daniel Petersen, del equipo de Ingeniería de Móviles, por sus comentarios.

¿Qué sigue?

Esta entrada del blog discute cómo los conflictos se manejan automáticamente en Couchbase Mobile 2.0. Puedes descargar Couchbase Mobile 2.0 desde nuestro descargas página.

Si tiene alguna pregunta o sugerencia, deje un comentario a continuación o póngase en contacto conmigo a través de Twitter en la dirección @rajagp o envíeme un correo electrónico a priya.rajagopal@couchbase.com. En Foros de Couchbase son otro buen lugar para plantear preguntas.

 

Comparte este artículo
Recibe actualizaciones del blog de Couchbase en tu bandeja de entrada
Este campo es obligatorio.

Autor

Publicado por Priya Rajagopal, Directora de Gestión de Productos

Priya Rajagopal es directora sénior de gestión de productos en Couchbase y responsable de las plataformas de desarrollo para la nube y el perímetro. Lleva más de 20 años dedicándose profesionalmente al desarrollo de software en varios puestos de liderazgo técnico y de producto, con más de 10 años centrados en tecnologías móviles. Como delegada de estándares IPTV de TISPAN, fue una colaboradora clave en las especificaciones de estándares IPTV. Tiene 22 patentes en las áreas de redes y seguridad de plataformas.

14 Comentarios

  1. Hola Priya,

    Si Mobile 2.0 introduce el nuevo modo "Conflict Free", ¿cuál es el modo alternativo? Sobre todo porque Gateway sólo admite "Conflict Free" como EE. ¿Cómo se resolverían/no se resolverían los conflictos en la edición comunitaria?

    Usando ConcurrencyControl es posible manejar y resolver conflictos manualmente en Save() en el lado del cliente local. Para los conflictos que resultan de la replicación se dice:
    > El cliente llama a la función de resolución de conflictos
    ¿Dónde está configurada esta función de resolución de conflictos? Beta 2 no tiene el antiguo ConflictResolver en la ReplicatorConfiguration. ¿Se refiere esto a la resolución automática interna, o es algo que puede resolverse manualmente? Si esto es sólo automático, ¿no sería extraño que los conflictos internos de guardado local puedan ser manejados de forma personalizada, pero los conflictos externos replicados no?
    Además, ¿cómo se gestionaría esto de forma diferente cuando no se tiene el modo "Sin conflictos" (EE)?

    Gracias, señor.

  2. ¡Hola!
    En CE, los conflictos en el SGW se gestionarían de la misma manera que en la versión 1.x. Básicamente, no se produciría el error 409 en caso de conflicto.
    Sí, es la resolución interna de conflictos. No se puede anular en la versión 2.0.
    Tienes razón en tu observación de que los conflictos con los guardados locales pueden ser detectados por la aplicación, pero no se puede hacer lo mismo con los conflictos resultantes de la replicación. Pero también hay que tener en cuenta que la política de resolución de conflictos por defecto es diferente en los dos casos - A diferencia del caso de guardado local, en el caso de la replicación, es determinista y pensamos que en la mayoría de los casos, el usuario preferiría un estado determinista.

    El objetivo es estar "libre de conflictos". Por lo tanto, en ambos casos, la resolución de conflictos se produce automáticamente en el momento en que se actualiza el documento (pull local o remoto). Así pues, con este objetivo en mente, a diferencia del caso anterior, en el que podemos rechazar un guardado local, como se puede deducir fácilmente, no se puede hacer lo mismo en una replicación pull.

    Ahora bien, dicho esto, podemos considerar la posibilidad de ofrecer una opción para anular la resolución automática de conflictos. Eso será post 2.0 dependiendo de la demanda de los usuarios. ¿Lo ve necesario?

    1. En la documentación de la versión 2.0 se indica:
      > A partir de Couchbase Lite 2.0, los conflictos de documentos deben ser resueltos usando la resolución automática de conflictos o en la aplicación.
      Entonces, si el CE debe utilizar el método v1.x en su lugar, ¿esto no es cierto?

      Todos los elementos utilizados en la v1.x para gestionar revisiones y conflictos, como los solucionadores de conflictos, la clase Revision del documento, etc. parecen haber sido eliminados de la API de la 2.x. Entonces, si la CE 2.x debe utilizar el método de la v1.x, ¿cómo? Todo parece haber sido diseñado únicamente para el nuevo método automático. El CE Gateway seguiría teniendo múltiples revisiones para los documentos en estado de conflicto, hasta que se resuelvan en algún sitio. Por lo tanto, los clientes deben poder ver qué documentos se encuentran en estado de conflicto y qué revisiones existen.

      Veo la necesidad de anular la resolución automática de conflictos, ya que permite anularla en el método save() del cliente. Claro, si usted emplea replicación continua, entonces los conflictos son más probables que ocurran al guardar, ya que los cambios son replicados instantáneamente (con suerte). Pero si usted está trabajando principalmente fuera de línea, y sólo ocasionalmente replicando, entonces los conflictos van a ocurrir principalmente cuando se replica, no en save(). En ese escenario, tener las capacidades avanzadas de fusión personalizada en save() es mucho menos útil, y usted estaría 'atascado' con sólo el valor por defecto del árbol de revisión más largo. Me parece que si quieres manejar el conflicto en save(), también querrías tener la capacidad de manejar el conflicto de la replicación de la misma manera.

      Claro que el problema técnico es diferente, ya que no se puede 'rechazar' el pull. En la v1.x esto se resolvía teniendo las múltiples revisiones en estado de conflicto, y luego resolviéndolo. Creo que todavía querría tener esta opción en v2.x de alguna manera. No creo que el desafío técnico de implementar esto debería ser la razón para paralizar la funcionalidad en comparación con v1.x, y en comparación con las capacidades de save().

  3. El tercer panel del primer diagrama (en "Conflictos en Couchbase Lite") presenta la leyenda: "La aplicación intenta guardar una versión modificada localmente del documento. El documento no está en conflicto".

    La ilustración parece representar claramente un conflicto. ¿Hay algún error en el pie de foto?

  4. En relación con el comentario anterior de avia_bdg, me gustaría recibir alguna aclaración sobre la estrategia de resolución de conflictos en relación con la replicación. Por mi lectura del artículo y el diálogo anterior, suena como si el diseño actual de CBL 2.0 prácticamente garantiza la pérdida de datos por los clientes fuera de línea que utilizan Sync Gateway. Esto haría que el producto completamente inutilizable.

    Sin un medio para poder resolver de forma determinista los conflictos que resultan de una replicación pull, el cliente tira los dados sobre si sus cambios serán desechados. Las fusiones -un requisito fundamental en muchas aplicaciones, incluido mi proyecto principal, donde actualmente utilizamos CBL 1.x- ya no son posibles. Eso es un obstáculo.

    Por favor, asegúrame que lo he entendido mal.

    1. Gracias por sus comentarios. Su comprensión es correcta. Evaluaremos la posibilidad de incorporar esta...

  5. Muy buenas preguntas.
    La más sencilla primero - Evaluaremos la opción de anular la política personalizada de resolución de conflictos en la replicación - pero eso sería post 2.0.
    Ahora la otra pregunta -
    Para aclarar, los clientes de Couchbase Lite 2.0 siempre usarán el modo libre de conflictos (CE o EE). La distinción entre CE y EE está en el lado SGW.
    Para los detalles sangrientos -
    Para aclarar la distinción en el lado del SGW, los push de los clientes 2.0 siempre estarán en modo "libre de conflictos". La implicación de esto - sin entrar en demasiados detalles sobre el protocolo es que el SGW (EE y CE) rechazará la revisión si causa un conflicto (como se discute en la entrada del blog). La distinción entre CE y EE se produce cuando las actualizaciones proceden de clientes que no son de CBL 2.0 o de la API REST. EE SGW evitará los conflictos de cualquiera de estos clientes. Pero usted puede tener conflictos en el modo SGW CE cuando se interactúa con los clientes no CBL 2.0 . Esos conflictos serán manejados por 1.x de la forma habitual y los clientes CBL 2.0 sacarán la revisión ganadora del servidor.

    1. Por suerte, no creo que tengamos este problema de mezcla 1.x/2.x, así que entonces no habrá problema con CE.

      Creo que Ben y yo estamos bastante de acuerdo en que necesitamos alguna forma de resolver de forma personalizada los conflictos resultantes de las réplicas pull.

      Estamos aplicando CBL en Xamarin mobile, en dispositivos que estarán offline en entornos con poca disponibilidad de internet y replicación one-shot ocasionalmente. Dado que se trata de una aplicación móvil que estamos buscando tener una función de autoguardado para nuestro formulario de datos - en caso de que el usuario suspende la aplicación y se cierra, quiere hacer ediciones parciales,... Esto significa potencialmente una alta tasa de revisiones, que se almacena localmente sólo hasta que se empujan. Hice algunas pruebas, y esto significa que si edito con autosave 2 o 3 veces, una sola edición hecha offline en otro dispositivo hecha en una fecha posterior perderá porque existen menos revisiones. Esto no es aceptable. La última edición (por fecha y hora) sería mejor, código personalizado para hacer alguna fusión sería aún mejor, el número de ediciones (el actual algoritmo de resolución automática) no está bien para esto.

      Incluso si cambiamos de autoguardado instantáneo a menos guardados o guardados manuales, el problema persiste: el algoritmo de resolución automática de conflictos sólo va a funcionar para escenarios online, y no va a ser aceptable para escenarios offline, donde los clientes pueden estar desconectados durante tiempos más cortos o más largos (semanas o meses), y hacer muchas ediciones mientras están desconectados, o hacer ediciones en diferentes proporciones y cantidades de otros clientes desconectados, y las ediciones antiguas más numerosas pueden desechar menos ediciones nuevas.

      1. Gracias por los detalles. Sus comentarios son muy útiles. Seguiremos evaluando esta cuestión... le mantendremos informado.

      2. Actualización rápida : He eliminado la nota sobre CE/ EE ....I añadido una nueva sección sobre la configuración SGW para aclarar lo mismo. No hay distinción a nivel CE/EE.

  6. Hola, equipo,

    Actualmente he actualizado mi couchlite a 2.1.2.
    Para resolver los conflictos debo obtener la última revisión del servidor, cómo puedo obtener el documento específico de la revisión.En la última versión no obtenemos el Id de revisión.Cómo podemos conseguir resolver los conflictos a nivel de aplicación.

    1. No se pueden resolver conflictos a nivel de aplicación, al menos no todavía. Couchbase cambió a la resolución automática de conflictos en la versión 2. Están trabajando en una solución que permita de nuevo cierto control.

      1. La resolución de conflictos personalizada con fusión bidireccional ya está disponible con Couchbase Mobile 2.6 (https://docs.couchbase.com/couchbase-lite/2.6/index.html#custom-conflict-resolution)

Deja un comentario

¿Listo para empezar con Couchbase Capella?

Empezar a construir

Consulte nuestro portal para desarrolladores para explorar NoSQL, buscar recursos y empezar con tutoriales.

Utilizar Capella gratis

Ponte manos a la obra con Couchbase en unos pocos clics. Capella DBaaS es la forma más fácil y rápida de empezar.

Póngase en contacto

¿Quieres saber más sobre las ofertas de Couchbase? Permítanos ayudarle.