第十四章 广告检索系统——Binlog 增量数据的投递

此博客用于个人学习,来源于网上,对知识点进行一个整理。

1. 增量数据投递前的准备工作:

MySQL 增量数据的投递核心目的是构建检索服务中的增量索引,也就是说 IncrementListener 中使用到的 Isender 的方法去投递增量数据。首先我们观察到 AdPlanTable 中有两个特殊的索引——startDate 和 endDate。Long 和 Integer 这种类型的数据对于 MySQL 的表达不会有问题。但对于 Date 这种类型,Binlog 序列化成字符串,所以说我们需要去搞清楚 Date 这种数据类型的表达是什么样的。同样的,我们最好的方式就是看一下 Binlog 怎么样以字符串的形式表达日期。

1.1 设计转化格式:

启动 Binlog 的监听开关,然后去数据库中写入一些内容,比如插入一条数据,然后查看控制台上的打印信息,特别观察其中的日期信息。

Tue Jan 01 08:00:00 CST 2019

根据上面的打印信息设置解析方式。

1.2 实现转化:

在 CommonUtils 类中定义一个方法,实现对数据的解析,将其解析为一个 Date 类型。

@Slf4j
public class CommonUtils {
   
   

    /**
     * 传进来一个 map,如果这个 map 的 key 不存在,返回一个新的 value 对象
     * @param key
     * @param map
     * @param factory
     * @param <K>
     * @param <V>
     * @return
     */
    public static <K,V> V getOrCreate(K key, Map<K,V> map, Supplier<V> factory){
   
   
        return map.computeIfAbsent(key,k -> factory.get());
    }

    /**
     * 拼接字符串
     * @param args
     * @return
     */
    public static String stringConcat(String... args){
   
   
        StringBuffer result = new StringBuffer();
        for (String arg : args) {
   
   
            result.append(arg);
            result.append("-");
        }
        result.deleteCharAt(result.length() - 1);
        return result.toString();
    }

    /**
     * 将 String 类型转化为 Date 类型
     * @param dateString
     * @return
     */
    public static Date parseStringDate(String dateString){
   
   
        try{
   
   
            DateFormat dateFormat = new SimpleDateFormat(
                    "EEE MMM dd HH:mm:ss zzz yyyy",
                    Locale.US
            );
            return DateUtils.addHours(
                    dateFormat.parse(dateString),
                    -8
            );
        }catch (ParseException ex){
   
   
            log.error("parseStringDate error:{}",dateString);
            return null;
        }
    }
}

1.3 定义数据层级:

因为我们构建索引的时候是根据表之间的层级关系去构建的,但是目前我们还没有一个常量定义去定义这样的一个常量关系。因为我们去定义索引的时候,可能要去处理 level2,level3,level4,在代码中写上234也不太好维护,所以我们去定义一个 DataLevel 的一个数据层级,因为数据层级是索引内部的含义,于是我们将其定义在 index 包下。定义一个枚举类 DateLevel。

@Getter
public enum DateLevel {
   
   

    LEVEL2("2","level 2"),
    LEVEL3("3","level 3"),
    LEVEL4("4","level 4");

    private String level;
    private String desc;

    DateLevel(String level,String desc){
   
   
        this.level = level;
        this.desc = desc;
    }
}

2. 增量数据的投递:

增量数据的投递其实就是去实现 ISender 这个接口,ISender 接口去接收一个参数,是 MySqlRowData 的类型。构建索引的过程是使用我们之前完成的 AdLevelDataHandler,里面分为好几个层级,对于每一个层级都是将表转化为 table 对象,最终我们在增量数据投递的过程中,去实现增量索引的加载。

2.1 第二层级增量数据的投递:

@Slf4j
@Component("indexSender")
public class IndexSender implements ISender {
   
   

    @Override
    public void sender(MySqlRowData rowData) {
   
   
        String level = rowData.getLevel();

        if (DateLevel.LEVEL2.getLevel().equals(level)){
   
   
            //第二层级增量数据的投递
            Level2RowData(rowData);
        }else if (DateLevel.LEVEL3.getLevel().equals(level)){
   
   
            //第三层级增量数据的投递
        }else if (DateLevel.LEVEL4.getLevel(
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值