MySQL Master‑Slave Replication in Docker, Sync to Redis via Canal & Spring Boot
This guide walks through setting up MySQL master‑slave replication in Docker, configuring the instances, testing synchronization, then deploying Canal and integrating it with a Spring Boot 2.7.8 application to capture database changes and push them into Redis.
Environment: Spring Boot 2.7.8, MySQL 8, master IP 192.168.2.129, slave IP 192.168.2.130.
1. Install MySQL with Docker
Create directories, set permissions, create my.cnf with required settings, then run the Docker container:
mkdir -p /root/software/mysql/conf /root/software/mysql/data
chmod -R 777 /root/software/mysql/
# my.cnf content omitted for brevity
docker run --name mysql8 --restart=always --privileged=true -v /root/software/mysql/conf/my.cnf:/etc/mysql/my.cnf -v /root/software/mysql/data:/var/lib/mysql -v /etc/localtime:/etc/localtime:ro -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123123 -d mysql --lower_case_table_names=12. Master‑Slave Configuration
On the master (192.168.2.129) add to my.cnf:
binlog_format=MIXED
log-bin=mysql-bin
server-id=1On the slave (192.168.2.130) add:
log-bin=mysql-bin
server-id=2Restart MySQL on both nodes.
3. Configure the Slave
Check master status to obtain File and Position values:
mysql> show master status;
+------------------+----------+...
| File | Position |
| mysql-bin.000001| 156 |Run CHANGE MASTER TO on the slave using those values:
CHANGE MASTER TO
MASTER_HOST='192.168.2.129',
MASTER_PORT=3306,
MASTER_USER='root',
MASTER_PASSWORD='123123',
master_log_file='mysql-bin.000003',
master_log_pos=156,
master_connect_retry=60,
GET_MASTER_PUBLIC_KEY=1;If the slave is running, stop it first: STOP SLAVE; Verify replication with: show slave status\G Key fields Slave_IO_Running and Slave_SQL_Running should be Yes.
4. Test Replication
Creating databases or tables on the master automatically replicates to the slave.
5. Deploy Canal
docker run --name canal -p 11111:11111 -v /opt/canal/conf:/home/admin/canal-server/conf -v /opt/canal/logs:/home/admin/canal-server/logs -d canal/canal-server6. Integrate Canal with Spring Boot
Add Maven dependencies for Redis, Web, and canal-spring-boot-starter (version 1.2.1‑RELEASE).
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>top.javatool</groupId>
<artifactId>canal-spring-boot-starter</artifactId>
<version>1.2.1-RELEASE</version>
</dependency>
</dependencies>Configure Redis and Canal in application.yml:
spring:
redis:
host: localhost
port: 6379
password: 123123
database: 8
lettuce:
pool:
maxActive: 8
maxIdle: 100
minIdle: 10
maxWait: -1
---
canal:
server: 192.168.2.130:11111
destination: redisDefine a simple data model:
public class Users {
private Integer id;
private String name;
private Integer age;
@Override
public String toString() {
return "Users [id=" + id + ", name=" + name + ", age=" + age + "]";
}
}Implement a service component to handle Canal events and write them to Redis:
@Component
@CanalTable("users")
public class UserServiceImpl implements EntryHandler<Users> {
private static final Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);
private final StringRedisTemplate stringRedisTemplate;
public UserServiceImpl(StringRedisTemplate stringRedisTemplate) {
this.stringRedisTemplate = stringRedisTemplate;
}
@Override
public void insert(Users user) {
logger.info("New data {}", user);
try {
stringRedisTemplate.opsForValue()
.set("users:" + user.getId(), new ObjectMapper().writeValueAsString(user));
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
@Override
public void update(Users before, Users after) {
logger.info("Before {}", before);
logger.info("After {}", after);
try {
stringRedisTemplate.opsForValue()
.set("users:" + after.getId(), new ObjectMapper().writeValueAsString(after));
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
@Override
public void delete(Users user) {
logger.info("Delete {}", user);
stringRedisTemplate.delete("users:" + user.getId());
}
}With these steps, any insert, update, or delete on the MySQL master is captured by Canal and instantly synchronized to Redis via the Spring Boot application.
Done.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Spring Full-Stack Practical Cases
Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
