常见性能优化策略的总结( 四 )


b.遍历上述商户配送范围列表,将其中的商户ID去重,保存到集合中 。
c 。根据上述商户ID集合批量获取对应的商户集合 。
d 。遍历上述商户集合,从中获取每个商户对象,并进行相应处理(根据是否已经是热门商户、自营、在线支付,判断是否需要插入或更新之前的商户和控制区域,等关系) 。
e 。删除此控制区域中不应存在的当前业务关系列表 。
分析代码,找到步骤2中的步骤a和b,找出与某个控制区域相交的配送范围集,并对商户ID进行去重,可以使用R-tree空间索引进行优化 。具体方法是:
本次优化已在第一阶段优化启动,整个流程时间从40多分钟缩短到20分钟以内 。
第一阶段优化改成R-tree后,跑了一段时间 。随着数据量的增加,性能开始逐渐恶化,一个月后已经恶化到50多分钟 。于是我继续深入分析代码,找到了两个优化点,安排了第二阶段的优化并上线了 。
两个优化点是:
发布后
通过日志观察,将执行时间从50多分钟缩短到15分钟以内 。下图为一天四台机器的日志时间(单位:毫秒):
可以看出效果还是很明显的 。
案例2:POI缓存设计与实现
背景
2014年Q4,数据库中POI(这里可以简单理解为外卖店)相关数据的读取流量急剧增加 。虽然增加从节点可以解决一些问题,但毕竟节点的增加会达到极限是的,达到极限后,主从复制会达到瓶颈,这可能会导致数据不一致 。因此,此时迫切需要引入新的技术方案来分担数据库的压力,减少数据库POI相关数据的读取流量 。另外,任何场景下考虑添加DB从库都会造成一定的资源浪费 。
实施计划
基于现有久经考验的技术方案,我选择了Tair作为缓存存储方案,帮助DB分担各种应用POI数据读取流量的压力 。原因主要是从可用性、高性能、可扩展性、是否通过在线大数据和高并发流量的考验、是否有专业的运维团队、是否有成熟的工具等方面 。
详细设计
初版设计
缓存的更新策略,根据业务的特点,现有的技术方案和实施成本,选择使用MQ接收POI变化的消息来触发缓存的更新,但是这个过程可能失败;过期策略,调用者会先判断是否过期 。如果过期,它会从后端DB加载数据并设置回缓存,然后返回 。缓存数据的可用性通过两方面的双重保险来保证 。
第二版设计
第一版设计运行一段时间后,发现两个问题:
在某些情况下,无法保证数据的实时一致性(例如技术人员手动修改DB数据,使用MQ更新缓存失败) 。这时候只能等待5分钟的过期时间,有些服务是不允许的 。加上过期时间会导致另一个问题:Tair 会在缓存未命中的那一刻尝试从硬盘加载数据,如果硬盘没有去 DB 加载数据 。这无疑会进一步延长Tair的响应时间,不仅会增加业务的超时率,还会导致Tair的业绩进一步恶化 。
为了解决以上问题,我们从美团点评基础设施负责同事那里了解到,在某些情况下缓存数据不一致的问题是可以解决的,并且可以去掉过期时间机制,从而改进查询效率和避免tair in查询硬盘未命中 。并且为了防止单点故障影响我们的业务,我们保留了之前用MQ消息更新缓存的方案,做了一个切换,使用这个方案进行容错 。整体架构如下:

常见性能优化策略的总结

文章插图
发布后
上线后,通过持续的数据监测发现,随着调用次数的增加,到DB的流量明显减少,大大减轻了DB的压力 。同时,这些数据接口的响应时间也显着降低 。缓存更新的双重保障机制也基本保证了缓存数据的可用性 。见下图: