增量接口的设计及实现

引言

在应用开发过程中,我们总会碰到这样的场景:某系统需要同步我们系统的数据去做一些业务逻辑,当数据量较小的时候,可以全量的提供,但当数据量很大时,全量提供就显得很笨重,不仅耗时而且做了很多无用功,这时我们需要一种提供增量数据的机制,只告诉对方变化的数据。提供增量数据大致可分为两种方式:MQ和接口提供,MQ的优点是及时,缺点是丢失、重复、回溯复杂等等问题(依赖于具体MQ实现),这里不过多赘述;接口提供不限于RPC或HTTP等方式,接口提供的优缺点正好和MQ反过来,及时性取决于调用周期。P.S.本文描述的数据同步区别于数据库层的同步,应用层的同步表不一定同构,或者都不落地。

Created with Raphaël 2.1.0AABBsync datado something

接口设计

只需要一个version参数,其它参数根据实际业务场景添加,返回值中也加入version,调用端使用返回值中的version用于下次调用。

接口使用

String lastVersion = getLastVersion();// 拿到上一次版本号
try {
    while(true) {
        List<Data> datas = syncData(lastVersion);// remote or local
        if (datas.isEmpty()) {
            break;
        }
        for (Data data : datas) {
            // 1. 做一些逻辑处理
            // ...............  
            // 2. 暂存version
            lastVersion = data.getVersion();
        }
    }
} finally {
    saveVersion(lastVersion);// 保存版本号
}

以上代码需要放到一个定时调度模块中,周期越短,数据延时越低。如果由于故障或BUG导致处理出现问题时,只需将版本号向前调整即可,回溯简单。

接口实现

实现要考虑以下几个方面,内存占用、version设计、数据删除。

内存占用

增量接口很可能被其它系统频繁的调用,尤其当我们系统中有一种很核心的数据,所以要对每次调用返回的数据量有一个控制,比如每次只返回1000条,后面描述都以1000条为例。我建议这个数据量控制在数据提供方,而不是调用方,即便调用方可以控制,提供方也要做一个最大限制。

version设计

假设我们的数据类似于下表:

id

update_time

2

2017-03-09 23:59:59

68

2017-03-09 23:59:59

26

2017-03-09 23:59:59

71

2017-03-09 23:59:59

17

2017-03-09 23:59:59

14

2017-03-09 23:59:59

11

2017-03-09 23:59:59

8

2017-03-09 23:59:59

5

2017-03-09 23:59:59

65

2017-03-09 23:59:59

66

2017-03-09 23:59:59

version设计很多人第一时间会想到数据更新时间,SQL可能是这样:

SELECT * FROM data 
WHERE update_time > #{version} 
ORDER BY update_time ASC LIMIT 1000;

当很多数据update_time一样时,会丢失数据。比如上一批次返回的最后一条是id=71,version是2017-03-09 23:59:59,那本次查询就会忽略后面update_time=2017-03-09 23:59:59的数据。这时可能又有人想到下面这样的方式:

SELECT * FROM data 
WHERE update_time >= #{version} 
ORDER BY update_time ASC LIMIT 1000;

update_time加了个=,这样是不会丢数据了,但是会返回重复数据,甚至死循环。比如比如上一批次返回的最后一条是id=71,version是2017-03-09 23:59:59,id=71后面有10000条update_time=2017-03-09 23:59:59的数据,接口每次返回1000条,这时调用端永远跳不出这批数据了。鉴于上面的问题,显然version单单使用数据更新时间已经不够了,这时可以加入其它辅助项,比如自增ID。比如比如上一批次返回的最后一条是id=71,这时的version格式是这样:2017-03-09 23:59:59@71,SQL变成下面这样,分两步查询:

第一步: 查询update_time = '2017-03-09 23:59:59'并且id > 71的数据;
SELECT * FROM data 
WHERE update_time = '2017-03-09 23:59:59' AND id > 71
ORDER BY update_time ASC, id ASC LIMIT 1000;
第二步: 查询update_time > '2017-03-09 23:59:59'的数据;
SELECT * FROM data 
WHERE update_time > '2017-03-09 23:59:59'
ORDER BY update_time ASC, id ASC LIMIT ?;

