前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >缓存的不当使用

缓存的不当使用

作者头像
心平气和
发布2020-09-11 11:30:24
6690
发布2020-09-11 11:30:24
举报

一、背景

最近一朋友做社区重构,社区主要功能有发帖、回帖、查看帖子详情,详情页按不同条件展示回帖(除了预先定义的顺序外,可能每个用户看到的顺序都不一样,组合超过100个),大概的效果如下:

以前用的是开源的代码,存储用的是Mysql,系统也过于臃肿,稍微有点流量系统响应就很慢,所以准备重构。

重构后的方案如下

1、存储还是Mysql;

2、为了提高访问速度,引入MongoDB作为缓存(为什么不用Redis,因为MongoDB多线程,可扩充性好,并且支持较复杂的查询)

Mysql数据表大概如下:

1、帖子表

字段名

类型

字段说明

id

int

主键

user_id

int

发帖用户id

title

varchar(500)

帖子标题

content

text

帖子内容

2、帖子回复表

字段名

类型

字段说明

id

int

主键

tid

int

帖子id

content

text

回复内容

position

int

楼层

上述表格是经过简化版的内容。

存储方面,Mysql存了全量的帖子和帖子回复,MongoDB也存了全量的帖子和帖子回复,之所以这么设计是因为让用户帖子详情页不用访问数据库,提高访问速度。

那为什么只保存在MongoDB里呢,因为MongoDB不支持多表事务,社区的场景插入回复,还有其它逻辑需要处理,所以需要借助Mysql的InnoDB的事务机制保证数据的一致性。

重构后访问帖子详情页顺序如下:

1、根据帖子id从MongoDB获取帖子详情信息,包括标题、内容及发帖时间和发帖人,如果读取不到,直接报错;

2、根据帖子id及当前条件从MongoDB获取帖子回复信息,同样读取不到也报错。

为什么不按分页将每个帖子按页缓存回复呢,因为前面说了整个详情页展示条件非常复杂,可以倒序排,也可升序排,还可以只看作者,有的回复还有权限,如果全部缓存帖子回复列表,则缓存的数据量非常的大。

二、问题分析

经过分析,这样的设计带来几个问题:

1、系统设计比较复杂,因为要保证数据在Mysql、MongoDB中一致,需要做很多的代码进行数据核对、检查;

2、系统可用性差,因为帖子详情页全部读取的是MongoDB,所以如果MongoDB挂了,则整个系统也就挂了,特别是MongoDB对于运维团队还不是特别熟悉的情况下。

有什么更好的方案呢,回到缓存的本质,关于缓存的使用有不少模式,一般来说对缓存不要强依赖,即缓存挂了,整个系统不要挂,让系统打到后端存储并且更新缓存,这样还有最后一道防线,而在这个案例中,将MongoDB当存储用了,并且同时使用两个存储。

如果当缓存用,怎么解决帖子详情页多种组合条件的导致缓存数据太大的问题?其实对于社区这样的场景,主要占内存的是回复的内容,只要解决帖子回复内容只缓存一份就可以了。

改进后帖子详情页逻辑如下:

1、根据帖子id从 MongoDB中获取帖子详情信息,如果获取不到,则从Mysql中获取,并且写回到MongoDB中;

2、根据帖子id从MongoDB中获取当页需要展示的帖子回复id,读取不到再从Mysql回源,并写回到MongoDB中;根据上面获取的回复id再从MongoDB中获取回复的详情,同样如果获取不到则从Mysql回源,并且写入到MongoDB中。

当然在添加、更新回复后,也需要更新相应的回复内容,这样就保证了帖子回复只缓存一份,不会造成缓存的数据量过大的问题。还有非常重要的一点,整个系统没有对缓存强依赖,即使MongoDB挂了,系统还会从Mysql读取数据。最后系统的代码也变得非常简洁。

当然这里还有很多细节需要注意,像如何避免同一时间大量的回源Mysql的问题,这些业内已经有标准的方案,就不在此展开讨论了。

三、案例总结

1、系统设计越简单越好;

2、不要强依赖缓存;

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-03-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员升级之路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 MongoDB
腾讯云数据库 MongoDB(TencentDB for MongoDB)是腾讯云基于全球广受欢迎的 MongoDB 打造的高性能 NoSQL 数据库,100%完全兼容 MongoDB 协议,支持跨文档事务,提供稳定丰富的监控管理,弹性可扩展、自动容灾,适用于文档型数据库场景,您无需自建灾备体系及控制管理系统。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档