Redis与MySQL数据双写一致性工程落地案例

4.12

1.2.17

1.16.18

5.1.47

1.1.16

1.3.0

com.alibaba.otter

canal.client

1.1.0

com.google.guava

guava

23.0

org.springframework.boot

spring-boot-starter-web

org.springframework.boot

spring-boot-starter-actuator

org.springframework.boot

spring-boot-starter-data-redis

org.apache.commons

commons-pool2

redis.clients

jedis

3.1.0

org.springframework.boot

spring-boot-starter-aop

org.redisson

redisson

3.13.4

mysql

mysql-connector-java

5.1.47

com.alibaba

druid-spring-boot-starter

1.1.10

com.alibaba

druid

${druid.version}

com.alibaba

druid

${druid.version}

org.mybatis.spring.boot

mybatis-spring-boot-starter

${mybatis.spring.boot.version}

《一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》无偿开源 威信搜索公众号【编程进阶路】 ependency>

org.springframework.boot

spring-boot-starter-amqp

junit

junit

${junit.version}

org.springframework.boot

spring-boot-devtools

runtime

true

org.springframework.boot

spring-boot-starter-test

test

log4j

log4j

${log4j.version}

org.projectlombok

lombok

${lombok.version}

true

cn.hutool

hutool-all

RELEASE

compile

com.alibaba

fastjson

1.2.73

org.springframework.boot

spring-boot-maven-plugin

3.写YML server.port=5555

4.业务类 RedisUtils,如下:

package com.zzyy.study.util;

import redis.clients.jedis.Jedis;

import redis.clients.jedis.JedisPool;

import redis.clients.jedis.JedisPoolConfig;

/**

  • @auther zzyy

  • @create 2020-10-11 14:33

*/

public class RedisUtils

{

public static JedisPool jedisPool;

static {

JedisPoolConfig jedisPoolConfig=new JedisPoolConfig();

jedisPoolConfig.setMaxTotal(20);

jedisPoolConfig.setMaxIdle(10);

jedisPool=new JedisPool(jedisPoolConfig,“192.168.111.147”,6379);

}

public static Jedis getJedis() throws Exception {

if(null!=jedisPool){

return jedisPool.getResource();

}

throw new Exception(“Jedispool is not ok”);

}

/*public static void main(String[] args) throws Exception

{

try(Jedis jedis = RedisUtils.getJedis())

{

System.out.println(jedis);

jedis.set(“k1”,“xxx2”);

String result = jedis.get(“k1”);

System.out.println("-----result: "+result);

System.out.println(RedisUtils.jedisPool.getNumActive());//1

}catch (Exception e){

e.printStackTrace();

}

}*/

}

RedisCanalClientExample,如下:

package com.zzyy.study.t1;

import com.alibaba.fastjson.JSONObject;

import com.alibaba.otter.canal.client.CanalConnector;

import com.alibaba.otter.canal.client.CanalConnectors;

import com.alibaba.otter.canal.protocol.CanalEntry.*;

import com.alibaba.otter.canal.protocol.Message;

import com.zzyy.study.util.RedisUtils;

import org.springframework.beans.factory.annotation.Autowired;

import redis.clients.jedis.Jedis;

import java.net.InetSocketAddress;

import java.util.List;

import java.util.concurrent.TimeUnit;

/**

  • @auther zzyy

  • @create 2020-11-11 17:13

*/

public class RedisCanalClientExample

{

public static final Integer _60SECONDS = 60;

public static void main(String args[]) {

// 创建链接canal服务端

CanalConnector connector = CanalConnectors.newSingleConnector(new InetSocketAddress(“192.168.111.147”,

11111), “example”, “”, “”);

int batchSize = 1000;

int emptyCount = 0;

try {

connector.connect();

//connector.subscribe(“.\…”);

connector.subscribe(“db2020.t_user”);

connector.rollback();

int totalEmptyCount = 10 * _60SECONDS;

while (emptyCount < totalEmptyCount) {

Message message = connector.getWithoutAck(batchSize); // 获取指定数量的数据

long batchId = message.getId();

int size = message.getEntries().size();

if (batchId == -1 || size == 0) {

emptyCount++;

try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }

} else {

emptyCount = 0;

printEntry(message.getEntries());

}

connector.ack(batchId); // 提交确认

// connector.rollback(batchId); // 处理失败, 回滚数据

}

System.out.println(“empty too many times, exit”);

} finally {

connector.disconnect();

}

}

private static void printEntry(List entrys) {

for (Entry entry : entrys) {

if (entry.getEntryType() == EntryType.TRANSACTIONBEGIN || entry.getEntryType() == EntryType.TRANSACTIONEND) {

continue;

}

RowChange rowChage = null;

try {

rowChage = RowChange.parseFrom(entry.getStoreValue());

} catch (Exception e) {

throw new RuntimeException(“ERROR ## parser of eromanga-event has an error,data:” + entry.toString(),e);

}

EventType eventType = rowChage.getEventType();

System.out.println(String.format(“================> binlog[%s:%s] , name[%s,%s] , eventType : %s”,

entry.getHeader().getLogfileName(), entry.getHeader().getLogfileOffset(),

entry.getHeader().getSchemaName(), entry.getHeader().getTableName(), eventType));

for (RowData rowData : rowChage.getRowDatasList()) {

if (eventType == EventType.INSERT) {

redisInsert(rowData.getAfterColumnsList());

} else if (eventType == EventType.DELETE) {

redisDelete(rowData.getBeforeColumnsList());

} else {//EventType.UPDATE

redisUpdate(rowData.getAfterColumnsList());

}

}

}

}

private static void redisInsert(List columns)

{

JSONObject jsonObject = new JSONObject();

for (Column column : columns)

{

System.out.println(column.getName() + " : " + column.getValue() + " update=" + column.getUpdated());

jsonObject.put(column.getName(),column.getValue());

}

if(columns.size() > 0)

{

try(Jedis jedis = RedisUtils.getJedis())

{

jedis.set(columns.get(0).getValue(),jsonObject.toJSONString());

}catch (Exception e){

e.printStackTrace();

}

}

你可能感兴趣的:(Java,经验分享,架构,java)