基于流式计算的多层级组织的实时报表设计

背景:

某公司,有多个组织层级,所有的员工关系都隶属于最低组织层级。

现需要实现实时报表,对每个层级的组织都可以查看其员工情况统计报表,中间层级组织的报表相当于其直属下属组织的报表汇总。报表数据可反查。

原则:

流式计算,以空间换时间、以时间换时间

方案:

信息系统在对员工信息修改时,将原始修改信息进行预处理,然后应用到该员工所属组织报表上,同步更新其所有上级组织的报表。

预处理阶段:数据预处理引擎,即将原始修改信息进行提取,加工为报表所需的数据。加工后的数据放到消息队列中待处理。详略。

实时报表阶段:实时处理引擎,提取加工员工数据,与报表定义比对,生成匹配区域,进一步生成匹配报表格:

1、如该员工为新员工,则直接将对应匹配报表格+1,匹配报表格对应员工集合增加该员工,维护该员工对应报表格集合;

2、如该员工为老员工,则取出员工对应报表格集合,与新匹配集合比较:

对原有现无的格子:原匹配格数字-1,匹配格对应员工集合删除该员工,该员工对应报表格删除该格子;

对原无现有的格子:现匹配格数字+1,匹配格对应员工集合增加该员工,该员工对应报表格增加该格子。

对原有现有的格子,如格子类型为统计格,则跳过;如格子类型为字段汇总格(如汇总收入),则根据原值和新值对匹配格数字进行调整。

查询报表阶段:取出报表模板,将报表数字填写到模板上。反查时,根据格子对应员工集合显示员工列表即可。

技术:

消息队列:RabbitMQ,其可靠性高

报表数字存放:Redis的Hashtable类型,其有快速的hashincrease操作。Hashtable的外部键名包含报表名和组织层级码参数,内部键名包含报表格名参数,值为报表格数字。

报表数字查询:取出hashtable全部数字或单个数字都非常简单,单个数字复杂度为O(1)。

报表格对应员工集合:Redis的SortedSet类型,能确保唯一性,新增和删除操作均为O(1),与Set类型相比还能支持分页查询。SortedSet的键名包含报表名和报表格名参数,值为员工所在组织代码和员工主键(组合方便查询)。即使扩展为报表内部分统计员工,部分统计组织,因报表格都是从单一实体类型统计,所以也无需保存实体类型。

                        查询:使用Zrangebylex进行查询。字典序设定为组织代码即可

员工对应报表格集合:Redis的Set类型。不需要分页查询,故没有使用SortedSet类型。Set的键名包含实体类型和实体主键,键值包含报表名和报表格名

                        无需查询

 详细设计:

报表定义:

属性 含义
RPTName 定义所属的报表  
RangeType

区域类型

R:单行

C:单列

MR:多行分布

MC:多列分布

RangeValue

区域范围

类型为R或C时,该值为一个整数,表示第几行、第几列

类型为MR或MC时,该值为一个数组,表示连续行或列,例如MR的[2,3]表示第2行开始的连续3行。

Forumula

取数公式

值为一个数组,格式为[属性名,操作符或函数,参数集合...]

取数定义中的公式Forumula

操作符或函数 类型 适用数据类型 描述 示例
=,>,<,>=,<= 单行列 任意 比较运算

["年龄",">","60"]

匹配年龄大于60岁

运算根据属性类型自动确定比较方法,如数字、日期、文本等,下同。

range 单行列 任意 区间运算

["年龄","range","(30","[60"]

匹配年龄在30(不含)-60(含)岁区间

注:“(”表示不含,“[”表示含,没有符号的默认为含,下同。

startswith 单行列 文本 文本运算 

 ["工作岗位","startswith","1"]

匹配工作岗位代码以1开始

注:属性类型不为文本时将先转换成文本再运算,下同。

mrange 多行列 任意 多区间运算

["年龄","mrange","","[30","[60",""]

匹配<=30,31-60,>60三个区间,并将结果赋予所匹配的具体区间。

例如当匹配第2个区间时,该定义的范围为5-7行,则该公式匹配第6行。

mstartswith 多行列 文本 文本运算

["工作岗位","mstartswith","1","2,"3"]

匹配工作岗位代码以1、2、3开始的,匹配多个条件的,以第一个条件为准。

posted @ 2017-10-22 14:01  子鹃鸟鸣  阅读(1273)  评论(0)    收藏  举报