Don‘t Put a Cache in Front of Database
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。
本作品 (李兆龙 博文, 由 李兆龙 创作),由 李兆龙 确认,转载请注明版权。
引言
这篇文章是看到西雅图大佬推的一篇文章以后产生的一些想法。paper本身很有意思,即为什么不建议把 Cache 放置在Database前面,这其实是一个与我个人传统认知相悖的一个题目,事实上在我还不知道数据库到底是什么东西的时候就听过做JavaWeb的同学讨论“Redis + MySQL”的组合了,而且在大概一年以前我在[1]这篇文章中也讨论过Facebook对于Memcache的一些扩展[2],其中就有提到facebook如何解决缓存数据库之间一致性的问题(没错,这个问题至少九年前已经被研究透了),也侧面反映出数据库前放置缓存的普适性与广泛程度,而且这在数据库无法保证SLA是确实是一种有效的提升性能的方法,这些过的经验都让这个问题变的更加吸引人,更加想让人对它去做层层拆解。
这篇文章是对《7 Reasons Not to Put an External Cache in Front of Your Database》的一个学习,虽然内容其实有点广告的意思,但是分析的也是头头是道,简略的博客可以参考[3],更详细的版本有一个PDF,需要的同学可以私我。
为什么需要缓存
很简单,DRAM的访问延迟往往在纳秒级别,而SSD在微秒级别,更不必说HDD的毫秒级别了。但是事情并没有这么简单,很久很久以前有 Phil Karlton 说过这样一段话:
There are only two hard things in Computer Science: cache invalidation and naming things.
目前主流的外部缓存方案主要有两种:
即 Side Cache 和 Transparent Cache,前者以Redis,MemCache最首,最广为人知;后者则是DAX[4]最受欢迎。
前者最大的问题在与缓存一致性的维护,这个需要业务去做,但是这本就是一件比较魔幻的事情,因为这让业务去做本不属于业务该做的事情。当然不需要用户维护一致性这也是DAX这种透明的做法的优势所在。
原因
文中给出七点不应该的原因:
- 外部缓存会增加延迟
- 外部缓存增加了不必要的成本
- 外部缓存会降低可用性
- 应用程序复杂性-您的应用程序需要处理更多情况
- 外部缓存破坏了数据库缓存
- 外部缓存使数据安全变得复杂
- 外部缓存忽略了数据库缓存能力和资源
首先假设我们的开发人员很优秀,其次不考虑钱,那么1,3,5,7是最令人值得思考的事情。
首先我们把第一点和第五点结合起来看,文中提到当数据不在缓存中时将请求发送到数据库,这会导致两跳的数据库延迟,而且现实中我们很难把缓存刚好放在用户和DB实例之间(突然想起TCP公平性,我翻了十几分钟,仍然没有找到我印象中的那篇文章,遂重新找到一篇意思相近的文章供读者做参考[10],顺便致敬下dog250大神),这意味着更高的网络延迟,而且因为访问基本发生在缓存服务器中,还导致了DB本身的缓存其实是冷的,进而导致这个请求响应的更慢了(可能涉及到SSD/HDD的访问)。
其次第七点也很有意思,以我相对比较熟悉的Redis举例子,其内存淘汰机制比较固定[5][6],看了下最新的代码,还是老几样:
我们知道普适的策略在极端场景大概率不是我们最想要的,因为业务和Database的复杂性,只有用户自己和Database本身知道如何去做缓存淘汰是最有效的,这种side cache的方案很难在缓存淘汰策略上达到最优,尤其是近些年DB for AI的流行,动态调整的优势愈加明显,其次Database还对命令有感知,这也侧面说明一个数据库本身的Cache应该是具有复杂的判断以及极端的优化做支撑的,其带来的优势应该显著高于side cache这种普适的方案,
DynamoDB Accelerator(DAX)
[4]中提到DAX适合如下场景:
- 需要低响应时间的业务
- 热点明显的应用
- 读取请求占总请求比例较高
- 不需要强一致性
可以看出还是和一般缓存系统一样,最大的优势还是不需要用户去处理一致性相关的事务,关于其一致性模型可以参考[8];其次在热点情况下会更适合一些(这种热点解决也是一种原始的方案,官网也写了,异步复制嘛,没啥说的),说起热点问题,就想起了欢神[9],yyds请允许我亲吻您的脚趾以表达敬意
总结
凡事总有trade-off,多快好省是几乎不可能的(慨慷大佬我想你这辈子也看不到这篇文章了),归根结底,用户第一,技术第二,当用户需要的时候一个技术上来讲辣鸡的东西那也是宝,理论与实际往往隔着十万八千里,又不是不能用,如此浅显易懂的道理你当然听懂了。
经理正好走到办公室门口,滑了一下,滑跌了,可能是皮鞋底子不是牛筋底吧,但由于领带没有和西装固定在一起,所以领带保持在原来的高度,给人的感觉就是领带好像飞起来了一样,可是皮鞋的方向也变化了。
浙江温州皮鞋湿,下雨进水不会胖。
还有,敲代码这么有意思的一件事情,还给钱23333。
参考:
- facebook技术探究之基于memcache的扩展
- Scaling Memcache at Facebook
- 7 Reasons Not to Put a Cache in Front of Your Database
- In-Memory Acceleration with DynamoDB Accelerator (DAX)
- Using Redis as an LRU cache
- Redis源码解析(6) 键的过期处理策略
- LRU-K,2Q,LIRS算法介绍与比较
- DAX and DynamoDB Consistency Models
- 2017双11技术揭秘—分布式缓存服务Tair的热点数据散列机制
- 漫谈bufferbloat以及TCP公平性
- 漫谈TCP加速的笑话