2.1 业务场景:千万工单表如何实现快速查询
本场景中的客服系统承接的是集团的所有业务,每条业务线的客服又分为多个渠道,有电话、在线聊天、微信、微博等。
它的业务流程是这样的:当客户接线进来以后,不管是通过什么渠道,客服都会登记一个客服工单,而后再根据业务线、工单的类型来登记不同的信息;工单创建后,会按需创建其他的单据,比如退款单、投诉单、充值单等,针对每个该工单的处理动作或工单关联单据的处理动作,也会自动添加工单处理记录和更新处理时间。
系统已经运作了5年左右,已有数据量大,而且随着集团业务的扩大,业务线增加,客服增多,工单数量的增长也越来越快,在系统中查询工单,以及打开工单详情的时候,就会出现响应速度很慢的情况。
一开始客服只是偶尔抱怨,后来抱怨的次数慢慢增多。但是之前客服这个板块的优先级不高,所以那些抱怨基本都被忽略了。
在一次集团战略会议上,客服的负责人又提到了这个问题,称其已经影响了客服的工作效率。会后,集团领导意识到了问题的急迫性,启动了客服系统的整改项目。
项目组调研了查询慢和工单详情打开慢的问题,具体情况如下。
1)查询慢。当时工单数据库里面有1000万左右的客服工单时,每次查询时需要关联其他近10个表,一次查询平均花费13秒左右。
2)打开工单慢。工单打开以后需要调用多个接口,分别将用户信息、订单信息以及其他客服创建的单据信息列出来(如退款、赔偿、充值、投诉等)。打开工单详情页需要近5秒。
因为以前做过冷热分离,所以项目组人员脑海中第一个思路就是,能不能把不常用的工单数据移到其他数据库?
但是这次不一样了,因为向客服调研的时候发现,有些工单的处理会涉及诉讼,所以周期很长,比如一个3年前建的工单最近还在处理。项目组问客服,这是不是个例,客服说不是,这种工单还不少。又问客服,是不是只有涉及诉讼的工单才会拖这么久?客服说,基本是这样。
项目组就有了一种思路:针对投诉类型的工单,不做冷热分离,其他类型的工单处理后归档冷数据库。
但是进一步调研以后才发现,还有个工单类型转换的场景,即原本客户只是咨询,沟通中发现了问题,然后就转投诉了,但是系统设计的功能中,是不能修改工单类型的。也就是说,有些客服工单表面上只是咨询,其实是投诉。
这样冷热分离的方案就不合适了,因为再继续下去,这个方案会跟业务耦合很深,对业务代码的影响面会变得很大。
还有个思路:读写分离。
这个思路是这样的:MySQL有个主从架构,可以将所有对工单表的写操作转入MySQL的主库,所有对工单表的查询操作连接到MySQL的从库。读写分离的好处就是,读的请求和写的请求针对不同的数据库,彼此不会抢占数据库资源。而且,主库用InnoDB的存储引擎,从库用MyISM,MyISM不支持事务,但是性能更好。
但是,使用这个方案得到的工单查询速度提升有限,所以最终没有采用。它主要还是用在数据库高并发的场景中。
最终采用的是查询分离的解决方案,即将更新的数据放在主数据库里,而查询的数据放在另外一个专门针对搜索的存储系统里。
对于主数据库,因为数据的更新都是单表更新,不需要关联也没有外键,而且不会被查询操作占用数据库资源,所以写的性能就没有问题了。数据的查询则通过一个专门处理大数据量的查询引擎来解决,它的优点就是能够实现快速查询。
接下来详细介绍一下这个方案。