/ HOWTO

Cockroach DB Cluster en Docker.

Hey! ¿Te interesa un curso Online de Docker?

Hoy vamos a poner en marcha un Cluster de 3 nodos “CockroachDB”, lo usaremos para un trabajo con 3k millones de registros a procesar.

Luego de leer muchos documentos sobre CockRoachDB (Cucaracha DB), quizás el peor nombre para un producto, los puntos mas importantes son, es un gestor de grandes volúmenes de datos, permite interactuar usando “SQL” como lenguaje, está pensado para trabajar en modo Cloud, distribuido, trabaja en modo ACID, es redundante, tiene características de NOSQL, tiene integridad de datos, soporta Lectura y Escritura en todos sus nodos, rebalanceo de carga, replicación y tolerancia a fallos. Y además un monitor GUI web del entorno.

En nuestro caso lo usaremos porque buscamos un Motor SQL que permita manejar unos cuantos GB, soporte ACID, R/W distribuido y además que admita decenas de servidores corriendo, paralelismo simple.

Nos bajamos la imágen oficial recomendada.

# docker pull cockroachdb/cockroach:v1.1.2
v1.1.2: Pulling from cockroachdb/cockroach
85b1f47fba49: Already exists
ac7a38ccd774: Pull complete
37265804308e: Pull complete
ec56dc0c7331: Pull complete
Digest: sha256:5cce677eeec382a504176ce4154cc8d2f922f2bc2fdf49547766eae5798944ab
Status: Downloaded newer image for cockroachdb/cockroach:v1.1.2

La imágen descargada es de 178 MB.

# docker images
REPOSITORY                     TAG                 IMAGE ID            CREATED             SIZE
cockroachdb/cockroach          v1.1.2              9e7b5a0bf574        3 weeks ago         178MB

Cockroach es un único EXE/APP de 46 mb., que corre como servidor de un cluster y además trae incluida un cliente SQL, mas que simple. Si lo desean correr en un servidor Real, basta con descargar un programa y colocarlo en una carpeta de “/bin”.

Oficialmente recomiendan crear una red exclusiva para esos servidores.

# docker network create -d bridge roachnet
# docker network list
NETWORK ID          NAME                DRIVER              SCOPE
7b48223de1e2        bridge              bridge              local
0941f81fdd9d        host                host                local
8a1d0746aac2        none                null                local
380b753463ec        roachnet            bridge              local

Aunque no es lo recomendado para instalaciones profesionales y productivas, existe un modo de configuración llamado “inseguro”, donde las comunicaciones entre los nodos se realiza “SIN” utilizar certificados y encriptación, al tenerlo en una red aislada y sin datos sensibles, usaremos esa opción (inseguro). Admite conexiones a todos los nodos desde cualquier cliente. No necesita cuentas y permisos para acceder a cada base de datos.

Crearemos 3 carpetas en nuestro equipo real, que contendrán los datos de cada nodo (99% iguales entre si).

# mkdir /home/dac/Downloads/croack/n1
# mkdir /home/dac/Downloads/croack/n2
# mkdir /home/dac/Downloads/croack/n3

Corremos el primer nodo (n1), usando la red creada “roachnet”, habilitando los puertos 26257 que usa el propio motor para replicar datos y el puerto 8080 para el acceso al cliente GUI WEB., mapeamos nuestro volúmen recién creado a la carpeta de datos del Contenedor y arrancamos el contenedor con el “insecure”.

# docker run -d --name=n1 --hostname=n1 --net=roachnet -p 26257:26257 -p 8080:8080 \
-v "/home/dac/Downloads/croack/n1:/cockroach/cockroach-data"  cockroachdb/cockroach:v1.1.2 start --insecure

Existen otros parámetros para anunciar nuestro cluster en la red local con un nombre distinto

--advertise-host
en caso de no usarlo, el nombre del nodo 1 será el publicado.

Podemos indicar el límite de RAM asignada al motor.

--attrs=ram:64gb

Para utilizar un certificado y trabajar de una manera mas segura, debemos usar el parámetro

--certs-dir

Podemos indicar donde queremos guardar los “logs” del motor.

--log-dir

Un parámetro importante para servidores productivos es el límite de uso de recursos. Deberemos indicar donde almacenar los datos locales (ssd01) y además que balancée el contenido cuando alcance los 20GB de almacenamiento.

--store=path=/mnt/ssd01,size=20GB

