第三方平台:钉钉、飞书、企业微信
现阶段同步方式(下列所有步骤在一个service方法中):
1、通过API拉取所有部门数据
2、获取本地所有部门数据
3、分析两侧数据,得出需要“增、删、改”的数据
4、执行增删改
5、获取本地所有部门
6、递归遍历部门,通过API(根据部门ID获取用户列表)获取用户,拿到所有用户
7、获取本地所有用户
8、分析两侧数据,得出需要“增、删、改”的用户数据,同时对用户登录名做重复性校验
9、执行增删改操作
10、提交事务。
目前这种方式同步几千人的组织还行,如果是几万人甚至是10万人的组织。同步一次光拉取数据就很久,然后如果中间网络波动,或者数据处理异常,整次同步就失效了,所有数据回滚。
存在几个问题:
1、需要数据库连接的超时事件设置的非常大,否则同步到一半连接就超时断了
2、超时时间设置的太大,导致很多数据库连接明明没用了,但是仍然sleep中
3、同步最耗时的就是拉取数据,动不动就是几十分钟,好不容易拉取的数据如果异常了,直接就没了,下次同步又需要重新拉取。
目前的想法:
想引入中间表,同步前拉取数据到这张表内,同步时的数据从这张表里取,与本地数据对比。当同步失败时也没关系,下次同步前可以免去拉取数据这一环节。这张表的数据设置一个过期时长。如果成功同步后主动删除这张表。
但是还有些细节没有想好,有没有朋友们一起完善这个思路
你的想法是沿着正确的方向前进的,引入中间表是一种有效的方法来优化大规模数据同步过程。在这里,我提供一种可能的实现思路,希望能帮助你完善你的方案。
中间表设计:
创建一个中间表,用于存储从第三方平台拉取的组织架构和人员数据。
表结构可以包含字段如下:id(唯一标识,可以是第三方平台的组织架构或用户ID)、type(类型,用于区分组织和用户记录)、data(存储数据的字段,可以是 JSON 或者其他格式)。
数据同步过程:
拉取数据:从第三方平台拉取组织架构和人员数据,并将数据存储到中间表中。可以考虑分批次拉取,避免一次拉取过多数据。
同步数据:获取本地的组织架构和人员数据,与中间表的数据进行对比,找出需要进行"增、删、改"的数据。这里可以利用唯一标识进行数据匹配,避免重复同步已存在的数据。
执行增删改:根据对比结果,执行相应的增删改操作,更新本地数据库的组织架构和人员数据。
同步失败处理:
如果同步过程中发生异常或失败,可以记录失败状态,并在下次同步时重试这些失败的记录。
对于中间表的数据,可以添加一个时间戳字段,记录数据的更新时间。这样,如果同步失败,下次同步时可以只拉取更新时间在上次同步之后的数据,避免重复拉取整个数据集。
定时同步:
可以考虑定时任务来触发数据同步操作。定时任务可以设置为较短的时间间隔,如每隔几分钟或几小时执行一次同步任务,以保持数据的及时性。
异步处理:
考虑将数据同步过程设计成异步处理,可以利用消息队列等技术来处理大规模数据的同步。拉取数据、对比数据、执行增删改等步骤都可以独立成为异步任务,提高处理效率。
优化网络波动:
如果网络波动导致数据拉取失败,可以实现重试机制,确保数据的完整性和准确性。
总的来说,中间表的引入可以减少对第三方平台的频繁拉取数据,提高数据同步的效率和稳定性。同时,结合异步处理和定时任务,可以优化大规模数据同步的整体性能。综合考虑网络状况、数据量大小等因素,适当调整同步策略,应对不同规模的数据同步需求。
看看能否用时间戳限制一下 每次同步记录一下同步的时间戳 不用获取全部数据 只处理同步时间戳之后的数据
这里分析差异不耗时,重点是拉取数据。
拉取数据的常用优化方式: 并发、批量、异步、缓存。
并发: 通过多个线程拉取不同部门的数据;
批量: 如果有提供多个部门 ID 的 API 接口,就用批量接口;
异步: 为什么要同步? 是否有实时性要求? 要求实时性的场景是什么? 具体要多久就必须同步完? 需要明确一些非质量属性。你这个需求肯定不是单独的需求,而是在一个具体的语境了。
缓存: 是否有一些不变的数据,可以缓存起来。当然,中间表本质上也是缓存的一种形式。
此外,你需要知道获取所有部门的 API (一次性还是批量接口)的 RT ; 根据每个部门获取用户的 RT 。如此,才能去设计方案。
感谢您的回复,你说的几个方面都很有思考意义
其实主要涉及飞书、钉钉、企业微信等平台的人员组织架构同步。
并发:现在基本各个平台都对每秒并发、每分钟访问次数有设立要求,如果超过特定频率后,会被禁止访问API几-几十分钟不等。所以恰恰相反,在拉取大量数据时,非但没有使用并发,还在每请求多少次后主动sleep一段时间,怕的就是超频被禁止。
批量:如果有最好。可更多时候是没有的,获取用户信息,获取部门信息基本都需要通过指定ID单独请求。
异步:定时同步对于用户来说本身没有同步异步之分了。最多是在用户主动同步时,选择是否异步,如果采用异步,可以提升用户的体验度,但是需要额外编写一些代码。不过是否异步我觉得与同步本身效率并无关系
缓存:难点正是在这儿,我们作为下游,无法确定哪些数据发生了变化,这要求我们不得不进行数据的全量拉取,然后与本地数据进行比较,分析出增删改数据,不过照你的思路,我想到一个优化的点就是,可以选择具体某一个部门单独进行更新,或是全量更新,因为现实情况往往是,除了第一次需要全量更新拉取数据外,后续基本上都是组织进来一个人,我知道他的部门,需要主动同步一下数据,但是不得不进行全量更新。如果能给用户多一个选择其实也不错。当然有舍有得,这样子还是牺牲了一些数据一致性,看如何取舍。
这样子,你目前的想法是中间这张表作中转站作用。最大的问题是,这张表的过期时长设定不确定,你肯定希望这张表能在短期内为你将数据操作完成,无论是否中途网络波动失败,下次都等继续进行读写操作,同步完成后删除它。那么,我们能否对这张表进行标记。取唯一标识来作为判定条件,每次中断时,下一次将以唯一标识为判断标准来读取接下来的数据,继续同步呢?这里,我不确定你的表是一张总表还是,多张分表。如果是分表,那么在同步到第几张分表时,你可能也要做标识,以此决定下一次继续同步,他直接在对应分表找到数据进行你接下来的读写。总表也是这样一个思路。最终,数据由一个接口转到另一个接口再由你的方法分布到本地。细说就是 api 拉所有数据,他每次拉下来一条道你的新表里,你都要确保原数据表内有一个标识和 新表一 一对应,下一次同步时,判定这个标识是新表没有的,于是继续同步
– 予时光宁静以致远 1年前@予时光宁静以致远: 感谢您的思路,您说的没错,中间表应该至少有两个字段:数据唯一标识和数据时间,在进行同步拉取数据时,通过这两个字段,我可以先清理掉所有已过期的数据,取消对其中没有过期的数据发起请求。
– 玩屎的猪 1年前