缓存脚本优化总结
一、 背景
缓存脚本主要用于更新各渠道的ap缓存、ssid缓存、基站缓存、围栏缓存、蓝牙缓存;优化前主要存在的问题有:
1、脚本更新一次缓存的时间过长,无法在一天内更新完成;
2、版本号更新混乱;
3、常出现流量异常情况;
4、对于SDK的拉取量没有统计指标;
5、监控不完善;
二、 优化内容
2.1 业务层优化
a、优化match计算
优化效果:增加match函数缓存,效率提升3倍左右
优化原因: Match 函数匹配所用到的参数有:ssid名称、ssid通配符,两者存在大量重复的情况,造成相同的参数重复计算。
优化结果:通过观察脚本运行时服务器的各项指标,发现用于匹配通配符的match函数频繁调用,被匹配的ssid名称存在大量重复的情况,所以对match函数匹配后的结果进行缓存,当遇到相同参数时直接返回结果,不会再用额外的资源重新计算,通过记录的缓存命中信息,多次进行调整为合适的缓存大小。
b、修改程序启动方式
优化效果:确保进程每次结束后的系统资源可以被完全回收。
优化原因:脚本原先的启动方式由进程池启动,通过观察与查看日志发现,一个进程更新完一个渠道后,进程所持有的资源并没有释放,导致进程所占的资源越来越大,最后被系统kill;
优化结果:将脚本中的进程池启动方式,修改为信号量的启动方式,它会维护当前并发进程的数量,并确保进程结束后资源会被完全回收,优化后的程序能够完整更新部分渠道。
c、拆分计算、上传程序
优化效果:减少上传文件至七牛的等待时间,上传程序可同时处理多个渠道的多个文件,减少等待充分利用系统资源。
优化原因:生成增量缓存时所产生的文件数量非常多,并且上传到七牛有一定的等待时间,但此时的系统资源占用非常少;由于控制了并发数量,导致当前进程必须等待耗时操作的完成,而其他渠道必须等待当前进程完成后才能更新的情况。
优化结果:将文件上传逻辑拆分出来,共运行10个进程,与计算程序通过redis通信,将本地缓存文件上传至七牛云,此进程作为后台进程一直运行,基本能与计算程序同时完成。
d、拆分城市计算
优化效果:效率提升2倍左右
优化原因:当更新大数据量的渠道时,常因内存溢出而被系统kill,导致一个渠道可能只更新了一部分的缓存,出现数据不一致情况。
优化结果:在更新较大渠道时,将渠道的城市进行分片,一次仅更新渠道的一部分城市,对所有城市分片进行串行更新,最后再将版本号更新,能确保渠道的所有城市所有缓存完整更新,保证数据一致性。
e、优化match匹配数据量
优化效果:效率提升 8-9 倍左右
优化原因:通过观察通配符表发现,表中存在大量重复的通配符数据,导致match函数计算的次数一般都要达到达到几百亿次。
优化结果:将通配符表中的数据去重后再进行匹配,原先需要耗费 8-9 分钟时间,优化后仅需 30秒左右。
f、缓存版本号确认机制
优化效果:确保只有当渠道的所有缓存更新成功后才会更新版本号
优化原因:当版本号先于缓存更新成功之前更新时,会导致SDK不拉取增量缓存,会直接拉取全量缓存,造成流量飙升。
优化结果:给定一个命令行的可选参数,默认为False(不更新版本号),只有当参数为True时,才会更新版本号;若进行了城市分片的渠道,在更新最后一个城市分片时再更新缓存版本号。
2.2 部署两台服务器
优化效果:当前需要进行更新的所有渠道都能够完整更新所有缓存。
优化原因: 渠道中存在数据量级不同的包名,对于量级较大的渠道无法一次性对所有城市的缓存进行更新,而较小量级的渠道为提升效率应一次性更新所有城市的缓存,所以将两种量级不同的渠道分开更新缓存。
优化结果:将数据量级不同的渠道分开维护,较小渠道更新缓存时不进行城市分片,并且并发多个进程一起更新,较大渠道更新缓存时串行的进行城市分片更新,以确保缓存能够完整更新。
2.3 监控、统计指标优化
优化效果:服务器出现空间不足、内存不足等情况时可及时接收到告警,对其进行处理,也能保证缓存更新的数据一致性。
优化原因:可随时观察缓存脚本的异常情况。
优化结果:将服务器各项指标加入 Grafana,并添加阈值告警。
b、七牛日志分析脚本
优化效果:通过发送每日邮件的方式,将今日的缓存拉取流量、拉取次数等指标统计到一个excel文件中,以便观察流量的波动情况
优化原因:可及时发现七牛流量异常的情况,分析出现流量高峰的情况;统计七牛的流量组成;
优化结果:在固定时间内发送邮件,内容包括:
今日流量总量、今日各渠道的总流量、今日各渠道每种类型缓存的总流量、今日缓存总拉取次数、今日各渠道的拉取次数、今日每种类型缓存的拉取次数、今日各渠道每种类型缓存的拉取次数、各渠道每种类型缓存的最后更新时间戳、近三十天 流量和拉取次数的折线图,全量和增量的柱状占比图