Backend Development 10 min read

How to Sync MySQL to Redis in Real-Time with Spring Boot 3 and mysql-binlog-connector-java

This article demonstrates how to achieve real‑time synchronization of MySQL data to Redis using Spring Boot 3, the open‑source mysql‑binlog‑connector‑java library, and optional JMX exposure, providing step‑by‑step setup, code examples for parsing binlog events, listening to changes, and configuring Maven dependencies.

Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
How to Sync MySQL to Redis in Real-Time with Spring Boot 3 and mysql-binlog-connector-java

Introduction

MySQL‑Redis real‑time synchronization reflects changes in a MySQL database instantly in a Redis cache. MySQL provides durable relational storage, while Redis offers high‑performance in‑memory caching. Combining them improves system performance and consistency, especially for high‑concurrency scenarios such as e‑commerce and social platforms.

Component Features

Automatic parsing of binlog file name/position and GTID

Connection‑loss recovery

Pluggable failover strategy

Supports binlog_checksum=CRC32 (MySQL 5.6.2+)

Secure communication via TLS

JMX management extension

Real‑time statistics

Available on Maven Central

No third‑party dependencies, tested across MySQL versions

Environment Preparation

Add the following Maven dependencies to your Spring Boot project:

<code>&lt;dependency&gt;
  &lt;groupId&gt;com.zendesk&lt;/groupId&gt;
  &lt;artifactId&gt;mysql-binlog-connector-java&lt;/artifactId&gt;
  &lt;version&gt;0.30.1&lt;/version&gt;
&lt;/dependency&gt;

&lt;dependency&gt;
  &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
  &lt;artifactId&gt;spring-boot-starter-data-redis&lt;/artifactId&gt;
&lt;/dependency&gt;</code>

Ensure MySQL binlog logging is enabled:

<code>SHOW VARIABLES LIKE '%log_bin%';</code>

Run the command and verify the output. Example screenshot:

1. Programmatically Parse Binlog

The following Java program reads a binlog file, deserializes events, and prints their details:

<code>public static void main(String[] args) throws Exception {
  File binlogFile = new File("C:\\ProgramData\\MySQL\\MySQL Server 5.7\\Data\\mysql-bin.000032");
  EventDeserializer eventDeserializer = new EventDeserializer();
  eventDeserializer.setCompatibilityMode(
    EventDeserializer.CompatibilityMode.DATE_AND_TIME_AS_LONG,
    EventDeserializer.CompatibilityMode.CHAR_AND_BINARY_AS_BYTE_ARRAY);
  BinaryLogFileReader reader = new BinaryLogFileReader(binlogFile, eventDeserializer);
  try {
    for (Event event; (event = reader.readEvent()) != null;) {
      EventData data = event.getData();
      if (data instanceof WriteRowsEventData ed) {
        List<Serializable[]> rows = ed.getRows();
        rows.forEach(row -> {
          for (Serializable s : row) {
            if (s instanceof byte[] bs) {
              System.err.print(new String(bs) + "\t");
            } else {
              System.err.print(s + "\t");
            }
          }
          System.out.println();
        });
      } else if (data instanceof QueryEventData ed) {
        System.out.printf("Query event: %s%n", ed.getSql());
      } else if (data instanceof DeleteRowsEventData ed) {
        System.err.println("Delete event");
      } else if (data instanceof TableMapEventData ed) {
        System.out.printf("Database: %s, Table: %s%n", ed.getDatabase(), ed.getTable());
      }
    }
  } finally {
    reader.close();
  }
}</code>

The program outputs events such as query start, table mapping, row inserts, updates, and deletions.

2. Real‑Time Binlog Listener

Implement a Spring component that connects to MySQL and registers an event listener to process changes as they occur:

<code>@Component
public class MySQLToRedisComponent implements CommandLineRunner {

  public void listener() {
    BinaryLogClient client = new BinaryLogClient("118.24.111.33", 3307, "test", "root", "123123");
    EventDeserializer eventDeserializer = new EventDeserializer();
    eventDeserializer.setCompatibilityMode(
        EventDeserializer.CompatibilityMode.DATE_AND_TIME_AS_LONG,
        EventDeserializer.CompatibilityMode.CHAR_AND_BINARY_AS_BYTE_ARRAY);
    client.setEventDeserializer(eventDeserializer);
    client.registerEventListener(event -> {
      EventHeader header = event.getHeader();
      switch (header.getEventType()) {
        case EXT_WRITE_ROWS:
          WriteRowsEventData writeData = event.getData();
          for (Serializable[] row : writeData.getRows()) {
            printRow(row);
          }
          break;
        case EXT_UPDATE_ROWS:
          UpdateRowsEventData updateData = event.getData();
          System.err.printf("Updated columns: %s%n", updateData.getIncludedColumns());
          for (Entry<Serializable[], Serializable[]> entry : updateData.getRows()) {
            printRow(entry.getKey());
            System.out.println(">>> before");
            printRow(entry.getValue());
            System.out.println(">>> after");
          }
          break;
        case EXT_DELETE_ROWS:
          DeleteRowsEventData deleteData = event.getData();
          for (Serializable[] row : deleteData.getRows()) {
            printRow(row);
          }
          break;
        case TABLE_MAP:
          TableMapEventData mapData = event.getData();
          System.out.printf("Changed table: %s.%s%n", mapData.getDatabase(), mapData.getTable());
          break;
        default:
          break;
      }
    });
    client.connect();
  }

  private void printRow(Serializable[] row) {
    for (Serializable s : row) {
      if (s instanceof byte[] bs) {
        System.out.print(new String(bs) + "\t");
      } else {
        System.out.print(s + "\t");
      }
    }
    System.out.println();
  }

  @Override
  public void run(String... args) throws Exception {
    listener();
  }
}</code>

When data changes, the listener prints the affected table, columns, and row values.

3. Expose Binlog Client via JMX

Configure Spring beans to expose the client and its statistics through JMX:

<code>@Bean
BinaryLogClient client() {
  return new BinaryLogClient("118.24.111.33", 3307, "test", "root", "123123");
}

@Bean
MBeanExporter exporterClient(BinaryLogClient client) {
  MBeanExporter exporter = new MBeanExporter();
  exporter.setBeans(Map.of("mysql.binlog:type=BinaryLogClient", client));
  return exporter;
}

@Bean
MBeanExporter exporterClientStatistics(BinaryLogClient client) {
  MBeanExporter exporter = new MBeanExporter();
  BinaryLogClientStatistics stats = new BinaryLogClientStatistics(client);
  exporter.setBeans(Map.of("mysql.binlog:type=BinaryLogClientStatistics", stats));
  return exporter;
}</code>

After starting the application, use JConsole to view the exposed MBeans.

The complete source code implements data‑change listening, conversion to objects, and writing to Redis. Feel free to leave a comment if you need the full implementation.

JavaRedisSpring BootMySQLbinlogreal-time sync
Spring Full-Stack Practical Cases
Written by

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.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.