缠丝猫 发表于 3 天前

数据库管理之冷热数据分离

优质博文:IT-BLOG-CN
一、配景

随着机票业务的快速发展,订单量持续增长对业务性能带来影响,需要举行冷热数据分离。目前机票订单模块紧张使用Mysql(InnoDB)作为数据库存储,历史订单信息状态修改频率低并占用大量数据库存储空间,期望历史数据与生产最新的数据举行分离,当前数据库保存最近一个月的数据作为热库,历史生意业务存在另一个库作为冷库。减少因在线存储空间不足扩容导致停服不可用的时长。
如何判定一个数据是冷数据还是热数据?
需要根据自己业务系统来区分了,一般而言是根据主表中的一个大概多个字段举行标识区分,好比订单的时间,这个是时间维度,可以将3个月之前的数据界说为冷数据,最近3个月的数据界说为热数据。固然也可以是状态维度,好比订单的状态,已完结的订单界说为冷数据,未完结的订单界说为热数据。同样的也可以将时间维度和状态维度组合起来,好比下单时间大于3个月且订单状态为已完结的界说为冷数据,反则为热数据。
   我的冷热数据怎么拆分的:已过腾飞时间 + 订单状态=“完成”的数据都是冷数据,别的为热数据。
二、方案选型

业务代码修改

这种方案是在业务代码层面判定是否举行冷热数据分离,对代码的侵入性比力高,在数据修改时触发冷热分离。因机票QPS很高,如果更新状态时,需要举行举行冷热数据分离,删除热库中的数据,并将数据写入冷库中,需要使用到分布式事件。会增长系统和数据库的压力。不适用
https://i-blog.csdnimg.cn/direct/8beeafc48aa4498a80cdb63a9a06df95.png
监听binlog日记

需要监听binlog日记的方式举行触发,当订单状态修改了,则触发冷热分离。比力适合及时性要求高的系统,这里虽然不会影响业务的响应时间。但是冷热数据分离的操作及时操作的,会给数据库造成压力。不适用,但是有用
https://i-blog.csdnimg.cn/direct/d0ef2028f6dd4050876bb6ce3bf833bc.png
怎么读取binlog中的内容,我们通过公司内部开发的DRC服务,这里简单看下紧张流程:
【1】在pom.xml中添加MySQL Binlog Connector Java的依赖
<dependency>
    <groupId>com.github.shyiko</groupId>
    <artifactId>mysql-binlog-connector-java</artifactId>
    <version>0.25.0</version>
</dependency>
【2】连接MySQL并读取binlog,注册了一个事件监听器来处理WriteRowsEventData事件。还可以根据需要处理其他范例的事件,例如UpdateRowsEventData和DeleteRowsEventData分场景举行业务处理。
import com.github.shyiko.mysql.binlog.BinaryLogClient;
import com.github.shyiko.mysql.binlog.event.*;

public class BinlogReader {

    public static void main(String[] args) throws Exception {
      String hostname = "localhost";
      int port = 3306;
      String username = "root";
      String password = "password";

      BinaryLogClient client = new BinaryLogClient(hostname, port, username, password);

      client.registerEventListener(event -> {
            EventData data = event.getData();
            if (data instanceof WriteRowsEventData) {
                WriteRowsEventData writeRowsEventData = (WriteRowsEventData) data;
                System.out.println("Write event: " + writeRowsEventData);
                // 处理写入事件
                handleWriteEvent(writeRowsEventData);
            } else if (data instanceof UpdateRowsEventData) {
                UpdateRowsEventData updateRowsEventData = (UpdateRowsEventData) data;
                System.out.println("Update event: " + updateRowsEventData);
                // 处理更新事件
                handleUpdateEvent(updateRowsEventData);
            } else if (data instanceof DeleteRowsEventData) {
                DeleteRowsEventData deleteRowsEventData = (DeleteRowsEventData) data;
                System.out.println("Delete event: " + deleteRowsEventData);
                // 处理删除事件
                handleDeleteEvent(deleteRowsEventData);
            }
      });

      client.connect();
    }

    private static void handleWriteEvent(WriteRowsEventData eventData) {
      // 在这里处理写入事件的业务逻辑
      // 例如:将数据写入另一个数据库或消息队列
    }

    private static void handleUpdateEvent(UpdateRowsEventData eventData) {
      // 在这里处理更新事件的业务逻辑
      // 例如:更新缓存或同步到另一个系统
    }

    private static void handleDeleteEvent(DeleteRowsEventData eventData) {
      // 在这里处理删除事件的业务逻辑
      // 例如:从缓存中移除数据或同步到另一个系统
    }
}
WriteRowsEventData类通常包罗以部属性:
【1】tableId:表现发生写入操作的表的ID,它通常由MySQL内部天生,用于在二进制日记中快速查找表的元数据。
【2】includedColumns:一个位图,表现哪些列包罗在写入操作中。位图中的每一位对应一个列,值为1表现该列包罗在写入操作中,值为0表现该列不包罗在写入操作中。
【3】rows:一个列表,包罗全部被写入的行的数据。每一行的数据通常以数组的形式存储,数组中的每个元素对应表中的一个列值。这些数据通常是经过编码的,需要根据表的元数据举行解码。
举个例子,如果你在MySQL中有一个表users,包罗三个列id、name和email,而且你插入了一行数据(1, 'Alice', 'alice@example.com'),那么WriteRowsEventData大概会包罗如下信息:
【1】tableId:假设为1234。
【2】includedColumns:位图表现三个列都包罗在写入操作中。
【3】rows:包罗一个数组。
定时使命

该方案可以根据“腾飞时间”举行区分,同时可以避免业务高峰期,而且与业务代码举行解耦。适用,联合binlog,每次获取1000条数据分批处理
https://i-blog.csdnimg.cn/direct/cd26af4b32a3445d8aca485386b6bba1.png
我们的方案

监听binlog日记,当订单号状态发生变革,而且已过腾飞时间时,将订单号存放至MongDB中,夜间2点批量读取MongoDB中的订单号实行数据冷热数据分离业务逻辑。
https://i-blog.csdnimg.cn/direct/5588bed3f4424727a4feda7c5ad56c20.png
   我们这里时存储在MongDB后期消耗,部分系统是通过Kafka举行消息及时消耗的,定时使命校验数据的一致性,对遗漏的数据举行校验。批量查询也是根据场景,大概需要对冷热数据库一并查询,需要封装统一的接口方法,当冷热数据存在冲突时,以热库的数据为准。
特别场景处理逻辑:
【1】冷库数据理论上不存在更新操作,但是部分业务场景特别,需要对冷库中的数据先进性Delete操作再举行Insert操作,而不是Update操作。这里场景接入的是Kafka。
【2】当冷热库存在相同的数据时,以热库数据为准。冷库的数据来源只有热库数据同步到冷库。批量查询如果对顺序由要求时,业务代码查询到数据后,需要根据需求在内存中举行排序。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 数据库管理之冷热数据分离