这里有一些细节需要控制,如果第一步返回的数据量已经达到1000,则不需要执行第二步,如果小于1000,则需要执行第二步,数据量应该依据第一步返回的数据量计算。最终,version的格式:更新时间毫秒数@数据自增id,上面为了方便说明,直接用了格式化后的时间。

但上面这种基于数据更新时间的同步方式在并发写入场景下可能存在问题,比如一条数据在2017-03-09 23:59:59时被更新,但该事务是在2017-03-10 00:00:01时提交,恰好在2017-03-09 23:59:59有一个同步发生,那这次同步是同步不到这条数据的,因为事务还没有提交,而下一次同步也不会同步这条数据,因为时间(2017-03-09 23:59:59)极有可能已经过去了。解决这个问题也比较简单,我们可以在更新数据的同时,记录一条数据日志,并且有一个线程去定期清理过期的重复数据,最后我们的版本号就是该日志表的自增主键ID。

数据删除

增量数据的获取是依赖更新时间,这就有一个隐含的前提,需要数据存在,如果数据真正的删除了,那也就不能获取到这条数据的变更了。所以,通过接口提供增量数据不能真删数据,而要假删(增加一个状态,表示有效或无效),这也算一个缺点吧。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏大眼瞪小眼

Mysql语句的执行过程

当你希望MySQL能够以更高的性能运行查询时,最好的办法是弄清楚MySQL是如何优化和执行查询。《高性能MySQL》

952
来自专栏北京马哥教育

理解MySql事务隔离机制、锁以及各种锁协议

一直以来对数据库的事务隔离机制的理解总是停留在表面,其内容也是看一遍忘一边。这两天决定从原理上理解它,整理成自己的知识。查阅资料的过程中发现好多零碎的概念如果串...

3849
来自专栏北京马哥教育

FTP基于PAM和MySQL/MariaDB实现虚拟用户访问控制

前言 vsftpd是一款在Linux发行版中最受 推崇的FTP服务器程序,特点是小巧轻快,安全易用,目前在开源操作系统中常用的FTP套件主要有proftp...

3435
来自专栏杨建荣的学习笔记

关于视图和存储过程的权限问题探究 (r9笔记第87天)

今天在处理一个工单的时候发现了一个奇怪的现象,开发同学需要创建一个存储过程,目前的架构类似这样的形式 ? 数据库中存在一个属主用户,表,存储过程等对象...

35910
来自专栏北京马哥教育

MySQL 数据库上线后根据 status 状态优化

马哥linux运维 | 最专业的linux培训机构 ---- 网上有很多的文章教怎么配置mysql服务器,但考虑到服务器硬件配置的不同,具体应用的差别,那些文...

3246
来自专栏L宝宝聊IT

Mysql性能优化——慢查询分析

MYSQL数据库是常见的两个瓶颈是CPU和I/O的瓶颈,CPU在饱和的时候一般发生在数据装入内存或从磁盘上读取数据时候。磁盘I/O瓶颈发生在装入...

1312
来自专栏PHP在线

SQL语句执行过程详解

一条sql,plsql的执行到底是怎样执行的呢? 一、SQL语句执行原理: 第一步:客户端把语句发给服务器端执行 当我们在客户端执行 select 语句时,客户...

6046
来自专栏LhWorld哥陪你聊算法

Mysql篇--Linux中安装Mysql

由于Windows安装Mysql非常麻烦,所以分享一篇Linux中对MySQL的搭建,废话不多说,来,come on.

3642
来自专栏数据和云

DB2 Vs MySQL系列 | 体系架构对比

前些日子,我们做了DB2 VS MySQL的数据类型的对比,今天我们将体系架构的对比分享给大家,让大家对这两类数据库有更深刻的认识。 ? DB2体系结构 ? ?...

3255
来自专栏逸鹏说道

zabbix最新SQL注入漏洞+EXP

最近zabbix又出大事了,高危的SQL注入漏洞,影响V3.0.4以下所有版本,请小伙伴及时修复。 漏洞概述: zabbix是一个开源的企业级性能监控解决方案。...

3948

扫码关注云+社区

领取腾讯云代金券