redis使用啥的就不说了,网上资料很多,本文主要讲使用缓存的一些设计模式;
以下几个缓存模式,本身是微软用在操作系统中的,此处借用来用于微服务中也是合适的;文末有微软的链接;
缓存的重要性:磁盘一次操作10 ms左右,内存一次操作65 ns左右,1 ms = 10^6 ns,差了好几个量级
1.read-through读穿透模式
应用读取数据,只读取缓存数据;缓存自己保证与数据库的同步性
2.write-through写穿透
应用数据只写入缓存,由缓存自身保证同步到数据库;
3.write-behind
应用数据只写入缓存,缓存自身保证但是不立即同步到数据库,会有一定延时,批量写入
参考write-behind
4.cache-aside
这种模式,是用在没有缓存框架保证上述三种模式时,用来模仿上述三种模式;
也是平常业务系统最常用的模式;
增:写数据库;
删:删数据库,然后失效缓存;
改:更新数据库,然后失效缓存
查:命中缓存则返回;不命中数据库,则查询数据库,同时更新缓存;
注:缓存设计要注意缓存雪崩、缓存穿透、缓存击穿问题
5.实例一
背景:业务中有一批和门店相关数据,每天只更新1-2次,但是查询QPS极高
模式:低频更新、高频查询的数据,cache-aside;
6.实例二
背景:业务中有一批动态数据,一批用户实时产生,一批用户在app上实时查询,增删改查QPS都非常高;
模式:高频更新、高频查询的数据,采用write-behind + read-through模式
使用两个缓存:写缓存、读缓存
高频更新、高频查询
7.实例一+实例二
背景:一般业务系统,实例一和实例二都是同时存在的;
方案:缓存设计两个,一个读缓存+一个写缓存,同时满足实例一和实例二中数据;数据库可以分别写到不同的业务系统中去;
当然,上面的设计模式是存在很多并发问题的:
比如高频更新模式,某条数据,缓存已失效,这会如果读数据并且更新缓存,不是一个原子性操作,中间有个GC停顿啥的就更久了;这两个操作中间,如果数据库中数据被更新,那么最终更新到缓存的是过期数据;
当然,概率不大,当时必须要考虑到这点;
那是要去解决这个问题吗?虽然你可能通过更复杂的事务模式,鬼斧神工地去保证事务性,但是复杂度太高,做一次容易,业务一直保持正确难,不太建议那么干;我建议你避开它,上述模式使用必须进行业务判断是否允许少量此种情况出现;
有些业务场景强依赖数据正确性比如金额计算啥的,就不能用缓存来做;
而应该使用强事务性的数据库;
金融行业推荐蚂蚁的OceanBase
当然,还有个更好用的工具去更新缓存:databus了解下,追数据库日志,并解析操作;
参考资料:
https://docs.microsoft.com/en-us/azure/architecture/patterns/cache-aside
网友评论