总第230篇
2018年 第22篇
背景
O2O是目前互联网竞争最激烈的领域之一,其重要的业务特征是有大规模的线下业务团队,他们分布在五湖四海,直接服务着数以百万的商家,责任很重,管理的难度巨大。能否通过技术手段,打造高效的线下团队,是O2O公司的核心竞争力。
随着美团酒旅业务的快速增长,业务人员绩效的考核方案和激励政策呈现出多样化、复杂化的特点,对绩效计算实时性和准确性的要求也越来越高。原始的绩效计算流程,包括各战区目标下发、激励调整、数据校验等繁琐工作,需要投入大量的人力,准确性也无法得到保障。鉴于这种情况,以优化体验、提升效率、降低成本为目标,我们设计并实现了一套在准确性、实时性、灵活性等方面表现都比较优秀的绩效系统来解决上述问题。
挑战
在开发Hermes(新的绩效系统的名称,是希腊神话中的财神)的过程中,主要面临的挑战有如下几个:
数据量大,来源广且高度复杂。业务人员绩效相关的数据每天以百万级的速度在增长,月末产生的数据至少是千万级别的,而且所产生的数据由于没有统一的规范,所以复杂度特别高。由于数据没有统一的来源,而且将来可能还会增加新的数据源,那么就需要我们对各方的数据进行预先的组织和处理。为了实现绩效计算的准确性和实时性,我们至少要保证每天都能更新绩效数据,否则月底的压力非常大,一是研发人员面对如此海量的数据计算压力十分大,二是业务人员数据校验的压力也会非常大。
绩效考核方案配置灵活,指标规则千变万化。为了更好地支撑业务的增长,每个月的考核方案和考核规则变化非常大,那么我们必须保证方案的配置灵活,指标规则的配置通用,能够跟得上业务发展的脚步。
绩效目标设置困难,难以有效、快速地提高业务人员的效率和积极性。绩效目标的设置往往是根据以往的经验决定的,但是随着酒旅业务的高速增长,经验可能往往不够,设置高了影响业务人员的积极性,设置低了,影响业务人员的效率,更是不利于公司业务长久高速地增长。所以最终我们要实现智能化、差异化的生成绩效考核方案。
解决思路
为了解决这一系列的问题,我们设计了如图1所示的整体流程。
数据引擎完成了数据的清洗、加载、转换、聚合的过程,为系统提供了稳定的外部数据支持
激励管理模块完成指标数据的申诉、主观考核以及激励调整等内部的数据准备工作,进一步保障了数据的可靠性和完整性
指标配置模块供商业分析的同事创建考核方案时使用,考核粒度可细化到具体的业务人员,该模块实现了考核指标的动态创建以及指标的多样性考核等功能
规则引擎完成了指标考核规则的配置、解析和匹配功能,使指标数据的计算更加准确、高效,同时,计算过程可追溯、可解释
计算引擎包括指标依赖解析、SQL执行器、计算调度器三个子部分,实现了根据指标的依赖关系完成指标的下钻、回溯计算流程,保障了系统的正常调度、准确计算及稳定输出功能
图1 系统整体流程图
解决方案
在明确解决思路之后,我们就开始了Hermes系统的设计,具体的系统架构图如图2所示。我们在明确整体功能和架构之后,设计了六个模块和四个引擎,双重缓存结构,下面我们开始逐层的介绍。
在API层我们会通过HTPP和Thrift两种方式分别为前端和HR中台提供数据,为了保证数据的安全性,在登录和流程管理时我们会使用UPM(美团点评用户权限管理系统)控制当前用户的权限以及展示的模块,在具体到指标管理、方案管理和激励管理等模块时,我们会依赖于将军令系统(美团点评数据管理权限系统)做数据权限控制。
指标管理主要用于管理指标的信息,指标是组成方案的最基本的元素,分为基础指标、主观指标和复合指标。基础指标是从外部系统获取,而复合指标和主观指标是在Hermes系统内创建。
如图3所示,复合指标是由基础指标和数字组成,并且在创建之初就需要确定该复合指标的数据口径以及数据来源。数据口径主要分为本人的、下属的和直接下属的三种,主要是为了标明所考核的指标是使用本人的值还是下属的汇总值。我们选择将数据口径放在指标维度是基于两点考虑,一是结构清晰,二是可以针对业务经理所考核的指标做预计算,减少后期的复杂度。数据来源是指所考核的指标的目标值、基准值等等数据的来源。如果是本系统上传,那么可以在创建方案的时候强制用户上传,起到一个预判断的作用。
图3 复合指标
主观指标主要应用于主观考核,即领导对于员工个人表现的一个打分,一般会作为最后工资计算的系数,在创建主观指标的时候也会有一个预判断,防止主观考核的系数过高或者过低。
方案管理主要用于管理方案的相关信息,如图4所示,方案主要是由考核对象、考核指标、指标规则和方案的封顶值等元素组成。方案的创建和修改在此模块发起,并不是真正的创建和修改方案,只是将修改或创建方案的任务插入到任务队列中去,扮演着生产者的角色,然后由调度引擎即消费者来真正完成方案的创建和更改操作。这里我们使用了Producer-Consumer模式,并在此基础上进行了改良,使用工作窃取算法完成方案的快速创建与修改。
图4 方案创建
由于Hermes系统负责美团旅行所有战区的所有业务人员绩效方案的创建与修改,任务量有时会非常的大。如果使用简单的Producer-Consumer模式,那么会使众多的消费者共享一个队列实例,很容易产生锁的竞争,即修改队列的头指针时所需要获取的锁而导致的竞争。如果一个通道实例对应多个队列实例,那么就可以实现多个消费者线程同时从通道中获取任务的时候访问的是各自的队列实例。此时,各个消费者线程修改队列的头指针并不会导致锁的竞争。
同时,当一个通道对应于多个队列实例时,当一个消费者处理完该线程所对应的队列中的任务后,它可以继续从其他的队列中取出任务进行处理,这样既不会导致该消费者线程闲置,又减轻了其他消费者的负担,加快了任务的执行进度。当任务执行失败之后,我们会使用公司的组件Mafka(Mafka是美团点评内部的消息中间件,在Kafka的基础上进行了优化)将任务做一个标识重新放入队列中去,当重试多次后仍然失败,会使用大象(是美团点评内部的一个通信软件)通知方案创建者和相关的研发人员。
激励管理模块主要是用于对业务人员的激励或是惩罚以及业务人员的申诉。主要通过主观值和调整值对业务人员进行激励和惩罚,调整值是直接在方案计算业务人员工资的基础上加或减工资,而主观值主要用于上级对下属的主观评价,然后作为一个系数直接作用于绩效考核方案的结果。如果业务人员对于某个指标的相关数据产生疑问,可以在此模块进行申诉。
如图5所示,申诉、激励调整和主观考核都会发起一个审批流程。由于审批流比较复杂,我们使用的是公司内部的组件Gravity(美团点评内部的流程管理组件)。它是基于activiti引擎构建的流程平台,能够轻松管理业务流程事项,并且提供了统一的流程规划、流程建模、流程部署、流程管理、任务管理、流程监控、流程分析、流程运维等服务,这样我们就节约了一定的开发成本。
审批如果被驳回,我们会通过大象通知流程发起者;审批通过时,我们一方面会通知流程发起者,另一方面我们会把审批的详细信息存入到一张中间表中。然后通过定时调度引擎来定时扫描该表中的数据,目前是10分钟一扫描,然后依据审批信息重新计算相关人员的绩效数据,最终更新数据库中的信息,完成申诉、激励调整和主观考核的流程。
图5 激励管理
激励查询主要分为业务人员查询和管理人员查询两个部分。业务人员可以查询到自己的工资详情,还有每个指标的完成情况以及每个指标对应的奖励详情;管理人员可以查询自己的工资详情,还有其所属下属指标的完成情况,以及下属之间竞争力的比较。
当主管查询下属的各个指标具体完成情况或是历史详情时,数据量会非常大。如图6所示,我们会先count一下,拿到具体的数据量,当数据量超过5万的时候前端渲染就会有问题,这时我们会提示用户数据量过大,只能将数据下载到Excel中。
如果数据量没有超过5万,我们会走两级缓存结构。当一级缓存中有数据时直接返回,整个请求结束;如果一级缓存异常,我们会走二级缓存,二级缓存有数据直接返回,整个请求结束;如果二级缓存也发生异常(几乎不可能),我们会查询数据库。为了防止整个查询超时,我们会在用户访问时返回给前端一个query_id作为唯一的查询标识符。前端会每隔5分钟轮询调用后台接口,直到有数据返回,整个查询结束。这样就很好地解决了当数据量过大,无法正常返回的场景。
图6 激励信息查询流程图
流程管理,主要是对于审批流程的管理。审批流使用的是公司内部的组件Gravity,我们在此基础上进行了一层封装,保存了审批相关的所有信息,这样我们就可以依据自身的场景做一些业务逻辑。现在只有流程查询和审批内容查询两部分,将来还会加入审计和权限管理等功能。
绩效管理,主要是用于和总部的HR中台打通。他们可以在这里查询员工的各种绩效信息,然后对比分析以核查方案创建的有效性,即考核方案是否合理,是否有效地鼓舞了员工,提升效率等等。
数据引擎是最基础的部分,是各种运算的数据来源和对外交互的数据来源。如图7所示,数据来源十分杂乱,有的来自于ETL任务,有的来自于起源系统等等,而且它们各有各的数据结构。如果我们为每一个来源都提供一种接入方式,那么将来如果有新的数据源,我们也需要新增一种新的接入方式,这样是不满足系统的可扩展性的。所以我们要做的是提供一种统一的接入方式,一个统一的数据规范,为此我们设计了一个适配层。无论是哪里来的数据必须符合适配层的规范,否则不予录入。这样就很好的解决了数据来源广、不规范的问题,无论将来新增多少种数据源都不需要我们做新的开发工作,节省了大量的无用功。在适配层我们会做一些简单的数据组装工作,然后分别存入到对应的表中。而且在适配层我们还会提前做一些缓存的逻辑,为后面的数据计算做好铺垫。
图7 数据引擎
API层是我们对外提供数据的核心层,我们会为总部和HR中台提供一些绩效数据。而数据逻辑层则负责Hermes系统内部的逻辑计算,会将计算结果回写到数据库和缓存中。
规则引擎是整个绩效系统的核心部分,主要包含两个方面,一是建立合理有效的激励考核方案,二是针对考核方案所涉及的指标进行规则的配置。方案的配置方式特别灵活,我们需要做的是能够兼容所有战区之间的差异。必须做到通用性强,能够满足战区的大部分需求,而不是每个月为了新的需求忙得焦头烂额。只有这样才能有效地解放人力,将一些重复的工作屏蔽掉,实现智能化方案管理。
如图8所示,方案是由参数组成,而参数是由指标组成,然后针对每一个指标配置一套规则。规则是由计算规则和计算表达式两部分组成。参数是对业务人员某项业务能力的考量。当配置方案时,我们只需根据当前月的主要目的就可以进行参数的筛选,而不必每个月都从头开始创建新的方案。
指标是组成方案的最基本的元素,每个指标会对应一套规则。针对不同的场景可以选择不同的规则,这样完全能够满足大部分的业务需求,每个月只需新增不满足需求的指标或指标规则即可,节省了大量的配置工作。计算规则是一个通用的逻辑表达式,计算表达式和计算规则成对出现,是一对一的关系,类似于数学的计算公式。
配置方案的时候需要指明该方案所要考核的对象,即图8中的Role。考核对象可能是一个组织,可能是一个个人,也可能是一个组织和多个人等等。同时还需要对这些角色进行职位的筛选,并且还要考虑一个人的离职、转岗以及升职等等情况。正是基于这种场景,我们选择使用empId_positionId_orgId作为一个唯一键,来唯一确定一个人。
图8 规则引擎
这里还有一个关键问题,方案的流转状态包括审批中、通过、驳回和拒绝,而审批状态的变化必然涉及到方案的有效性。方案的有效性会引起Role的变化,因为一个自然月内一个人(empId_positionId_orgId)有且仅能有一个方案。那么我们怎么保持数据库、Squirrel缓存和Tair缓存的一致性呢?我们采用的依旧是任务队列的方式,即方案的状态发生变动时,我们会把它作为一个任务放到任务表中,然后使用一个任务以事务的方式来保证缓存和数据库的一致性。
调度引擎主要就是定时的完成一些任务,主要包含两个方面,一是数据的预加载,二是方案相关操作的异步化。
数据的预加载主要涉及到战区人员信息的提前缓存,人员组织信息的提前缓存和基础数据预计算结果的缓存等等,所有涉及到数据量大并且频繁使用的数据,我们都会进行预处理和存储在两个缓存当中,这样能够有效地提高系统的响应速度和降低出错率。
人员信息和人员的组织信息主要是调用公司的ORG接口,如果选择实时调用接口,那么性能将会有一定的影响,而且这样我们将严重依赖于第三方,一旦ORG出错我们也会受到波及,所以我们选择使用两级缓存结构来降低这种风险。第一,我们是提前缓存数据,一旦出错我们能在业务人员使用前解决掉(数据同步时间是每天凌晨);第二,我们使用了两级缓存结构,二者同时出错的概率极小,而且响应性能肯定是比接口好的,还有可以预先根据业务场景组织数据。其他基础数据的预加载和这个是一个思路。
方案相关操作的异步化是指创建方案和编辑方案时,由于涉及的表操作和缓存操作较多,如果同步构建缓存和同步更新数据库很有可能造成超时,即使不超时,响应时间也是非常长的,影响用户体验。所以当创建或是修改方案时只是将前端的入参合理组装之后便插入到任务表中,然后通过调度引擎扫描任务表更新方案信息和构建缓存,同时更新任务表状态。
计算引擎的设计我们借鉴了Hadoop中的计算模型(Map-reduce)的设计理念。如图9所示,在Map阶段,我们对薪资表达式先进行参数级别的下钻。图中的参数1指的是业务人员的指标奖金考核项,可依赖于指标类数据项(包括基础指标、复合指标、主观指标及在职奖金基数类统计指标)。
此处实现了参数粒度的并行计算,接下来再进行指标级别的下钻。若该处的指标为复合指标时,计算引擎会继续下钻到基础指标级别;待所有的指标计算结果就绪后,会触发计算引擎的回溯计算流程(类似Hadoop中的reduce过程),依赖于各指标的参数因子会被计算并保存。当各参数因子准备就绪时,直接生成绩效最终结果。
图9 计算引擎
展望
我们最终的目标是将Hermes系统工具化、平台化,增强系统数据的可视化能力和可分析能力,指导战区制定更加合理化、人性化的激励性更强的考核方案;对于业务人员来说,提供指导性和针对性更强的指标业务导向,提升工作效率,进一步增强美团酒旅业务在行业中的竞争能力。
后续,我们计划使用数据挖掘和机器学习等手段提升系统的智能化水平,以数据为依托,业务人员业绩产出为目标,指导修正已有的绩效考核方案。针对现有系统的不足,我们也将努力修正,例如数据源管理方面,针对指标来源分散导致的管理难的问题,我们将引入起源,统一管理指标数据,降低系统复杂度。总而言之,我们的目标就是要做一个稳定的,高效的绩效系统,欢迎加入我们!
作者简介
联系客服