Cuando trabaja en un proyecto que consta de muchos microservicios, es probable que también incluya varias bases de datos.
Por ejemplo, puede tener una base de datos MySQL y una base de datos PostgreSQL, ambas ejecutándose en servidores separados.
Por lo general, para unir los datos de las dos bases de datos, tendría que introducir un nuevo microservicio que uniría los datos. Pero esto aumentaría la complejidad del sistema.
En este tutorial, usaremos Materialise para unir MySQL y Postgres en una vista materializada en vivo. Entonces podremos consultar eso directamente y obtener resultados de ambas bases de datos en tiempo real usando SQL estándar.
Materialise es una base de datos de transmisión disponible en la fuente escrita en Rust que mantiene los resultados de una consulta SQL (una vista materializada) en la memoria a medida que cambian los datos.
El tutorial incluye un proyecto de demostración que puede comenzar a usar docker-compose
.
El proyecto de demostración que vamos a utilizar monitoreará los pedidos en nuestro sitio web simulado. Generará eventos que, más adelante, podrían usarse para enviar notificaciones cuando un carrito haya estado abandonado durante mucho tiempo.
La arquitectura del proyecto de demostración es la siguiente:
Requisitos
Todos los servicios que usaremos en la demostración se ejecutarán dentro de los contenedores de Docker, de esa manera no tendrá que instalar ningún servicio adicional en su computadora portátil o servidor en lugar de Docker y Docker Compose.
En caso de que no tenga Docker y Docker Compose ya instalados, puede seguir las instrucciones oficiales sobre cómo hacerlo aquí:
- Instalar Docker
- Instalar Docker Compose
Resumen
Como se muestra en el diagrama anterior, tendremos los siguientes componentes:
- Un servicio simulado para generar pedidos continuamente.
- Los pedidos se almacenarán en una base de datos MySQL .
- A medida que se producen las escrituras en la base de datos, Debezium transmite los cambios de MySQL a un Redpanda tema.
- También tendremos un Postgres base de datos donde podemos obtener nuestros usuarios.
- Luego ingeriremos este tema de Redpanda en Materialise directamente junto con los usuarios de la base de datos de Postgres.
- En Materialise uniremos nuestros pedidos y usuarios, filtraremos y crearemos una vista materializada que muestre la información del carrito abandonado.
- Entonces crearemos un sumidero para enviar los datos del carrito abandonado a un nuevo tema de Redpanda.
- Al final usaremos Metabase para visualizar los datos.
- Más adelante, podría usar la información de ese nuevo tema para enviar notificaciones a sus usuarios y recordarles que tienen un carrito abandonado.
Como nota al margen aquí, estaría perfectamente bien usando Kafka en lugar de Redpanda. Simplemente me gusta la simplicidad que aporta Redpanda, ya que puede ejecutar una sola instancia de Redpanda en lugar de todos los componentes de Kafka.
Cómo ejecutar la demostración
Primero, comience clonando el repositorio:
git clone https://github.com/bobbyiliev/materialize-tutorials.git
Después de eso, puede acceder al directorio:
cd materialize-tutorials/mz-join-mysql-and-postgresql
Empecemos ejecutando primero el contenedor de Redpanda:
docker-compose up -d redpanda
Construye las imágenes:
docker-compose build
Finalmente, inicie todos los servicios:
docker-compose up -d
Para iniciar la CLI de Materialise, puede ejecutar el siguiente comando:
docker-compose run mzcli
Este es solo un acceso directo a un contenedor Docker con postgres-client
pre instalado. Si ya tiene psql
podría ejecutar psql -U materialize -h localhost -p 6875 materialize
en su lugar.
Cómo crear una fuente Materialize Kafka
Ahora que está en la CLI de Materialise, definamos los orders
tablas en mysql.shop
base de datos como fuentes de Redpanda:
CREATE SOURCE orders
FROM KAFKA BROKER 'redpanda:9092' TOPIC 'mysql.shop.orders'
FORMAT AVRO USING CONFLUENT SCHEMA REGISTRY 'http://redpanda:8081'
ENVELOPE DEBEZIUM;
Si tuviera que comprobar las columnas disponibles de los orders
source ejecutando la siguiente sentencia:
SHOW COLUMNS FROM orders;
Podrá ver que, dado que Materialise extrae los datos del esquema del mensaje del registro de Redpanda, conoce los tipos de columna que se deben usar para cada atributo:
name | nullable | type
--------------+----------+-----------
id | f | bigint
user_id | t | bigint
order_status | t | integer
price | t | numeric
created_at | f | text
updated_at | t | timestamp
Cómo crear vistas materializadas
A continuación, crearemos nuestra primera vista materializada para obtener todos los datos de los orders
Fuente Redpanda:
CREATE MATERIALIZED VIEW orders_view AS
SELECT * FROM orders;
CREATE MATERIALIZED VIEW abandoned_orders AS
SELECT
user_id,
order_status,
SUM(price) as revenue,
COUNT(id) AS total
FROM orders_view
WHERE order_status=0
GROUP BY 1,2;
Ahora puede usar SELECT * FROM abandoned_orders;
para ver los resultados:
SELECT * FROM abandoned_orders;
Para obtener más información sobre la creación de vistas materializadas, consulte la sección Vistas materializadas de la documentación de Materialise.
Cómo crear una fuente de Postgres
Hay dos formas de crear una fuente de Postgres en Materialise:
- Usando Debezium tal como lo hicimos con la fuente MySQL.
- Usar la fuente Materialise de Postgres, que le permite conectar Materialise directamente a Postgres para que no tenga que usar Debezium.
Para esta demostración, usaremos Postgres Materialise Source solo como una demostración de cómo usarlo, pero siéntase libre de usar Debezium en su lugar.
Para crear una fuente Materialise de Postgres, ejecute la siguiente instrucción:
CREATE MATERIALIZED SOURCE "mz_source" FROM POSTGRES
CONNECTION 'user=postgres port=5432 host=postgres dbname=postgres password=postgres'
PUBLICATION 'mz_source';
Un resumen rápido de la declaración anterior:
MATERIALIZED
:Materializa los datos de la fuente PostgreSQL. Todos los datos se retienen en la memoria y hace que las fuentes se puedan seleccionar directamente.mz_source
:El nombre de la fuente de PostgreSQL.CONNECTION
:Los parámetros de conexión de PostgreSQL.PUBLICATION
:La publicación de PostgreSQL, que contiene las tablas que se transmitirán a Materialise.
Una vez que hayamos creado la fuente de PostgreSQL, para poder consultar las tablas de PostgreSQL, necesitaríamos crear vistas que representen las tablas originales de la publicación ascendente.
En nuestro caso, solo tenemos una tabla llamada users
por lo que la instrucción que necesitaríamos ejecutar es:
CREATE VIEWS FROM SOURCE mz_source (users);
Para ver las vistas disponibles ejecute la siguiente sentencia:
SHOW FULL VIEWS;
Una vez hecho esto, puede consultar las nuevas vistas directamente:
SELECT * FROM users;
A continuación, avancemos y creemos algunas vistas más.
Cómo crear un fregadero Kafka
Los sumideros le permiten enviar datos de Materialise a una fuente externa.
Para esta demostración, usaremos Redpanda.
Redpanda es compatible con la API de Kafka y Materialise puede procesar datos de la misma manera que procesaría datos de una fuente de Kafka.
Vamos a crear una vista materializada, que contendrá todos los pedidos pendientes de pago de gran volumen:
CREATE MATERIALIZED VIEW high_value_orders AS
SELECT
users.id,
users.email,
abandoned_orders.revenue,
abandoned_orders.total
FROM users
JOIN abandoned_orders ON abandoned_orders.user_id = users.id
GROUP BY 1,2,3,4
HAVING revenue > 2000;
Como puede ver, aquí estamos uniendo a los users
vista que está ingiriendo los datos directamente desde nuestra fuente de Postgres, y el abandond_orders
vista que está ingeriendo los datos del tema de Redpanda, juntos.
Vamos a crear un Sumidero donde enviaremos los datos de la vista materializada anterior:
CREATE SINK high_value_orders_sink
FROM high_value_orders
INTO KAFKA BROKER 'redpanda:9092' TOPIC 'high-value-orders-sink'
FORMAT AVRO USING
CONFLUENT SCHEMA REGISTRY 'http://redpanda:8081';
Ahora, si tuviera que conectarse al contenedor de Redpanda y usar el tema rpk topic consume
comando, podrá leer los registros del tema.
Sin embargo, por el momento, no podremos obtener una vista previa de los resultados con rpk
porque tiene formato AVRO. Lo más probable es que Redpanda implemente esto en el futuro, pero por el momento, podemos transmitir el tema nuevamente a Materialise para confirmar el formato.
Primero, obtenga el nombre del tema que se ha generado automáticamente:
SELECT topic FROM mz_kafka_sinks;
Salida:
topic
-----------------------------------------------------------------
high-volume-orders-sink-u12-1637586945-13670686352905873426
Para obtener más información sobre cómo se generan los nombres de los temas, consulte la documentación aquí.
A continuación, cree una nueva fuente materializada a partir de este tema de Redpanda:
CREATE MATERIALIZED SOURCE high_volume_orders_test
FROM KAFKA BROKER 'redpanda:9092' TOPIC ' high-volume-orders-sink-u12-1637586945-13670686352905873426'
FORMAT AVRO USING CONFLUENT SCHEMA REGISTRY 'http://redpanda:8081';
¡Asegúrate de cambiar el nombre del tema en consecuencia!
Finalmente, consulta esta nueva vista materializada:
SELECT * FROM high_volume_orders_test LIMIT 2;
Ahora que tiene los datos en el tema, puede hacer que otros servicios se conecten a ellos y los consuman y luego activen correos electrónicos o alertas, por ejemplo.
Cómo conectar Metabase
Para acceder a la instancia de Metabase, visite http://localhost:3030
si está ejecutando la demostración localmente o http://your_server_ip:3030
si está ejecutando la demostración en un servidor. Luego siga los pasos para completar la configuración de Metabase.
Asegúrese de seleccionar Materializar como fuente de los datos.
Una vez que esté listo, podrá visualizar sus datos tal como lo haría con una base de datos PostgreSQL estándar.
Cómo detener la demostración
Para detener todos los servicios, ejecute el siguiente comando:
docker-compose down
Conclusión
Como puede ver, este es un ejemplo muy simple de cómo usar Materialise. Puede usar Materialise para ingerir datos de una variedad de fuentes y luego transmitirlos a una variedad de destinos.
Recursos útiles:
CREATE SOURCE: PostgreSQL
CREATE SOURCE
CREATE VIEWS
SELECT