本文介绍了新旧模型在平台管控策略中的应用,特别是分配、个性化及星空旗舰版本的局部共享等技术实现方案。旧模型通过三个关系表(主表、使用表、排除表)管理数据分配与个性化,但存在性能问题。新模型则引入位图技术(RoaringBitmap)和kryo序列化工具,提高数据存储与查询效率,同时简化了数据结构。文中还详细说明了新旧模型中数据变化的操作逻辑,包括初始化、分配、个性化、删除等操作,并提供了SQL查询示例及相关的Java工具类说明。
星空旗舰版本:
局部共享 = 平台的分配
分配 = 平台的分配+平台个性化
下面的描述中如没特别说明,以平台的术语为准
管控策略:
星空支持---全局共享:5 私有:7 分配/局部共享:2
苍穹支持---全局共享:5 私有:7 自由分配:2 管控范围内共享:6 逐级分配:1
在旧模型中,实现技术方案是使用了三个关系表来实现:
主表
_u表使用表
usereg登记表
exc排除表
三个关系表数据变化简要说明
A组织新增数据001初始化:
U表会记录A 001、usereg登记表会记录A 001
分配个性化逻辑:
A组织分配001数据给B B组织对001个性化生成002
这个时候 U表会记录B 002 usereg登记表会记录B 002和B 001,同时exc排除表会记录B 001
删除个性化逻辑:
删除B的个性化数据002: 那么需要删除U表中B 002记录 登记表中B 002记录,从排除表中还原B 001记录到U表,然后删除排除表中B 001的记录,最后删除主表B的002数据
删除分配逻辑:
删除B的 001 分配关系:删除U表中B 001记录 登记表中B 001记录
总结:具体的实现逻辑比较复杂,多表关联性能较差,平台的第一个版本只有usereg登记表,其它两个表的数据都是内存中计算出来的,后面版本版本为了提高性能才增加_u表使用表、exc排除表
基础资料列表查询的SQL语句:
SELECT TOP 100000,0 A.fnumber "number", A.FId "id" FROM 主表 A inner join 主表_U ur1925338813459084288 on ur1925338813459084288.fdataid = A.fid and ur1925338813459084288.fuseorgid=组织Id WHERE A.fenable = 1 ORDER BY A.fnumber
在新模型中,使用了位图来实现
主表
_bit位图表
平台实现位图引入了两个工具: RoaringBitmap 和 kryo
RoaringBitmap是一个高效的压缩位图数据结构,用于处理大量的布尔型数据,它的基本原理是将大量的 0 或 1 的位串压缩成一个连续的整数集合,从而减小存储空间和提高查询效率。它是由Facebook开发的一种数据结构,主要用于处理大规模的集合运算,如交集、并集、差集等。
kryo是一个高性能的序列化/反序列化工具,由于其变长存储特性并使用了字节码生成机制,拥有较高的运行速度和较小的体积。
工具类:
kd.bos.bd.utils.KryoSerializerUtils
主要提供了kryo序列化与反序列化数据用于保存到数据库和缓存中,其中
保存进数据库_bit表是字段:forgid 、fdata(RoaringBitmap数据进行kryo序列化后的byte[])
保存进redis缓存的是Hash: key=bd_数据中心ID_基础资料标识, value =orgid, BaseDataUseRelBit(进行kryo序列化后的byte[])
基础资料主表会增加以下三个字段:
主表
序号 | 名称 | 数据类型 | 长度 | 小数位 | 允许空值 | 说明 |
---|---|---|---|---|---|---|
1 | fsourcedataid | int8 | 19 | 0 | N | 原id |
2 | fbitindex | int4 | 10 | 0 | N | 位图 |
3 | fsourcebitindex | int4 | 10 | 0 | N | 原位图 |
对应的表:bit表,表结构如下:
主表_bit
编号 | 名称 | 数据类型 | 长度 | 小数位 | 允许空值 | 主键 | 默认值 | 说明 |
---|---|---|---|---|---|---|---|---|
1 | FORGID | int8 | 20 | 0 | N | Y | ||
2 | FDATA | bytea | 2147483647 | 0 | N | N |
redis缓存:
其中这里重点关注
1、主表 中的 fbitindex 字段,它是一个从1开始自增长步长为1的int类型数字。即主表每增加一条数据,fbitindex生成一个整型数字表示这条数据的位图。redis缓存key: BIT_INDEX_标识_数据中心ID 会记录fbitindex起始位,缓存过期了会取数据库中的最大值
实现的类:
kd.bos.bd.service.AbstractBaseService
2、bit表的fdata数据是:是位图数据结构RoaringBitmap进行kryo序列化后的byte[]数据
示例说明:
1、主表组织A创建3条数据 fbitindex = 1、fbitindex = 2、fbitindex = 3
bit表 组织A的 fdata= kryo.序列化(RoaringBitmap.bitmapOf(1,2,3))
2、将数据 fbitindex = 1、fbitindex = 2 分配给组织B
bit表 组织B的 fdata= kryo.序列化(RoaringBitmap.bitmapOf(1,2))
3、将数据 fbitindex = 1、fbitindex = 2 分配给组织C、 fbitindex = 3 分配个性化给组织C
主表新增个性化数据 fbitindex = 4,fsourcebitindex =3
bit表 组织C的 fdata= kryo.序列化(RoaringBitmap.bitmapOf(1,2,4))
基础资料列表查询的SQL语句,以组织C为例:
select forgid,fdata from 主表_bit where forgid in (组织C的id) select a.fnumber "number", a.fid "id" from 主表 a where a.fenable = '1' and a.fbitindex in (1,2,4)
关系表数据变化简要说明
A组织新增数据001初始化:
主表001数据的 fbitindex =1 、bit表增加 forgid=A组织id,fdata={1} 数组的数据
分配个性化逻辑:
A组织分配001数据给B B组织对001个性化生成002,fbitindex =2
bit表增加 forgid=B组织id,先分配:fdata={1} 再个性化:fdata={2}
删除个性化逻辑:
删除B的个性化数据002: 那么需要删除bit表中 forgid=B组织id fdata={2},从主表中fsourcebitindex还原为bit表中 forgid=B组织id fdata={1},最后删除主表B的002数据
删除分配逻辑:
删除B的 001 分配关系:删除bit表 forgid=B组织id fdata={1} 的数据
平台提供操作位图的主要工具类
兼容新旧模型:
基础资料数据服务工具类:
kd.bos.servicehelper.basedata.BaseDataServiceHelper
判断是否新模型方法:
public static Boolean kd.bos.bd.service.BaseDataCommonService.isNewModel(String entity)
新模型工具类:
位图序列化反序列化工具类:
kd.bos.bd.utils.KryoSerializerUtils
位图操作公共抽象操作类:
kd.bos.bd.engine.AbstractBaseDataUseRelEngine
查询服务,负责位图数据的查询(从数据库、缓存):
kd.bos.bd.engine.BaseDataUseRelQueryEngine extends AbstractBaseDataUseRelEngine
更新服务,处理位图数据的更新,插入:
kd.bos.bd.engine.BaseDataUseRelUpdateEngine extends AbstractBaseDataUseRelEngine
推荐阅读