Skip to content

Commit 72fcdc6

Browse files
committed
Add replication sample
1 parent c3edd2f commit 72fcdc6

5 files changed

Lines changed: 179 additions & 2 deletions

File tree

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
-- 0. Espera un momento para que el motor de logs esté 100% estable
2+
SELECT SLEEP(20);
3+
4+
-- 0. FUERZA a que esta sesión grabe en el BinLog
5+
SET SESSION sql_log_bin = 1;
6+
7+
-- 1. Crear base de datos si no existe y usarla
8+
CREATE DATABASE IF NOT EXISTS post;
9+
USE post;
10+
11+
-- 2. Limpiar tablas previas para evitar errores de duplicados en la demo
12+
DROP TABLE IF EXISTS comment;
13+
DROP TABLE IF EXISTS post;
14+
15+
-- 3. Crear tabla POST (Entidad principal)
16+
CREATE TABLE post (
17+
id BIGINT NOT NULL AUTO_INCREMENT,
18+
username VARCHAR(255),
19+
title VARCHAR(255) NOT NULL,
20+
text TEXT,
21+
PRIMARY KEY (id)
22+
) ENGINE=InnoDB;
23+
24+
-- 4. Crear tabla COMMENT (Entidad relacionada)
25+
CREATE TABLE comment (
26+
id BIGINT NOT NULL AUTO_INCREMENT,
27+
username VARCHAR(255),
28+
comment TEXT,
29+
post_id BIGINT,
30+
PRIMARY KEY (id),
31+
CONSTRAINT fk_post_comment FOREIGN KEY (post_id) REFERENCES post (id)
32+
) ENGINE=InnoDB;
33+
34+
-- 5. Procedimiento de carga masiva optimizado
35+
-- DELIMITER $$
36+
37+
-- DROP PROCEDURE IF EXISTS FastDataLoad;
38+
-- CREATE PROCEDURE FastDataLoad()
39+
-- BEGIN
40+
-- DECLARE i INT DEFAULT 1;
41+
42+
-- -- Optimizaciones críticas de MySQL para inserción masiva
43+
-- SET FOREIGN_KEY_CHECKS = 0;
44+
-- SET UNIQUE_CHECKS = 0;
45+
-- SET AUTOCOMMIT = 0;
46+
47+
-- WHILE i <= 100000 DO
48+
-- -- Insertar Post
49+
-- INSERT INTO post (username, title, text)
50+
-- VALUES (
51+
-- CONCAT('User_Alpha_', i),
52+
-- CONCAT('Producto Pro v', i),
53+
-- CONCAT('Descripción técnica del post ', i, '. Este registro se usa para pruebas de estrés de JPA y latencia de red en topologías distribuidas.')
54+
-- );
55+
56+
-- -- Para el comentario, necesitamos el ID que se acaba de generar
57+
-- SET @last_id = LAST_INSERT_ID();
58+
59+
-- -- Insertar Comentario relacionado
60+
-- INSERT INTO comment (username, comment, post_id)
61+
-- VALUES (
62+
-- CONCAT('User_Alpha_', i),
63+
-- 'Reseña automática generada para carga de base de datos.',
64+
-- @last_id
65+
-- );
66+
67+
-- -- Commit parcial cada 10.000 filas para evitar saturar el buffer
68+
-- IF (MOD(i, 10000) = 0) THEN
69+
-- COMMIT;
70+
-- END IF;
71+
72+
-- SET i = i + 1;
73+
-- END WHILE;
74+
75+
-- COMMIT;
76+
77+
-- -- Restaurar configuración normal
78+
-- SET FOREIGN_KEY_CHECKS = 1;
79+
-- SET UNIQUE_CHECKS = 1;
80+
-- SET AUTOCOMMIT = 1;
81+
-- END$$
82+
83+
-- DELIMITER ;
84+
85+
-- -- 6. Ejecutar la carga
86+
-- CALL FastDataLoad();
87+
88+
-- -- Limpieza (Opcional)
89+
-- DROP PROCEDURE IF EXISTS LoadMassiveData;
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
CREATE USER 'repl_user'@'%' IDENTIFIED WITH mysql_native_password BY 'repl_pass';
2+
GRANT REPLICATION SLAVE ON *.* TO 'repl_user'@'%';
3+
FLUSH PRIVILEGES;
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
-- Esperamos a que el master esté listo (esto lo gestiona el driver/script)
2+
CHANGE MASTER TO
3+
MASTER_HOST='mysql-master',
4+
MASTER_USER='repl_user',
5+
MASTER_PASSWORD='repl_pass',
6+
MASTER_LOG_FILE='mysql-bin.000001',
7+
MASTER_LOG_POS=4;
8+
START SLAVE;
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
include:
2+
- docker-compose-monitoring.yml
3+
4+
services:
5+
mysql-master:
6+
image: mysql:8.0
7+
container_name: mysql-master
8+
environment:
9+
MYSQL_ROOT_PASSWORD: root
10+
MYSQL_DATABASE: post
11+
# Habilitamos el log binario y asignamos ID único
12+
command:
13+
- --server-id=1
14+
- --log-bin=mysql-bin
15+
- --binlog-format=ROW
16+
volumes:
17+
- ./config-db-replica/master-init.sql:/docker-entrypoint-initdb.d/01-setup.sql
18+
- ./config-db-replica/data_load.sql:/docker-entrypoint-initdb.d/02-data.sql
19+
- ./mysql-master:/var/lib/mysql
20+
healthcheck:
21+
test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost"]
22+
timeout: 5s
23+
retries: 5
24+
deploy:
25+
resources:
26+
limits:
27+
cpus: '1.0'
28+
memory: 1G
29+
30+
mysql-worker:
31+
image: mysql:8.0
32+
container_name: mysql-worker
33+
depends_on:
34+
mysql-master:
35+
condition: service_healthy
36+
environment:
37+
MYSQL_ROOT_PASSWORD: root
38+
command:
39+
- --server-id=2
40+
- --log-bin=mysql-bin
41+
- --read-only=1
42+
volumes:
43+
- ./config-db-replica/worker-init.sql:/docker-entrypoint-initdb.d/01-setup.sql
44+
45+
spring-app:
46+
build: ./ejem-2-cache-redis
47+
environment:
48+
- SPRING_DATASOURCE_URL=jdbc:mysql:replication://mysql-master:3306,mysql-worker:3306/post?autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true&connectTimeout=5000&socketTimeout=10000&readFromMasterWhenNoSlaves=true
49+
- SPRING_DATASOURCE_PASSWORD=root
50+
- SPRING_DATASOURCE_USERNAME=root
51+
- SPRING_DATASOURCE_HIKARI_MAXIMUM-POOL-SIZE=20
52+
- SPRING_REDIS_HOST=redis_t3
53+
- SPRING_REDIS_PORT=6379
54+
depends_on:
55+
mysql-master:
56+
condition: service_healthy
57+
deploy:
58+
replicas: 3 # Con LB
59+
resources:
60+
limits:
61+
cpus: '2.0'
62+
memory: 1G
63+
64+
haproxy:
65+
image: haproxy:latest
66+
container_name: lb_demo
67+
volumes:
68+
- ./haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro
69+
ports:
70+
- "8090:80" # Tráfico de la App
71+
- "8404:8404" # Estadísticas
72+
depends_on:
73+
- spring-app
74+
75+
redis:
76+
image: redis:alpine
77+
container_name: redis_t3

parte_5/ejem1-jmeter/test_plan.jmx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
</collectionProp>
2727
</HeaderManager>
2828
<hashTree/>
29-
<LoopController guiclass="LoopControlPanel" testclass="LoopController" testname="Controlador Bucle" enabled="true">
29+
<LoopController guiclass="LoopControlPanel" testclass="LoopController" testname="Controlador Bucle">
3030
<stringProp name="LoopController.loops">20</stringProp>
3131
</LoopController>
3232
<hashTree>
@@ -158,7 +158,7 @@
158158
<stringProp name="filename"></stringProp>
159159
</ResultCollector>
160160
<hashTree/>
161-
<ResultCollector guiclass="RespTimeGraphVisualizer" testclass="ResultCollector" testname="Response Time Graph">
161+
<ResultCollector guiclass="RespTimeGraphVisualizer" testclass="ResultCollector" testname="Response Time Graph" enabled="true">
162162
<boolProp name="ResultCollector.error_logging">false</boolProp>
163163
<objProp>
164164
<name>saveConfig</name>

0 commit comments

Comments
 (0)