Redis 热 key 与 TTL 的处理清单
Redis 在项目里跑起来之后,缓存命中率看着不错,并不代表系统就稳了。到 2021 年很多内容和后台服务都会碰到两个更现实的问题:某几个 key 被打得特别热,以及 TTL 设得过于随意,导致缓存失效节奏非常难看。
Redis 在项目里跑起来之后,缓存命中率看着不错,并不代表系统就稳了。到 2021 年很多内容和后台服务都会碰到两个更现实的问题:某几个 key 被打得特别热,以及 TTL 设得过于随意,导致缓存失效节奏非常难看。
很多项目第一次做 webpack 缓存优化,都会先把文件名改成带 hash,觉得这样浏览器就能长期缓存了。这个方向没错,但如果 chunk 划分本身不稳定、运行时代码老是跟着变化、公共依赖和业务代码混在一起,最后会发现缓存命中率并没有想象中高。
webpack 开始提示包太大以后,很多人的第一反应是“那我多写几个 import() 吧”。动态导入当然是重要工具,但如果拆分点没有顺着页面路由和功能边界走,只会把一个大包拆成很多难管理的小包,首屏和切页体验未必真的更好。
webpack 的性能优化很容易让人一上来就陷入“经验动作”:先怀疑 UI 组件库,再怀疑图片,再想办法加几个拆包配置。可如果还没看清产物里到底是什么占了体积,这些动作大多只是碰运气。真正有效的优化,通常都从一份可读的打包分析开始。
Java 集合一学到 ArrayList 和 LinkedList,很多人就会形成一个很顺手的印象:前者适合查,后者适合增删,于是当某段代码出现“可能会插入删除”的需求时,就很自然地想把 LinkedList 搬出来。可真到业务代码里,这个选择远没有口诀那么简单。
刚开始学 Go,并发部分最容易让人紧张的词就是“死锁”。这当然没错,因为死锁一出现,程序常常会非常明显地挂在那里。可等你真正把 Go 服务跑起来一段时间后,会发现另一类问题更难受:goroutine 没有马上死掉,而是在后台一点点堆起来。
很多人学 Java 时,最先熟悉的就是 String、ArrayList、HashMap 这些基础类。也正因为太熟了,项目里反而经常是在它们身上出问题。不是因为类本身复杂,而是因为大家太容易“顺手就用”,很少停下来想当前场景到底合不合适。
带坐标的数据一多,最常见的需求之一就是“按距离最近排序”。
很多人一开始会先把经纬度查出来,再在应用层自己算距离、自己排序。小数据量时确实能跑,但 2016 年我在看这类场景时越来越觉得,所有距离计算都堆在应用层,其实是在主动放弃数据库已经能帮你做的一部分工作。
2016 年做接口优化时,缓存几乎是最容易被提起的方案。接口慢了,加缓存;数据库忙了,加缓存;列表页扛不住了,还是加缓存。可真正做过几轮之后,我反而越来越谨慎,因为缓存很少是“开了就完事”的提速按钮。
2014 年做内容站和后台系统时,MongoDB 很吸引人,原因很简单:模型灵活、起步轻、开发速度快。可一旦列表页慢下来,很多团队的第一反应都是“是不是该上副本集”“是不是该多加几台机器”。我后来发现,这种反应往往太快了。