Ya tenemos corriendo nuestro primer nodo (n1)

# docker ps
CONTAINER ID        IMAGE                          COMMAND                  CREATED             STATUS              PORTS                                              NAMES
6988c438f036        cockroachdb/cockroach:v1.1.2   "/cockroach/cockro..."   6 seconds ago       Up 4 seconds        0.0.0.0:8080->8080/tcp, 0.0.0.0:26257->26257/tcp   n1

Como habíamos creado una red aparte para este cluster, podemos acceder mediante un I.Browser con

[LINK] ( http://172.18.0.2:8080/#/cluster/all/overview )

GRAFICO1: co1

Además verificaremos desde nuestro equipo real, que el motor del N1 está funcionando correctamente y nos comunicaremos con el motor usando lenguaje “SQL”. También aquí debemos indicar que usaremos el modo inseguro, para poder conectarnos al motor.

Como cochroach es un servidor que también funciona como cliente “SQL”, también podríamos usar cualquiera de los nodos que forman parte del cluster.

# cockroach sql --insecure

# Welcome to the cockroach SQL interface.
# All statements must be terminated by a semicolon.
# To exit: CTRL + D.
#
# Server version: CockroachDB CCL v1.1.2 (linux amd64, built 2017/11/02 19:32:03, go1.8.3) (same version as client)
# Cluster ID: b83c5b38-46c6-4584-aaea-2a5eb48f3abe
#
# Enter \? for a brief introduction.
#
root@:26257/> \q

Vamos a arrancar dos nodos mas

# docker run -d --name=n2 --hostname=n2 --net=roachnet -v "/home/dac/Downloads/croack/n2:/cockroach/cockroach-data" \
cockroachdb/cockroach:v1.1.2 start --insecure --join=n1

# docker run -d --name=n3 --hostname=n3 --net=roachnet -v "/home/dac/Downloads/croack/n3:/cockroach/cockroach-data" \
cockroachdb/cockroach:v1.1.2 start --insecure --join=n1

Ya tenemos funcionando nuestro cluster de tres nodos. Nos podemos conectar mediante un Browser a cualquier de los 3 nodos, todos nos brindarán “info” del cluster.

El Nodo N1 fue el primero y los nodos N2 y N3 se unieron a él.

# docker ps
CONTAINER ID        IMAGE                          COMMAND                  CREATED              STATUS              PORTS                                              NAMES
65ffc9cafee6        cockroachdb/cockroach:v1.1.2   "/cockroach/cockro..."   About a minute ago   Up About a minute   8080/tcp, 26257/tcp                                n3
7158cab54dfe        cockroachdb/cockroach:v1.1.2   "/cockroach/cockro..."   About a minute ago   Up About a minute   8080/tcp, 26257/tcp                                n2
6988c438f036        cockroachdb/cockroach:v1.1.2   "/cockroach/cockro..."   16 minutes ago       Up 16 minutes       0.0.0.0:8080->8080/tcp, 0.0.0.0:26257->26257/tcp   n1

GRAFICO1: co2

Podemos ver las opciones del cluster que hemos creado con

# cockroach sql --insecure
root@:26257/> SHOW ALL CLUSTER SETTINGS;

Luego de usarlo unas cuantas horas, tiene una gestión muy simple (como si fuera un MySQL), unos cuantos comandos muy útiles y una belleza espartana, hace lo que tiene que hacer y lo hace sin demasiada retórica.

Recomendamos el comando “\h” que nos dará la lista de comandos que soporte el modo cliente.

Verificamos que funcione el modo transaccional.

root@:26257/> begin;
Now adding input for a multi-line SQL transaction client-side.
Press Enter two times to send the SQL text collected so far to the server, or Ctrl+C to cancel.
You can also use \show to display the statements entered so far.
           -> commit;
COMMIT
Time: 1.219193ms

Es posible conectarse a cualquiera de los nodos y meter datos en una base de datos. Aunque haremos un “helloworld” SQL de manual. Unos milisegundos despues los datos ya están disponibles en los otros dos nodos. Simple, rápido y eficaz.

# cockroach sql --insecure
root@:26257/> create database dockertips;
CREATE DATABASE
Time: 138.48393ms

root@:26257/> use dockertips;
SET
Time: 2.539979ms

root@:26257/dockertips> create table test(ID int, c2 varchar(50));
CREATE TABLE
Time: 157.391032ms

root@:26257/dockertips> insert into test values (1, 'abc');
INSERT 1
Time: 129.870051ms

root@:26257/dockertips> select * from test;
+----+-----+
| id | c2  |
+----+-----+
|  1 | abc |
+----+-----+
(1 row)
Time: 4.374242ms

Verificamos nuestras carpetas del servidor real.

# ll
total 51440
6168277 drwxr-xr-x 5 root root     4096 nov 26 18:00 .
6042225 drwxr-xr-x 5 root root     4096 nov 26 17:55 ..
6168352 -rw-r--r-- 1 root root 52612934 nov 26 18:32 000003.log
6168347 drwxr-xr-x 2 root root     4096 nov 26 18:00 auxiliary
6168355 -rw-r--r-- 1 root root        8 nov 26 18:00 cockroach.advertise-addr
6168354 -rw-r--r-- 1 root root       13 nov 26 18:00 COCKROACHDB_VERSION
6168356 -rw-r--r-- 1 root root        7 nov 26 18:00 cockroach.http-addr
6168357 -rw-r--r-- 1 root root        8 nov 26 18:00 cockroach.listen-addr
6168350 -rw-r--r-- 1 root root       16 nov 26 18:00 CURRENT
6168351 -rw-r--r-- 1 root root       37 nov 26 18:00 IDENTITY
6168336 drwxr-xr-x 3 root root     4096 nov 26 18:00 local
6168348 -rw-r--r-- 1 root root        0 nov 26 18:00 LOCK
6168333 drwxr-xr-x 2 root root     4096 nov 26 18:00 logs
6168349 -rw-r--r-- 1 root root       13 nov 26 18:00 MANIFEST-000001
6168353 -rw-r--r-- 1 root root     4241 nov 26 18:00 OPTIONS-000005

ll ../n2
total 41480
6168278 drwxr-xr-x 5 root root     4096 nov 26 18:15 .
6042225 drwxr-xr-x 5 root root     4096 nov 26 17:55 ..
6168379 -rw-r--r-- 1 root root 42412045 nov 26 18:32 000003.log
6168370 drwxr-xr-x 2 root root     4096 nov 26 18:15 auxiliary
6168384 -rw-r--r-- 1 root root        8 nov 26 18:15 cockroach.advertise-addr
6168382 -rw-r--r-- 1 root root       13 nov 26 18:15 COCKROACHDB_VERSION
6168386 -rw-r--r-- 1 root root        7 nov 26 18:15 cockroach.http-addr
6168388 -rw-r--r-- 1 root root        8 nov 26 18:15 cockroach.listen-addr
6168375 -rw-r--r-- 1 root root       16 nov 26 18:15 CURRENT
6168378 -rw-r--r-- 1 root root       37 nov 26 18:15 IDENTITY
6168361 drwxr-xr-x 3 root root     4096 nov 26 18:15 local
6168371 -rw-r--r-- 1 root root        0 nov 26 18:15 LOCK
6168358 drwxr-xr-x 2 root root     4096 nov 26 18:15 logs
6168373 -rw-r--r-- 1 root root       13 nov 26 18:15 MANIFEST-000001
6168381 -rw-r--r-- 1 root root     4241 nov 26 18:15 OPTIONS-000005

ll ../n3
total 42000
6168279 drwxr-xr-x 5 root root     4096 nov 26 18:15 .
6042225 drwxr-xr-x 5 root root     4096 nov 26 17:55 ..
6168411 -rw-r--r-- 1 root root 42945741 nov 26 18:33 000003.log
6168406 drwxr-xr-x 2 root root     4096 nov 26 18:15 auxiliary
6168415 -rw-r--r-- 1 root root        8 nov 26 18:15 cockroach.advertise-addr
6168413 -rw-r--r-- 1 root root       13 nov 26 18:15 COCKROACHDB_VERSION
6168416 -rw-r--r-- 1 root root        7 nov 26 18:15 cockroach.http-addr
6168414 -rw-r--r-- 1 root root        8 nov 26 18:15 cockroach.listen-addr
6168409 -rw-r--r-- 1 root root       16 nov 26 18:15 CURRENT
6168410 -rw-r--r-- 1 root root       37 nov 26 18:15 IDENTITY
6168392 drwxr-xr-x 3 root root     4096 nov 26 18:15 local
6168407 -rw-r--r-- 1 root root        0 nov 26 18:15 LOCK
6168389 drwxr-xr-x 2 root root     4096 nov 26 18:15 logs
6168408 -rw-r--r-- 1 root root       13 nov 26 18:15 MANIFEST-000001
6168412 -rw-r--r-- 1 root root     4241 nov 26 18:15 OPTIONS-000005

Paramos y arrancamos los 3 nodos.

# docker stop n3
# docker stop n2
# docker stop n1

# docker start n1
# docker start n2
# docker start n3

Verificamos que todo está corriendo nuevamente.

# docker ps
CONTAINER ID        IMAGE                          COMMAND                  CREATED             STATUS              PORTS                                              NAMES
65ffc9cafee6        cockroachdb/cockroach:v1.1.2   "/cockroach/cockro..."   19 minutes ago      Up 1 second         8080/tcp, 26257/tcp                                n3
7158cab54dfe        cockroachdb/cockroach:v1.1.2   "/cockroach/cockro..."   19 minutes ago      Up 2 seconds        8080/tcp, 26257/tcp                                n2
6988c438f036        cockroachdb/cockroach:v1.1.2   "/cockroach/cockro..."   33 minutes ago      Up 3 seconds        0.0.0.0:8080->8080/tcp, 0.0.0.0:26257->26257/tcp   n1

Ahora nos conectaremos y verificamos los datos que habíamos guardado en nuestra base de datos de pruebas “dockertips” y en la tabla “test”.

# cockroach sql --insecure

# Welcome to the cockroach SQL interface.
# All statements must be terminated by a semicolon.
# To exit: CTRL + D.
#
# Server version: CockroachDB CCL v1.1.2 (linux amd64, built 2017/11/02 19:32:03, go1.8.3) (same version as client)
# Cluster ID: b83c5b38-46c6-4584-aaea-2a5eb48f3abe
#
# Enter \? for a brief introduction.
#
root@:26257/> show databases;
+--------------------+
|      Database      |
+--------------------+
| crdb_internal      |
| dockertips         |
| information_schema |
| pg_catalog         |
| system             |
+--------------------+
(5 rows)
Time: 4.024125ms

root@:26257/> use dockertips;
SET
Time: 5.233126ms

root@:26257/dockertips> select * from test;
+----+-----+
| id | c2  |
+----+-----+
|  1 | abc |
+----+-----+
(1 row)
Time: 410.23127ms

Para interactuar contra el motor, usaremos bash (aunque tiene clientes para varios lenguajes de programación).

# echo "use dockertips;select * from test;" | cockroach sql --insecure
id	c2
1	abc
# 1 row

Para entender el formato de Backups/restore, hacemos un backup de la base “dockertips”

# cockroach dump --insecure dockertips
#
 Server version: CockroachDB CCL v1.1.2 (linux amd64, built 2017/11/02 19:32:03, go1.8.3) (same version as client)
# Cluster ID: b83c5b38-46c6-4584-aaea-2a5eb48f3abe
CREATE TABLE test (
	id INT NULL,
	c2 STRING(50) NULL,
	FAMILY "primary" (id, c2, rowid)
);

INSERT INTO test (id, c2) VALUES
	(1, 'abc');

Encontramos un post sobre como adaptar “Dumps” de MySQL para importarlos en cockroach, aunque requirió un trabajo manual de adaptación del archivo a importar, muchas opciones se quitaron y nos quedamos con instrucciones SQL simples.

[LINK2] ( https://github.com/cockroachdb/cockroach/issues/10291 )

También probamos el “pgloader”.

[LINK3] ( http://pgloader.io/howto/mysql.html )

Ya tenemos todo listo para nuestra carga masiva de datos. Estimamos que serán unos 30 gb de datos en disco.

Dos maneras de subir un fichero SQL a cockroach

# echo "<sql statement>;<sql statement>" | cockroach sql <flags>
# cockroach sql <flags> < file-containing-statements.sql

Podemos monitorizar que pasa con los nodos del cluster.

CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT     MEM %               NET I/O             BLOCK I/O           PIDS
65ffc9cafee6        n3                  38.95%              162.8MiB / 7.685GiB   2.07%               40.8MB / 105MB      182MB / 282MB       53
7158cab54dfe        n2                  1.00%               127.8MiB / 7.685GiB   1.62%               38.9MB / 22.2MB     183MB / 282MB       18
6988c438f036        n1                  3.79%               127.1MiB / 7.685GiB   1.61%               98.1MB / 49MB       227MB / 282MB       18

Subscríbete y recibirás los últimos artículos semanalmente en tu email.