从13年7月份开始,就一直呆在微博部门进行效果广告的后台配套系统的开发,很荣幸,作为一位实习生,能真正的参与到项目中去,还是很有收获的,有必要把这几个月自己所做的事稍微总结一下,理清一下思路。
可能有些东西涉及到公司隐私,所以我不会详细的去描述。此随笔仅供各位看官学习交流之用,请勿转载,请勿用于其它目的,如引起纠纷,请自己负责。
言归正传,我刚到部门的时候,微博正在进行商业化,刚经历了几个月的封闭开发,广告平台已经大体成型,但是缺少一些对广告效果的监控。我的工作主要是负责这个。
技术上,其实说白了,就是对数据库的增删改查(而且一般只涉及到查)。那这么说,就更加简单了,查数据库——整理数据——前台显示。是的主体就是这么三步。其实就是通俗意义上的信息系统。
接下来,说说我们刚开始碰到的问题,随着系统的开发,查询条件越来越复杂,需要显示的数据也越来越多,产品和运维的人希望全面详细的了解整个平台每小时,每天,每个月的各个终端等等详细情况,还需要了解某些个订单,广告主的实时广告消耗情况等等。伴随着系统功能的不断增加,某些查询也越来越耗时了,而且当你有很多的查询语句,而且查询时间越来越长,会对线上的系统的稳定性产生影响,当然可以有从库,加索引等等优化查询语句的办法,在一定程度上可以提高数据库响应时间,但是终究不是一个长久之计。
另一方面,刚开始设计数据库的时候,我们尽量满足第三范式,考虑节约内存,节约数据传输大小,实时响应等等各方面,但是碰到查询的时候,就会带来一些问题,有时候为了查询一个广告主的所有订单,你可能要通过先查询广告主的所有计划,然后从计划表中获取所有的订单,然后再去订单表中查询具体的订单信息,这种查询语句,想必大家看起来都会嫌恶心的,当然可以用join,但是合适么,我是不太看好这种方式的,尤其是还涉及到数据库的量,速度,各种事务等等。当然是个人习惯问题,我比较喜欢干干净净的sql语句,不崇尚特别复杂的SQL语句,也不崇尚特别复杂的代码,好的代码必然是非常清晰的,仅仅是个人理解。
从上面两方面,原本是一个为了查询的“附赠”系统,却要开始改变整个广告系统主体了,当然这也是非常有必要的,起码组长也是非常认同的,那说说我们具体是怎么改变上面这些矛盾的,上面的那些个矛盾可能也不全。
1. 修改部分原有的数据库表,多增加一些冗余字段,我只是查的功能,那这就需要增“删”修这三方面都做一些改变。而且从这个项目中也可以体会到,数据库表的设计,第三范式不一定是最好的,有时候做一些冗余,会带来很多的方便。
2. 针对产品,运维等相关人员提出的各种数据要求,新增一个数据库,专门做统计需求,将计费,广告等信息通过php脚本,同步到新的统计库中,并在统计库原始表的基础上,增加各种脚本,做统计,形成各个统计表。凡是做过数据统计的人应该都知道,开发人员最讨厌的就是统计数据,因为这个数据的东西,它是不允许有错误的,数据哪怕有一点不对,就得查问题。
3 在新建了统计库的基础上,我们有很多的脚本在周期性的做着统计工作,这里得保证各个脚本正常的运行,数据的正确,当前系统定时运行的脚本可能已经有20多个了。可以理解为从两个源头流出的数据经过一个个管道到达了一个个表,而且从某一方面来说,监控系统,也必须带有一些监测的功能,而最好的反应系统运行情况,就是各种数据,一旦数据出了什么问题,我们能否马上查到问题的所在。这里引出了,我们是如何解决这些的。首先,说一些常识性的东西,随着脚本的增多,脚本的命名,各个脚本的分类,放在各自的文件夹当中,各个脚本运行都需要在一些关键的点上打日志,脚本运行其实涉及到两种,正常运行和数据恢复,每个系统或多或少会有一些bug,我这边的数据算是最底层的数据了,一旦我的前面有一些异常,就直接影响到了我这边的数据,所以有些时候,就会涉及到数据恢复,那伴随着脚本的增多,像这种从源头数据就已经有问题,我就需要运行N个脚本,而且是有一定的顺序,来恢复数据,这里就需要在编写每个脚本的时候,考虑是不是还需要再编写一个错误数据恢复的脚本,这样脚本的量一下子有翻倍了,当然有些脚本,没办法,就得用两个脚本,但是有的脚本,其实是可以用一个脚本来实现的,只需要输入一些参数控制好了。另外,又新增了一个脚本控制中心,这个root型的脚本就是用来控制和运行所有的脚本的,如果我们要数据恢复,只需要运行这个脚本,输入相应的控制参数,好了,它会自己去恢复的,然后我们再校对一下数据就ok了。
4 脚本的监控,数据的监控是不可避免的,这里其实是两个需求,一个是脚本是否是正常运行了,另一个方面是数据是否符合预期。脚本的是否正常运行,只需要读取待同步的表和同步的表,看看数据是否一致就可以了。但是如果要对每个表都做这样的操作,就显得有点多余了,而且在能省查询语句就省的原则上,我是采用了从原始表,到末端表数据进行一致性判断,如果一致,那就表明这一条数据流上,脚本运行正确,数据没有问题,如若不然,它会告警,然后我就会去查各个脚本运行的log,当然新部署一个脚本,肯定会多做一些一致性判断,到后来基本稳定之后,就没必要了。通过这种方面,能最少的查询,判断数据是否有问题。另外,我们采用了两个数据来源,两个数据来源数据一般情况下不会出现太大的误差,其实一个数据来源是计费数据,另一个是日志数据,计费数据只需要关注扣的钱(当然肯定不仅仅只有这个)就行了,日志数据就会含有一些其他的详细信息,那我们就会将这两个数据来源的数据进行比较(相当于对原始数据的比较),误差过大就开始告警,告警这一模块,就利用一些微信,邮箱接口等等。
5. 通过以上的几部,现在基本上形成了一个闭环,从新业务上线,产生数据,数据分析,数据监控等等。而且对于我们查找问题也给出了很大的参考性,举个例子,如果发现数据异常了,而我这边没有收到脚本同步之间的告警,那么可以直接跳过我这边的检查,在根据两个数据来源的比较,和往期数据的比较,发现日志上数据不对,查找是谁新上了东西么?做了哪些修改,哪些数据不正常,而不是像无头苍蝇一样从头开始查问题,可以很快发现问题,很快定位问题。通过上面的脚本跑统计数据,也满足了产品各项查询数据要求,扩展性还可以,当然肯定还会有更好的做法,但是目前这是个不错的设计。
差不多从宏观角度来讲的就这些了,如果涉及到技术,倒反没有什么了,都是mysql+php+js+html,也没有涉及到很复杂的算法,很高深的技术,能解决问题的不一定是高深的技术,而且针对不同问题的不同思路。