背景说明:
博主现在所在的公司是做医疗SAAS服务的,因为面向的是客户,所以在做进销存的时候会产生大量的数据。导致查询非常耗时,轻则服务响应超时,严重甚至导致数据库任务阻塞,资源耗尽宕机。
问题描述:
需求就是查询指定时间期间内期初,期出入库,期末,的出入库数据以及对应时间点的成本本等信息。
我们来看看博主接手之前的处理方案
最初版:
第一版的同事最初写需求是用的常规处理办法, 根据出入库数据推导得来。这种方案在数据量不大的单体应用上时没有问题的。但是因为是saas,一个诊所的出入库数据不算多,但是如果是一千家,一万家诊所呢,诊所每开一个个方都会影响多个药的进销存数据?这时候问题就出现了,随着用户量的增加,服务开始查询超时。
第二版:
这时候项目开始优化,既然推导过程过于复杂,那么我们就把启动一个定时任务,每天凌晨自动统计当天的库存以及进销存数据,作为当天的一个快照保存起来。这样以后查询的时候就少了推导的过程,只需要计算期间的数据就够了。典型的空间换时间方案。经过一段时间的运行,问题又出来了,每个诊所大概五百个药,如果是一千家诊所,每天需要向着快照表中插入约50万条数据,一个月下来就是1500万。渐渐的,效率越来越低。问题甚至比第一版更加严重。
最终版:
mysql查询效率不够,那么我们引入搜索引擎来应对各种条件查询。对于第二种数据量大的问题,我们来采用降低统计频率的方案来解决数据量过大的问题。详细操作方案如下:
降低快照表采集频率 ----- 从每天一次,降低到一个月一次。这样快照表的数据量大概会降至方案二的1/30.如下是优化后,由2400多万变成了90多万。
查询指定时间段库存时,期初由当月1日库存 与一号至查询开始时间段的出入库计算得来,期末同理。
引入ELK----- es搜索引擎对条件查询非常支持非常友好。内存查询,效率很快。LogStash自动采集,自动同步数据,自动实现数据同步(略微牺牲了实时性)。
最终结果,查询时间控制在400毫秒左右
具体搭建步骤后续更新。。。。。