近一年多没在博客园写东西了,从换公司后就一直努力学习公司的框架和业务。而今接手一个电商数据统计项目,在博客园搜索统计项目解决方案却一无所获,最终自己设计并在开发的过程中持续更新,希望可以和大家一起交流。
需求
项目组的电商系统运行了3年多,每天下单量在2w单左右。
1.要求从商户,客户,商品的角度统计每天,每月,任意天数查询的需求。
2.并对部分敏感数据做实时查询,例如下单数,下单金额之类的指标。
3.对客户,商品交易额交易量指标做top并支持导出。
4.按地域统计各个交易指标并做top。
5.不能在原有的系统上做集成,防止影响主业务。
设计思路
服务器采用windows2012 IIS7.5 .netfromwork4.0 数据库是部分sqlserver和部分mysql 基于目前系统的状况和需求,决定采用触发式预统计方式来完成部分重要功能。
何为触发式? 目前多个系统之间通信有消息中间件来处理业务。例如 下单,下单时创建订单后就直接往消息系统中注册一条创建订单任务,任务系统会分发给对应执行者去执行下单相关的后续任务。
根据消息系统的特性,在不掺和主系统的情况下利用下单,支付,等业务触发,完成数据的收集,处理,这就是触发式。
非实时部分
关于预统计呢,其实只要是统计,都绕不过这个方法。数据少的时候我们统计一般采用全表查询,count,groupby等形式来得出结果。但大多数情况下,会重复获取大量数据,每次都统计一遍,不但耗时,而且在数据库性能,数据传输,超时等问题上都是不能容忍的。
因此我们会总结,将可以增量统计的部分采取一点一滴的叠加,每天统计增量数据,将合理的数据结构存储起来(半成品),下次统计或者查询的时候直接查半成品,不仅数据量少,而且不用遍历原来的表。特别是电商系统,每天增量数据大,多会采用分库分表的方式来提高数据库性能和访问速度,但是却给统计造成了困扰。
实时部分
对于部分实时性要求高的指标,就需要我们达到流式计算的要求了。一样采用触发式的任务,在任务中维护一个全局的内存变量,不同商家也可以区分开,另外由于数据实时性和内存大小考虑,需要一个定时推送redis,一个定时定量去移除存储到数据库。
关于定时定量,是指内存中累积到一定个数比如客户交易商品累计到100或者离上次存储已经过去1分钟,这个时候就会触发存储规则。推送也一样,说是实时,但是不可能有变化就推送到redis,那这样用redis就没有意义。按我的想法是每个有交易的商家每分钟推一次,下单任务触发后根据上次推送时间来决定,如果没有交易当然就不推送。
库表设计
统计项目的库表我采用的是查从库,从库拥有和主库一样的表结构,并且只读不写。在分表原则上 将表设计为待统计表,预统计表,按月统计表 按月存储表 并根据数据量分表,让每个表中预期数据不超过1千万,我将部分数据量大的表分为128张,少量的分为16张
极限情况下可以分库,来提升连接数。
流程设计
在提升系统性能和响应速度方面,会采用长缓存+短缓存的方式。例如 不变通用的数据采用长缓存(2-24小时),实时要求敏感数据(1-5分钟)
对于部分慢的地方还可以采用首页缓存,默认参数缓存等方式来提高页面打开速度。
消息系统架构
触发式统计是建立在消息中间件的基础之上的,因此将它的架构和设计思路贴出来,供大家参考和借鉴。消息系统的存在主要有几点好处,1.解耦系统之间的依赖 2.异步执行耗时任务 3.具有可靠的日志和重试机制 4.可分布式部署横向扩展
统计任务中心
触发式统计的核心有两个,一是消息系统 二是统计任务中心。它的职责主要是收集交易数据,管理预统计结果并推送(redis和数据库)。已下列支付为例,它在全局中单例,并负责收集数据,管理(统计,存储,推送)
总结
这一次,我将统计项目的大体结构和设计思路分享了出来,目前项目还未正式开始 ,后期可能会做调整,改掉不合理的设计。我打算将统计项目作为一个系列,在实现的途中分享,也希望有人能获益,有人能给予指点。