缓存写入失败是影子体系 导致的吗(写入缓存战略 无法更改)〔缓存写入失败怎么解决〕

  本文要感谢我职级评定过程中的一位评委,他发起 把之前所做的各种性能优化的案例和方案加以提炼、总结 ,以文档的情势 沉淀下来,并在内部举行 分享 。力图 到达 如下结果 :

  1. 形成可实践 、可鉴戒 、可参考的各种性能优化的方案以及选型思量 点,同时共同 具体 的真实案例,其他人碰到 相似题目 时 ,不消 从零开始。

  2. 有助于开阔视野,除了性能优化之外,也能提供通用的常见思绪 以及方案选型的思量 点 ,资助 各人 作育 在方案选型时的意识、头脑 以及做各种衡量 的本领 。

  文章在内部分 享后,引起猛烈 分享,得到了不少同事和朋侪 的承认 和好 评 ,以为 对一样平常 的工作有很好的引导 作用。思量 到这些履历 大概 对业界偕行 也有资助 ,以是 在美团点评技能 团队博客公开 。

  常见性能优化战略 分类

  代码

缓存写入失败是影子系统导致的吗(写入缓存策略无法更改) 缓存写入失败是影子体系
导致的吗(写入缓存战略

无法更改)〔缓存写入失败怎么解决〕 新闻资讯

  之以是 把代码放到第一位,是由于 这一点最轻易 引起技能 职员 的忽视。很多 技能 职员 拿到一个性能优化的需求以后 ,言必称缓存、异步 、JVM等。实际 上,第一步就应该是分析相干 的代码,找出相应的瓶颈 ,再来思量 具体 的优化战略 。有一些性能题目 ,美满 是 由于代码写的不公道 ,通过直接修改一下代码就能办理 题目 的,比如 for循环次数过多、作了很多 无谓的条件判定 、雷同 逻辑重复多次等。

  数据库

  数据库的调优 ,总的来说分为以下三部分 :

  SQL调优

  这是最常用 、每一个技能 职员 都应该把握 根本 的SQL调优本领 (包罗 方法、工具、辅助体系 等)。这里以MySQL为例,最常见的方式是,由自带的慢查询日记 大概 开源的慢查询体系 定位到具体 的出题目 的SQL ,然后利用 explain 、profile等工具来渐渐 调优,末了 颠末 测试到达 结果 后上线 。这方面的细节,可以参考MySQL索引原理及慢查询优化。

  架构层面的调优

  这一类调优包罗 读写分离、多从库负载均衡 、程度 和垂直分库分表等方面 ,一样平常 必要 的改动较大,但是频率没有SQL调优高,而且一样平常 必要 DBA来共同 参加 。那么什么时间 必要 做这些事变 ?我们可以通过内部监控报警体系 (比如 Zabbix) ,定期跟踪一些指标数据是否到达 瓶颈,一旦到达 瓶颈大概 警戒值,就必要 思量 这些事变 。通常 ,DBA也会定期监控这些指标值。

  毗连 池调优

  我们的应用为了实现数据库毗连 的高效获取 、对数据库毗连 的限流等目标 ,通常会采取 毗连 池类的方案,即每一个应用节点都管理了一个到各个数据库的毗连 池。随着业务访问量大概 数据量的增长,原有的毗连 池参数大概 不能很好地满意 需求 ,这个时间 就必要 连合 当前利用 毗连 池的原理、具体 的毗连 池监控数据和当前的业务量作一个综合的判定 ,通过反复的反复 调试得到终极 的调优参数 。

  缓存

  分类

  本地 缓存(HashMap/ConcurrentHashMap、Ehcache 、Guava Cache等),缓存服务(Redis/Tair/Memcache等)。

  利用 场景

  什么环境 适实用 缓存?思量 以下两种场景:

短时间内雷同 数据重复查询多次且数据更新不频仍 ,这个时间 可以选择先从缓存查询,查询不到再从数据库加载并回设到缓存的方式。此种场景较适实用 单机缓存。

