Skip to content

22 elasticsearch带权限搜索系统设计2 groupserver

Jinxin Chen edited this page Dec 11, 2019 · 1 revision

本文介绍如何设计Groupserver

Groupserver用于同步不同系统的用户组织信息,并提供api用于获取用户所属组织,然后将这些信息合并到查询中以获取有权限的资料。

这里主要思考如下几个问题:

  1. 大数据量时如何保证同步的效率
  2. 如何让不同系统的用户组织信息共存及关联

大数据量时如何保证同步的效率

用户组织信息的变更包含新增、修改和删除,当数据量较大时,逐一比对groupserver和源系统的信息变化将消耗大量的资源和时间,对系统带来的效能影响也是无法接受的。

这里可以分两种情况设计:

  1. 第一次全量同步
  2. 非第一次的增量同步

第一次全量同步

因为groupserver还不存在任何源系统的用户组织信息,所有的资料均为新增,所以无需比对资料,直接将源系统获取的内容增加到groupserver中即可

非第一次的增量同步

当groupserver已经存在一部分源系统的用户组织信息时,再次同步则需要比对两边的资料,由于数据量大,逐一比对的路不可行。

解决方案可以考虑给用户组织信息加上“时间”、“变化”这两个标签,即在什么时候,发生了什么事情(新增、修改或删除)。这样一来,每次增量同步时只需要处理上次同步时间之后发生的事件,历史事件无需再处理,这样便省去了比对资料的过程。

增量获取资料:

select * from usergrouprelations where modified > @lastMaxModified

缺点是什么?

这样虽然可以提升同步效率,但是需要源系统配合修改,在每次人员组织信息发生变化时,增加一笔记录到事件中,并且要提前确定好事件的格式。

如何在源系统不修改逻辑的情况下,实现增量同步?

可以考虑单独增加一个表,用来记录用户组织信息及修改时间,并用job来定时sync源系统的资料:

UserId GroupId Created Modified Status
USER_A GROUP_A 2019-07-19 13:55:00 2019-07-19 13:55:00 0
USER_B GROUP_B 2019-07-19 13:55:00 2019-07-19 13:55:00 0
USER_C GROUP_A 2019-07-19 13:55:00 2019-07-19 13:55:00 0

插入新资料:

insert into usergrouprelations (GroupId, UserId , Status)

select rs.* from systemusergrouprelation rs left outer join usergrouprelations rd
	on rs.UserId = rd.UserId and rs.GroupId = rd.GroupId and rs.Status = rd.Status

where rd.UserId is null ;

删除不存在的资料:

update  rd set rd.status=1, rd.modified = getdate()

from usergrouprelations rd left outer join systemusergrouprelation rs
	on rs.UserId = rd.UserId and rs.GroupId = rd.GroupId and rs.Status = rd.Status

where rs.UserId is null and rd.status != 1

Groupserver 平台选择

groupserver主要的目的是获取user所属的groups,即

/api/groups/[userid]

这个特性可以考虑使用 key、value 形式的nosql,或者直接使用elk来存储,此时可以直接利用logstash来配置JDBC从源数据sync资料。

当然,使用传统的关系型数据库也可以,这时候就需要额外的编写代码来sync资料。

Clone this wiki locally