En este post, voy a echar un vistazo a una aplicación de ejemplo que utiliza la función Servidor Couchbase Cliente Java Multi-Cluster Aware (MCA). Este cliente va de la mano con Couchbase's Cross-Data Center Replication (XDCR).
XDCR soporta la replicación flexible de datos entre diferentes clusters. XDCR es una característica importante para despliegues de centros de datos múltiples a gran escala. Las referencias a continuación incluyen varias sobre XDCR. El cliente MCA puede redirigir automáticamente el tráfico a estos clústeres separados basándose en la configuración de la biblioteca, liberando al desarrollador de la aplicación de la gestión de gran parte de la complejidad implicada.
Éstas y otras características permiten que las implantaciones de Couchbase admitan una serie de fuertes alta disponibilidad y estrategias de recuperación en caso de catástrofe. Para saber más antes de profundizar en los detalles de los clientes, eche un vistazo a estos recursos:
Introducción a Couchbase HA/DR - Documentación sobre alta disponibilidad y recuperación tras catástrofes
Couchbase XDCR - Documentación XDCR
Seminario web XDCR/MCA (incluye demostración técnica) - Seminario web HA/DR
Tutorial del seminario web - Configuración de clusters paso a paso, con XDCR
Una mirada más profunda a XDCR - Profundización en la replicación entre centros de datos (XDCR) por Denis Rosa
Configuración de XDCR mediante Docker - Replicar datos NoSQL entre centros de datos con Couchbase XDCR por Nick Raboy
Vídeo corto sobre la configuración de XDCR utilizando Docker - Usar XDCR para replicar datos NoSQL entre contenedores Couchbase Docker - Video Tutorial por Nick Raboy
Detalles del cliente de MCA en breve
El MCA Java SDK se basa en el estándar SDK Java de Couchbase. La API básica imita en gran medida la del cliente estándar.
- La posibilidad de priorizar una lista de agrupaciones.
- Formas de proporcionar normas sobre lo que constituye un fracaso.
- API para coordinar las instancias cliente.
- Una interfaz de gestión.
Discutiremos los dos primeros utilizando el ejemplo de código. La gestión se realiza mediante programación o a través de una interfaz JMX. Esto permite a los administradores cambiar de clúster en la lista de prioridades. Queda fuera del alcance de este artículo.
La aplicación de ejemplo
Para ilustrar el uso del cliente MCA, tenemos una aplicación de ejemplo sencilla. La aplicación ejecuta un número configurable de hilos en grupos. Un grupo simplemente lee de la base de datos, otro escribe nuevos registros aleatorios, otro lee documentos, los modifica y luego los vuelve a escribir, y otro realiza un sencillo N1QL consulta. La idea es proporcionar una variedad de cargas para aplicar contra un clúster. En este seminarioHemos utilizado esta aplicación para ilustrar un comportamiento sencillo de conmutación por error entre clústeres.
Puedes encontrar el código completo, junto con las instrucciones de construcción y otros materiales en GitHub. A continuación se muestra un ejemplo de invocación ejecutada contra dos clusters de 3 nodos con 10 hilos actualizando documentos.
1 |
java -tarro mca-1.0.jar -c 172.23.123.4,172.23.123.5,172.23.123.6:172.23.122.55,172.23.122.56,172.23.122.57 -b mi_cubo -i usuario -p contraseña -u 10 -l estadísticas |
Ahora, repasemos las partes principales del código.
Guía de códigos
El código de la aplicación, en este caso, consiste en una clase principal y algunas clases simples de ayuda. Una vez que tenemos la instancia del cliente MCA, se utiliza casi exactamente igual que el cliente normal. Me centraré, entonces, en la configuración del cliente. El código proviene de la clase ClusterBasics clase.
Nodos de clúster y agrupaciones
Los clusters se especifican en la línea de comandos como grupos de nodos separados por dos puntos (:
). Dentro de cada grupo, los nombres de los nodos o las direcciones IP están separados por comas. Implícitamente, los clusters se especifican por orden de prioridad. Este bloque de código descompone ese formato simple en conjuntos y crea una especificación de clúster para cada clúster. (Una especificación de cluster puede incluir un id para facilitar la referencia. No era necesario aquí, pero vale la pena señalarlo).
1 2 3 4 5 6 7 8 |
Cadena[] racimos = opciones.stringValueOf("racimos").dividir(":"); Lista<ClusterSpec> especificaciones = nuevo ArrayList<>(racimos.longitud); para (Cadena grupo: racimos) { Establecer<String> nodos = Matrices.flujo(grupo.dividir(",")).recoja(Coleccionistas.toSet()); especificaciones.añada(ClusterSpec.crear(nodos)); } |
Tipos de servicio Couchbase
Hablaremos de la coordinación y la monitorización de fallos en un momento. Puedes ajustar ambos por tipo de servicio. En este ejemplo, estamos utilizando la recuperación directa de clave/valor (TipoServicio.BINARY
) y las consultas N1QL (TipoServicio.QUERY
). Estas dos líneas siguientes preparan un conjunto de tipos de servicio para su uso posterior.
1 2 |
tipos de servicio.añada(Tipo de servicio.BINARIO); tipos de servicio.añada(Tipo de servicio.CONSULTA); |
Coordinación entre clientes
A continuación empezamos a ver la verdadera diferencia de capacidades de este cliente. Coordinadores
gestionar la orquestación del comportamiento a través de instancias cliente. Actualmente, sólo se han implementado coordinadores aislados, pero eso es apropiado para este caso de todos modos. Otros más sofisticados están previstos para el futuro. Aún así, mirando todas las opciones, puedes ver que incluso un coordinador aislado permite bastante control. He aquí cómo crear uno con algunas opciones no predeterminadas.
1 2 3 4 5 6 7 8 |
Coordinador coordinador = Coordinadores.aislado(nuevo CoordinadorAislado.Opciones() .clusterSpecs(especificaciones) .activeEntries(especificaciones.talla()) .failoverNumNodes(2) .gracePeriod(TIEMPO DE ESPERA) .topologyBehavior(TopologyBehavior.WRAP_AT_END) .tipos de servicio(tipos de servicio) ); |
Notas de código (por número de línea):
- Crear un
CoordinadorAislado
con las opciones configuradas - Especifique los nodos para cada miembro de esta topología
- Establece el número de clusters que se considerarán activos
- Establece el número de nodos individuales que fallan antes de que todo el clúster falle por completo.
- Período de gracia tras el fallo antes de la conmutación del clúster
- Selecciona el comportamiento cuando se alcanza el final de una topología. Las alternativas incluyen permanecer en el cluster final, o retroceder a través de la lista. La mejor opción dependerá de su escenario específico.
- Asignar los servicios gobernados
Detección de fallos
El cliente puede monitorizar bastante información mientras funciona. Los detectores de fallos hacen uso de esta riqueza de información que ocurre bajo el capó. La utilizan para enviar una señal al coordinador. El coordinador puede entonces decidir cómo responder.
A TrafficMonitoringFailureDetector
observa las peticiones enviadas al servidor. Puedes configurar los tipos de errores (excepciones) a contar, el número umbral de excepciones, el intervalo de tiempo en el que deben ocurrir y más. Yo suelo usar los valores por defecto y sólo ajusto el recuento de operaciones fallidas y el intervalo.
El cliente también tiene visibilidad de lo que ocurre con los nodos y el clúster directamente. Esto se captura utilizando un NodeHealthFailureDetector
. Hay algunos matices que es mejor dejar para la documentación. Aquí sólo utilizo los valores predeterminados.
Por último, puede construir combinaciones de condiciones complejas utilizando ConjunctionFailureDetector
y DisjunctionFailureDetector
. Piense que los detectores de conjunción realizan una "y" lógica de los detectores constituyentes. La disyunción realiza una "o". Quiero que se dispare ante cualquier fallo, así que conecto mi monitorización del tráfico y de la salud a un DisjunctionFailureDetector
para obtener el objeto detector final que se entregará al cliente.
1 2 3 4 5 6 7 8 9 10 11 |
TrafficMonitoringFailureDetector.Opciones trafficOptions = TrafficMonitoringFailureDetector.opciones() .maxFailedOperations(5) .failureInterval(60); FailureDetectorFactory<TrafficMonitoringFailureDetector> tráfico = FailureDetectorFactories.vigilancia del tráfico(coordinador, trafficOptions); NodeHealthFailureDetector.Opciones healthOptions = NodeHealthFailureDetector.opciones(); FailureDetectorFactory<NodeHealthFailureDetector> salud = FailureDetectorFactories.nodeHealth(coordinador, healthOptions); DisjunctionFailureDetectorFactory detector = FailureDetectorFactories.disyunción(tráfico, salud); |
Notas de código (por número de línea):
- Instanciar y configurar el
TrafficMonitoringFailureDetector
opciones - Fijar el número de operaciones fallidas necesarias para indicar un problema
- Establezca el intervalo de tiempo en el que se almacenarán los fallos.
- Crear un
TrafficMonitoringFailureDetector
con acceso a la base de datosCoordinador
y nuestras opciones - Crear un
NodeHealthFailureDetector
con opciones por defecto - Define la lógica final utilizando un
DisjunctionFailureDetector
de nuevo a través de una fábrica
Instanciación del cliente
Finalmente, instanciamos un cliente, y lo usamos para obtener una instancia de bucket. Para aquellos que no estén familiarizados con Couchbase, los buckets son una abstracción organizativa de alto nivel. Puedes pensar en ellos como algo intermedio entre una tabla y una base de datos completa.
El manejador del bucket es todo lo que necesitamos para ejecutar las cargas contra nuestros clusters. Un cliente bucket multi-cluster te permite especificar tiempos de espera para operaciones individuales. Para simplificar, he envuelto la interfaz en una fachada, aplicando sólo un tiempo de espera fijo a cada operación. Esto hace que la interfaz sea idéntica a la estándar.
1 2 3 4 |
MultiClusterClient cliente = nuevo MultiClusterClient(coordinador, detector); cliente.autentifique(opciones.stringValueOf("id"), opciones.stringValueOf("contraseña")); cubo = nuevo CuboFachada(cliente.openBucket(bucketName, null), TIEMPO DE ESPERA, Unidad de tiempo.MILLISEGUNDOS); |
Conclusión
Eso es todo para los nuevos conceptos necesarios para arrancar con el cliente MCA. El resto del código analiza las opciones, configura los hilos solicitados y los ejecuta en bucles. Hay algunas estadísticas. Hago llamadas para obtener los datos aleatorios para escribir y actualizar documentos, por lo que este código no está optimizado para conducir la carga. Sin embargo, puede dar una idea del rendimiento que ofrece Couchbase.
De nuevo, para ver todo esto en acción, junto con cómo se comportan los clusters, echa un vistazo a la demostración durante la segunda mitad de este seminario.
Recientemente se ha publicado la versión 1.0 del cliente MCA. En el momento de redactar este artículo, se trata de una función exclusiva de la edición Enterprise. Para obtener más información y acceso al cliente, habla con un representante de ventas de Couchbase (sales@couchbase.com). También puede ponerse en contacto conmigo para obtener más información, como se describe a continuación.