高并发查询热门 数据,后端数据库不堪重负 ,可以用缓存来扛 。

  选型思量

假如 数据量小,而且 不会频仍 地增长又清空(这会导致频仍 地垃圾采取 ),那么可以选择本地 缓存。具体 的话 ,假如 必要 一些战略 的支持(比如 缓存满的逐出战略 ),可以思量 Ehcache;如不必要 ,可以思量 HashMap;如必要 思量 多线程并发的场景 ,可以思量 ConcurentHashMap。

其他环境 ,可以思量 缓存服务 。如今 从资源的投入度、可运维性、是否能动态扩容以及配套办法 来思量 ,我们优先思量 Tair。除非如今 Tair还不能支持的场合 (比如 分布式锁、Hash范例 的value),我们思量 用Redis。

  计划 关键点

  什么时间 更新缓存?怎样 保障更新的可靠性和及时 性?

  更新缓存的战略 ,必要 具体 题目 具体 分析 。这里以门店POI的缓存数据为例,来阐明 一下缓存服务型的缓存更新战略 是怎样的?如今 约10万个POI数据采取 了Tair作为缓存服务,具体 更新的战略 有两个:

吸取 门店变动 的消息 ,准及时 更新。

给每一个POI缓存数据设置5分钟的逾期 时间,逾期 后从DB加载再回设到DB。这个战略 是对第一个战略 的有力增补 ,办理 了手动变动 DB不发消息 、接消息更新程序临时 堕落 等题目 导致的第一个战略 失效的题目 。通过这种双保险机制 ,有效 地包管 了POI缓存数据的可靠性和及时 性。

  缓存是否会满,缓存满了怎么办?

  对于一个缓存服务,理论上来说 ,随着缓存数据的日益增多,在容量有限的环境 下,缓存肯定有一天会满的。怎样 应对?

  ① 给缓存服务 ,选择符合 的缓存逐出算法,比如 最常见的LRU 。

  ② 针对当前设置的容量,设置得当 的警戒值,比如 10G的缓存 ,当缓存数据到达 8G的时间 ,就开始发出报警,提前排查问 题大概 扩容。

  ③ 给一些没有须要 长期 生存 的key ,只管 设置逾期 时间。

  缓存是否答应 丢失?丢失了怎么办?

  根据业务场景判定 ,是否答应 丢失。假如 不答应 ,就必要 带长期 化功能的缓存服务来支持 ,比如 Redis大概 Tair 。更细节的话,可以根据业务对丢失时间的容忍度,还可以选择更具体 的长期 化战略 ,比如 Redis的RDB大概 AOF。

  缓存被“击穿 ”题目

  对于一些设置了逾期 时间的key,假如 这些key大概 会在某些时间点被超高并发地访问,是一种非常“热门 ”的数据。这个时间 ,必要 思量 别的 一个题目 :缓存被“击穿”的题目 。

概念:缓存在某个时间点逾期 的时间 ,恰幸亏 这个时间点对这个Key有大量的并发哀求 过来,这些哀求 发现缓存逾期 一样平常 都会从后端DB加载数据并回设到缓存,这个时间 大并发的哀求 大概 会刹时 把后端DB压垮。

