可视化网站建设软件,国内有没有开源的wordpress主题网,什么叫外链,成都本地网站建设优质博文#xff1a;IT-BLOG-CN
一、背景
随着机票业务的快速发展#xff0c;订单量持续增长对业务性能带来影响#xff0c;需要进行冷热数据分离。目前机票订单模块主要使用Mysql(InnoDB)作为数据库存储#xff0c;历史订单信息状态修改频率低并占用大量数据库存储空间IT-BLOG-CN
一、背景
随着机票业务的快速发展订单量持续增长对业务性能带来影响需要进行冷热数据分离。目前机票订单模块主要使用Mysql(InnoDB)作为数据库存储历史订单信息状态修改频率低并占用大量数据库存储空间期望历史数据与生产最新的数据进行分离当前数据库保留最近一个月的数据作为热库历史交易存在另一个库作为冷库。减少因在线存储空间不足扩容导致停服不可用的时长。
如何判断一个数据是冷数据还是热数据 需要根据自己业务系统来区分了一般而言是根据主表中的一个或者多个字段进行标识区分比如订单的时间这个是时间维度可以将3个月之前的数据定义为冷数据最近3个月的数据定义为热数据。当然也可以是状态维度比如订单的状态已完结的订单定义为冷数据未完结的订单定义为热数据。同样的也可以将时间维度和状态维度组合起来比如下单时间大于3个月且订单状态为已完结的定义为冷数据反则为热数据。 我的冷热数据怎么拆分的已过起飞时间 订单状态“完成”的数据都是冷数据其余为热数据。 二、方案选型
业务代码修改
这种方案是在业务代码层面判断是否进行冷热数据分离对代码的侵入性比较高在数据修改时触发冷热分离。因机票QPS很高如果更新状态时需要进行进行冷热数据分离删除热库中的数据并将数据写入冷库中需要使用到分布式事务。会增加系统和数据库的压力。不适用 监听binlog日志
需要监听binlog日志的方式进行触发当订单状态修改了则触发冷热分离。比较适合实时性要求高的系统这里虽然不会影响业务的响应时间。但是冷热数据分离的操作实时操作的会给数据库造成压力。不适用但是有用 怎么读取binlog中的内容我们通过公司内部开发的DRC服务这里简单看下重要流程 【1】在pom.xml中添加MySQL Binlog Connector Java的依赖
dependencygroupIdcom.github.shyiko/groupIdartifactIdmysql-binlog-connector-java/artifactIdversion0.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, aliceexample.com)那么WriteRowsEventData可能会包含如下信息 【1】tableId假设为1234。 【2】includedColumns位图表示三个列都包含在写入操作中。 【3】rows包含一个数组[1, Alice, aliceexample.com]。
定时任务
该方案可以根据“起飞时间”进行区分同时可以避免业务高峰期并且与业务代码进行解耦。适用结合binlog每次获取1000条数据分批处理 我们的方案
监听binlog日志当订单号状态发生变化并且已过起飞时间时将订单号存放至MongDB中夜间2点批量读取MongoDB中的订单号执行数据冷热数据分离业务逻辑。 我们这里时存储在MongDB后期消费部分系统是通过Kafka进行消息实时消费的定时任务校验数据的一致性对遗漏的数据进行校验。批量查询也是根据场景可能需要对冷热数据库一并查询需要封装统一的接口方法当冷热数据存在冲突时以热库的数据为准。 特殊场景处理逻辑 【1】冷库数据理论上不存在更新操作但是部分业务场景特殊需要对冷库中的数据先进性Delete操作再进行Insert操作而不是Update操作。这里场景接入的是Kafka。 【2】当冷热库存在相同的数据时以热库数据为准。冷库的数据来源只有热库数据同步到冷库。批量查询如果对顺序由要求时业务代码查询到数据后需要根据需求在内存中进行排序。