搜文章
推荐 原创 视频 Java开发 iOS开发 前端开发 JavaScript开发 Android开发 PHP开发 数据库 开发工具 Python开发 Kotlin开发 Ruby开发 .NET开发 服务器运维 开放平台 架构师 大数据 云计算 人工智能 开发语言 其它开发
Lambda在线 > SegmentFault > 缓存架构的理论分析

缓存架构的理论分析

SegmentFault 2017-11-28

问题背景

略谈服务端缓存设计 一文说到缓存不是必须的,因为数据库本身就利用了内存。但实际情况是缓存是大型网站的标配。

虽然经验显示 RDBMS 最快时只需 0~1ms 就能响应,不逊于专门的缓存,但是当压力增大时,性能的下降也是飞快的。随着业务的逐渐复杂、开发团队的逐渐扩大,难以全面优化所有的 SQL,数据库内存的命中率难免下降。

数据库的连接数是有限的、磁盘的并发能力也很差(一块磁盘才一个磁头),因此当访问量增大或数据库内存命中率下降,平均响应速度会陡然下降;更糟的是,某些查询导致大量的冷数据换入并占用数据库内存(例如全表扫描),真正最需要的热数据暂时被挡在内存外,等到 1~100 ms(或更久)之后才能重新被读入数据库内存,到这种时候,压力可能爆棚了。

  • MySQL 的 buffer_pool_hit_rate 指标统计了命中率。

  • MySQL 有类似于分代 LRU 的机制,按这个链接调优能有所缓解。

以上分析告诉我们:缓存架构要满足冷热分离的特征——RDBMS 不满足,因为冷数据可能挤走热数据。

另外,众所周知,缓存架构还要满足读写分离的特征——RDBMS 也不满足,因为写操作会争抢读操作的资源。

鉴于这些局限性,RDBMS 终归还是顶不住,缓存成为大型网站的标配就是顺理成章的了。

方案选择

略谈服务端缓存设计 一文还比较了本地缓存和分布式缓存,首推分布式缓存。那么就要选择一款缓存系统。而且强烈建议预先考虑水平扩展,如果先用了单机方案,之后很难不关机就在线迁移到基于 sharding 的集群方案。

缓存系统的选择,我随手列一些典型方案(没有每个都用过),分成三系:
Memcached 系:Twemproxy,Couchbase(自动维护集群)
Redis系:Twemproxy,Codis/RebornDB(自动维护集群),官方的 Redis Cluster(慎用)
Java系:Apache Ignite(自动维护集群,支持多种语言,兼容 Memcached API),基础性能低于前两系,但支持 SQL 查询、事务和丰富的数据结构,还能远程执行代码、推送事件通知、对接本地缓存/数据库 /HDFS 等。同类产品有 Hazelcast、Gemfire。

应用代码怎么写?通常是:读操作先 get 缓存,若没有,查数据库,并且 set 缓存;写操作直达数据库,并且 delete 缓存。这种风格称为直写式缓存。

  • 为避免重复代码,可以利用 AOP:Java 可用 Spring Cache,另外 Hibernate 可自动管理缓存;支持高阶函数的语言自带 AOP,把数据操作变成闭包,外层包一个处理缓存的函数。

还有一种风格称为写回式缓存,读写操作都走缓存,由缓存来负责与数据库同步。这种风格需要缓存系统的支持。

结语

以上对问题背景和方案选择都做了分析,尤其触及一些知识盲点,然而这只是理论。
是的!鉴于实际环境的复杂性(即使是本篇文章也无法反映真实情况),最推荐的做法仍然是实测!根据真实的应用场景来设计你的缓存架构!(并不是只能线上实测,可以在测试环境尽量模拟。)

最后再推荐一些相关文章:

Pinterest谈实战经验:如何在两年内实现零到数百亿的月访问

微博“异地多活”部署经验谈

The Log: What every software engineer should know about real-time data’s unifying abstraction

以上文章可点击阅读原文。

版权声明:本站内容全部来自于腾讯微信公众号,属第三方自助推荐收录。《缓存架构的理论分析》的版权归原作者「SegmentFault」所有,文章言论观点不代表Lambda在线的观点, Lambda在线不承担任何法律责任。如需删除可联系QQ:516101458

文章来源: 阅读原文

相关阅读

关注SegmentFault微信公众号

SegmentFault微信公众号:segmentfault_sudo

SegmentFault

手机扫描上方二维码即可关注SegmentFault微信公众号

SegmentFault最新文章

精品公众号随机推荐

下一篇 >>

缓存