怎样 办理 :业界比力 常用的做法 ,是利用 mutex。简单 地来说,就是在缓存失效的时间 (判定 拿出来的值为空),不是立即 去load db ,而是先利用 缓存工具的某些带乐成 操纵 返回值的操纵 (比如 Redis的SETNX大概 Memcache的ADD)去set一个mutex key,当操纵 返回乐成 时,再举行 load db的操纵 并回设缓存;否则 ,就重试整个get缓存的方法 。雷同 下面的代码:

  publicString get(key){ String value = redis.get(key); if(value == null) { //代表缓存值逾期 //设置3min的超时,防止del操纵 失败的时间 ,下次缓存逾期 不停 不能load dbif(redis.setnx(key_mutex, 1, 3* 60) == 1) { //代表设置乐成 value = db.get(key); redis.set(key, value, expire_secs); redis.del(key_mutex); } else{ //这个时间 代表同时间 的其他线程已经load db并回设到缓存了 ,这时间 重试获取缓存值即可sleep(50); get(key); //重试} } else{ returnvalue; } }

缓存写入失败是影子系统导致的吗(写入缓存策略无法更改) 缓存写入失败是影子体系
导致的吗(写入缓存战略

无法更改)〔缓存写入失败怎么解决〕 新闻资讯

  异步

  利用 场景

  针对某些客户端的哀求 ,在服务端大概 必要 针对这些哀求 做一些附属的事变 ,这些事变 着实 用户并不关心大概 用户不必要 立即 拿到这些事变 的处理 惩罚 结果 ,这种环境 就比力 适实用 异步的方式处理 惩罚 这些事变 。

  作用

收缩 接口相应 时间,利用 户的哀求 快速返回,用户体验更好。

克制 线程长时间处于运行状态,如许 会引起服务线程池的可用线程长时间不敷 用 ,进而引起线程池任务 队列长度增大,从而壅闭 更多哀求 任务 ,使得更多哀求 得不到技能 处理 惩罚 。

线程长时间处于运行状态 ,大概 还会引起体系 Load、CPU利用 率、呆板 团体 性能降落 等一系列题目 ,乃至 引发雪崩。异步的思绪 可以在不增长 呆板 数和CPU数的环境 下,有效 办理 这个题目 。

  常见做法

  一种做法 ,是额外开辟 线程,这里可以采取 额外开辟 一个线程大概 利用 线程池的做法,在IO线程(处理 惩罚 哀求 相应 )之外的线程来处理 惩罚 相应的任务 ,在IO线程中让response先返回 。

  假如 异步线程处理 惩罚 的任务 计划 的数据量非常巨大,那么可以引入壅闭 队列BlockingQueue作进一步的优化。具体 做法是让一批异步线程不绝 地往壅闭 队列里扔数据,然后额外起一个处理 惩罚 线程 ,循环批量从队列里拿预设巨细 的一批数据,来举行 批处理 惩罚 (比如 发一个批量的长途 服务哀求 ),如许 进一步进步 了性能。

  另一种做法,是利用 消息队列(MQ)中心 件服务 ,MQ天生就是异步的。一些额外的任务 ,大概 不必要 我这个体系 来处理 惩罚 ,但是必要 其他体系 来处理 惩罚 。这个时间 可以先把它封装成一个消息 ,扔到消息队列内里 ,通过消息中心 件的可靠性包管 把消息投递到关心它的体系 ,然后让这个体系 来做相应的处理 惩罚 。

  比如 C端在完成一个提单动作以后 ,大概 必要 别的 端做一系列的事变 ,但是这些事变 的结果 不会立即 对C端用户产生影响,那么就可以先把C端下单的哀求 相应 先返回给用户 ,返回之前去 MQ中发一个消息即可。而且这些事变 理应不是C端的负责范围,以是 这个时间 用MQ的方式,来办理 这个题目 最符合 。

  NoSQL

  和缓存的区别

  先阐明 一下 ,这里先容 的和缓存那一节不一样,固然 大概 会利用 一样的数据存储方案(比如 Redis大概 Tair),但是利用 的方式不一样,这一节先容 的是把它作为DB来用。假如 当作 DB来用 ,必要 有效 包管 数据存储方案的可用性 、可靠性。

  利用 场景

  必要 连合 具体 的业务场景,看这块业务涉及的数据是否适实用 NoSQL来存储,对数据的操纵 方式是否适实用 NoSQL的方式来操纵 ,大概 是否必要 用到NoSQL的一些额外特性(比如 原子加减等) 。

  假如 业务数据不必要 和其他数据作关联,不必要 事件 大概 外键之类的支持,而且有大概 写入会非常 频仍 ,这个时间 就比力 适实用 NoSQL(比如 HBase)。

  比如 ,美团点评内部有一个对exception做的监控体系 ,假如 在应用体系 发生严峻 故障的时间 ,大概 会短时间产生大量exception数据,这个时间 假如 选用MySQL,会造成MySQL的刹时 写压力飙升 ,轻易 导致MySQL服务器的性能急剧恶化以及主从同步耽误 之类的题目 ,这种场景就比力 适实用 Hbase雷同 的NoSQL来存储。

  JVM调优

  什么时间 调?

  通过监控体系 (如没有现成的体系 ,本身 做一个简单 的上报监控的体系 也很轻易 )上对一些呆板 关键指标(gc time、gc count、各个分代的内存巨细 变革 、呆板 的Load值与CPU利用 率、JVM的线程数等)的监控报警,也可以看gc log和jstat等下令 的输出 ,再连合 线上JVM进程 服务的一些关键接口的性能数据和哀求 体验,根本 上就能定位出当前的JVM是否有题目 ,以及是否必要 调优 。

  怎么调?

假如 发现高峰期CPU利用 率与Load值偏大 ,这个时间 可以观察一些JVM的thread count以及gc count(大概 重要 是young gc count),假如 这两个值都比以往偏大(也可以和一个汗青 履历 值尴尬刁难 比),根本 上可以定位是young gc频率过高导致 ,这个时间 可以通过得当 增大young区巨细 大概 占比的方式来办理 。

假如 发现关键接口相应 时间很慢,可以连合 gc time以及gc log中的stop the world的时间,看一下整个应用的stop the world的时间是不是比力 多。假如 是 ,大概 必要 镌汰 总的gc time,具体 可以从减小gc的次数和减小单次gc的时间这两个维度来思量 ,一样平常 来说 ,这两个因素是一对互斥因素,我们必要 根据实际 的监控数据来调解 相应的参数(比如 新生代与老生代比值、eden与survivor比值 、MTT值、触发cms采取 的old区比率阈值等)来到达 一个最优值 。

假如 发生full gc大概 old cms gc非常频仍 ,通常这种环境 会诱发STW的时间相应加长,从而也会导致接口相应 时间变慢。这种环境 ,大概率是出现了“内存泄漏 ”,Java里的内存泄漏 指的是一些应该开释 的对象没有被开释 掉(尚有 引用拉着它)。那么这些对象是怎样 产生的呢?为啥不会开释 呢?对应的代码是不是出题目 了?题目 的关键是搞明白 这个,找到相应的代码 ,然后对症下药。以是 题目 的关键是转化成探求 这些对象 。怎么找?综合利用 jmap和MAT,根本 就能定位到具体 的代码。

  多线程与分布式

  利用 场景

  离线任务 、异步任务 、大数据任务 、耗时较长任务 的运行**,适本地 利用 ,可到达 加快 的结果 。

  留意 :线上对相应 时间要求较高的场合 ,只管 少用多线程,尤其是服务线程必要 等待 任务 线程的场合 (很多 庞大 变乱 就是和这个痛痒相干 ) ,假如 肯定 要用,可以对服务线程设置一个最大等待 时间 。

  常见做法

  假如 单机的处理 惩罚 本领 可以满意 实际 业务的需求,那么尽大概 地利用 单机多线程的处理 惩罚 方式 ,镌汰 复杂性;反之,则必要 利用 多机多线程的方式。

  对于单机多线程,可以引入线程池的机制,作用有二:

进步 性能 ,节流 线程创建和烧毁 的开销

限流,给线程池一个固定的容量,到达 这个容量值后再有任务 进来 ,就进入队罗列 行 列队 ,保障呆板 极限压力下的稳固 处理 惩罚 本领 在利用 JDK自带的线程池时,肯定 要细致 明白 构造方法的各个参数的寄义 ,如core pool size、max pool size、keepAliveTime 、worker queue等,在明白 的底子 上通过不绝 地测试调解 这些参数值到达 最优结果 。

  假如 单机的处理 惩罚 本领 不能满意 需求,这个时间 必要 利用 多机多线程的方式 。这个时间 就必要 一些分布式体系 的知识了。起首 就必须引入一个单独的节点 ,作为调治 器,其他的呆板 节点都作为实行 器节点。调治 器来负责拆分任务 ,和分发任务 到符合 的实行 器节点;实行 器节点按照多线程的方式(也大概 是单线程)来实行 任务 。这个时间 ,我们整个任务 体系 就由单击演变成 一个集群的体系 ,而且差别 的呆板 节点有差别 的脚色 ,各司其职,各个节点之间尚有 交互。这个时间 除了有多线程、线程池等机制 ,像RPC、心跳等网络通讯 调用的机制也不可少。后续我会出一个简单 的分布式调治 运行的框架 。

  度量体系 (监控 、报警、服务依靠 管理)

  严格 来说,度量体系 不属于性能优化的范畴,但是这方面和性能优化痛痒相干 ,可以说为性能优化提供一个强有力的数据参考和支持 。没有度量体系 ,根本 上就没有办法定位到体系 的题目 ,也没有办法有效 衡量 优化后的结果 。很多 人不器重 这方面 ,但我以为 它是体系 稳固 性和性能保障的基石。

  关键流程

  假如 要计划 这套体系 ,总体来说有哪些关键流程必要 计划 呢?

  ① 确定指标

  ② 收罗 数据

  ③ 盘算 数据,存储结果

  ④ 显现 和分析

  必要 监控和报警哪些指标数据?必要 关注哪些?

  按照需求出发 ,重要 必要 二方面的指标:

接口性能相干 ,包罗 单个接口和全部的QPS、相应 时间 、调用量(统计时间维度越细越好;最好是,既能以节点为维度 ,也可以以服务集群为维度,来查察 相干 数据) 。此中 还涉及到服务依靠 关系的管理,这个时间 必要 用到服务依靠 管理体系

单个呆板 节点相干 ,包罗 CPU利用 率、Load值、内存占用率 、网卡流量等。假如 节点是一些特别 范例 的服务(比如 MySQL、Redis、Tair) ,还可以监控这些服务特有的一些关键指标。

  数据收罗 方式

  通常采取 异步上报的方式,具体 做法有两种:第一种,发到本地 的Flume端口 ,由Flume进程 网络 到长途 的Hadoop集群大概 Storm集群来举行 运算;第二种,直接在本地 运算好以后,利用 异步和本地 队列的方式 ,发送到监控服务器 。

  数据盘算

  可以采取 离线运算(MapReduce/Hive)大概 及时 /准及时 运算(Storm/Spark)的方式,运算后的结果 存入MySQL大概 HBase;某些环境 ,也可以不盘算 ,直吸取 罗 发往监控服务器。

  显现 和分析

  提供同一 的显现 分析平台,必要 带报表(列表/图表)监控和报警的功能。

  真实案例分析

  案例一:商家与控制区关系的革新 job

  配景

  这是一个每小时定期运行一次的job,作用是用来革新 商家与控制区的关系 。具体 规则就是根据商家的配送范围(多个)与控制区是否有交集 ,假如 有交集,就把这个商家划到这个控制区的范围内。

  业务需求

  必要 这个过程越短越好,最好保持在20分钟内。

  优化过程

  原有代码的重要 处理 惩罚 流程是:

拿到全部 门店的配送范围列表和控制区列表 。

遍历控制区列表,针对每一个控制区:

  a. 遍历商家的配送范围列表 ,找到和这个控制区相交的配送范围列表。

  b. 遍历上述商家配送范围列表,对内里 的商家ID去重,生存 到一个聚集 里。

  c. 批量根据上述商家ID聚集 ,取到对应的商家聚集 。

  d. 遍历上述商家聚集 ,从中拿到每一个商家对象,举行 相应的处理 惩罚 (根据是否已是热门商家 、自营、在线付出 等条件来判定 是否必要 插入大概 更新之前的商家和控制区的关系)。

  e. 删除这个控制区当前已有的 ,但是不应该存在的商家关系列表。

  分析代码,发现第2步的a步调 和b步调 ,找出和某控制区相交的配送范围集归并 对商家ID去重 ,可以采取 R树空间索引的方式来优化。具体 做法是:

任务 开始先更新R树,然后利用 R树的布局 和匹配算法来拿到和控制区相交的配送范围ID列表 。

再批量根据配送范围ID列表,拿到配送范围列表。

然后针对这一批配送范围列表(数量 很小) ,用原始多边形相交匹配的方法做进一步过滤,而且 对过滤后的商家ID去重。

  这个优化已经在第一期优化中上线,整个过程耗时由40多分钟收缩 到20分钟以内 。

  第一期优化改为R树以后,运行了一段时间 ,随着数据量增大,性能又开始渐渐 恶化,一个月后已经恶化到50多分钟。于是继承 深入代码分析 ,探求 了两个优化点,安排第二期优化并上线。

  这两个优化点是:

第2步的c步调 ,原来是根据门店ID列表从DB批量获取门店 ,如今 可以改成mget的方式从缓存批量获取(此时商家数据已被缓存);

第2步的d步调 ,根据是否已是热门商家、自营、在线付出 等条件来判定 是否必要 插入大概 更新之前的商家和控制区的关系 。

  上线后结果

  通过日记 观察,实行 时间由50多分钟收缩 到15分钟以内 ,下图是截取了一天的4台呆板 的日记 时间(单位 :毫秒):

  

  可以看到,结果 还是 非常显着 的。

  案例二:POI缓存计划 与实现

  配景

  2014年Q4,数据库中关于POI(这里可以简单 明白 为外卖的门店)相干 的数据的读流量急剧上升 ,固然 说参加 从库节点可以办理 一部分 题目 ,但是毕竟 节点的增长 是会到达 极限的,到达 极限后主从复制会到达 瓶颈,大概 会造成数据不同等 。以是 此时 ,急需引入一种新的技能 方案来分担数据库的压力,低落 数据库POI相干 数据的读流量 。别的 ,任何场景都思量 加DB从库的做法 ,会对资源造成肯定 的浪费。

  实现方案

  基于已有的颠末 检验 的技能 方案,我选择Tair来作为缓存的存储方案,来帮DB分担来自于各应用端的POI数据的读流量的压力。来由 重要 是从可用性 、高性能、可扩展性、是否颠末 线上大规模数据和高并发流量的检验 、是否有专业运维团队、是否有成熟工具等几个方面综合考量决定 。

  具体 计划

  第一版计划

  缓存的更新战略 ,根据业务的特点、已有的技能 方案和实现本钱 ,选择了用MQ来吸取 POI改变的消息来触发缓存的更新,但是这个过程有大概 失败;同时启用了key的逾期 战略 ,而且 调用端会先判定 是否逾期 ,如逾期 ,会从后端DB加载数据并回设到缓存 ,再返回。通过两个方面双保险确保了缓存数据的可用。

  第二版计划

  第一版计划 运行到一段时间以后,我们发现了两个题目 :

某些环境 下不能包管 数据的及时 同等 (比如 技能 职员 手动改动DB数据 、利用 MQ更新缓存失败),这个时间 只能等待 5分钟的逾期 时间,有的业务是不答应 的。

参加 了逾期 时间导致别的 一个题目 :Tair在缓存不掷中 的那一刻 ,会实行 从硬盘中Load数据,假如 硬盘没有再去DB中Load数据 。这无疑会进一步延伸 Tair的相应 时间,如许 不但 使得业务的超时比率加大 ,而且会导致Tair的性能进一步变差。

  为了办理 上述题目 ,我们从美团点评负责底子 架构的同事那边 相识 到Databus可以办理 缓存数据在某些环境 下不同等 的题目 ,而且 可以去掉逾期 时间机制 ,从而进步 查询服从 ,克制 tair在内存不掷中 时查询硬盘。而且为了防止DataBus单点出现故障影响我们的业务,我们保存 了之前接MQ消息更新缓存的方案 ,作了切换开关,利用 这个方案作容错,团体 架构如下:

  

  上线后结果

  上线后 ,通过连续 地监控数据发现,随着调用量的上升,到DB的流量有了显着 地镌汰 ,极大地减轻了DB的压力 。同时这些数据接口的相应 时间也有了显着 地镌汰 。缓存更新的双重保障机制 ,也根本 包管 了缓存数据的可用。见下图:

  

  

  案例三:业务运营背景 相干 页面的性能优化

  配景

  随着业务的快速发展,带来的访问量和数据量的急剧上升,通过我们相应的监控体系 可以发现 ,体系 的某些页面的性能开始出现恶化 。 从用户方的反馈,也证明 白 这点。此时如今 ,有须要 敏捷 排期 ,灵敏 开辟 ,对这些页面举行 调优。

  欢迎 页

需求配景 :欢迎 页是地推职员 以致 总部各种脚色 职员 进入外卖运营背景 的首页,会表现 地推职员 最想看到最关心的一些核心 数据 ,其紧张 性不问可知 ,以是 该页面的性能恶化会严峻 影响到用户体验 。因此,起首 必要 优化的就是欢迎 页。通过相应定位和分析 ,发现导致性能恶化的重要 缘故起因 有两个:数据接口层和盘算 显现 层。

办理 方案:对症下药,分而治之 。颠末 细致 排查、分析定位,数据接口层采取 接口调用批量化、异步RPC调用的方式来举行 有效 优化,盘算 显现 层决定采取 预先盘算 、再把盘算 好的结果 缓存的方式来进步 查询速率 。此中 ,缓存方案根据业务场景和技能 特点,选用Redis。定好方案后,快速开辟 上线。

上线结果 :上线后性能对比图 ,如下:

  

构造 架构页

需求配景 :构造 架构页,采取 了四层树形布局 图,一起出现 加载 ,第一版上线后发现性能非常差 。用户急迫 盼望 对这个页面的性能举行 调优。

办理 方案:经太过 析代码,定位到一个比力 经典的题目 :内里 实行 了太多次小数据量的SQL查询。于是采取 多个SQL归并 成大SQL的方式,然后利用 本地 缓存来缓存这些数据 ,公道 预估数据量和性能,充实 测试后上线 。

上线结果 :上线后性能对比图,如下:

订单关联楼宇页

需求配景 :随着订单量日益增大 ,订单表积聚 的数据日益增多,订单关联楼宇页的性能也日益变差(相应 时间线性上升)。而这个页面和地推职员 的业绩痛痒相干 ,以是 地推职员 利用 该页面的频率非常高,性能日益恶化极大地影响了地推职员 的用户体验。

办理 方案:经太过 析与计划 ,决定采取 当时 已有的订单二级索引月分表来代替 原始的订单表来供前端的查询哀求 ;而且 限定 住筛选的时间条件,使得筛选的开始时间和竣事 时间不能跨月(事先和用户沟通过,可以担当 ,能满意 用户的根本 需求),如许 就只需一个月分索引表即可,通过得当 的功能限定 来到达 性能的调优 。如许 从二级索引月分表中根据各种查询条件查到终极 的分页的订单ID聚集 ,然后再根据订单ID从订单库来查出相应的订单数据聚集 。

上线结果 :上线后发如今 调用量险些 没怎么变的环境 下,性能提拔 显着 ,如下图:

  其他

  除了上面先容 的之外 ,优化还涉及前端、分布式文件体系 、CDN 、全文索引、空间索引等几方面。限于篇幅,我们留到将来 再做先容 。

  图片来自 RoadandTrack

  查察 文章原网址可点击“阅读原文 ”。

  更多技能 博客:美团点评技能 博客。

  PS:正文中标绿的名词均为参考链接,可点击查询 。

  美团点评

  技能 团队

  https://tech.meituan.com

  长按二维码关注我们