聊聊缓存重构的事儿,老系统缓存和数据库数据同步,现在改为按需加载。。要死

2018-08-24 17:09:34 +08:00
 FeifeiJin

我们以前的系统,缓存和数据库同步修改。 系统启动时,加载必要数据到内存里。 所有底层业务都基于缓存数据来进行的。

比如,查询,只从缓存里取,这个倒好改,改成缓存没取到,其查数据库就好了。 删除,它时优先删除缓存里的,根据 key 删除一个缓存对象,并且返回这个缓存对象,再取数据库删除这个对象。

1,现在要先删除数据库,再删除缓存。 2,工作量巨大,各种细枝末节的地方。 3,所有的逻辑都是基于缓存的,没得缓存层改动的逻辑真时多到吐血。

v 友们, 是否有相似经历?

3679 次点击
所在节点    程序员
23 条回复
rushssss
2018-08-24 17:37:30 +08:00
为啥要这么改
akira
2018-08-24 17:51:30 +08:00
是内存不够 i 还是程序启动太慢,不是必须的话 没必要去改的啊
metrxqin
2018-08-24 18:00:13 +08:00
20% 的数据 80%的时间都在使用。
FeifeiJin
2018-08-24 18:42:25 +08:00
FeifeiJin
2018-08-24 18:45:36 +08:00
@akira
有做集群,现在启动太慢了。挂了的话,不能迅速启动。
假设我现在有 A/B 两个节点,其中一个挂了,导致另一个负载上升,随之久挂了。
这个时候再启动 C,可能要花半小时。
改完后 B 挂了,可以立即启动一个 C 来支撑运行。
要保证加载速度,所以这样改。
FeifeiJin
2018-08-24 18:46:01 +08:00
@rushssss
做了集群,启动太慢。挂了重启太耗时。
FeifeiJin
2018-08-24 18:46:31 +08:00
@metrxqin
赞成。
lovedebug
2018-08-24 18:47:22 +08:00
启动的时候全加载到缓存,只会让老的挂的更快。不如做成多级缓存。另外用的 redis 吗
FeifeiJin
2018-08-24 18:55:58 +08:00
@lovedebug
以前就是启动的时候全加载了,现在改了。
Redis 也在改造计划中。

可以理解为内存的压力现在部分分散到数据库和 Redis 中。
但没做多级缓存。Redis 和现在 Memory 是同级别的。
HuHui
2018-08-24 19:30:31 +08:00
可以参考红薯的 j2cache
FeifeiJin
2018-08-24 19:54:11 +08:00
@HuHui 看了下。思路可行。
但我们是 .net 的项目。
sagaxu
2018-08-24 19:56:49 +08:00
@FeifeiJin 你需要的是热备,不能 abc 都启动吗?挂掉一个,剩下两个也能抗住,有足够时间慢慢恢复。
swulling
2018-08-24 19:58:57 +08:00
这就是业务层去做缓存逻辑的弊病。

业务层应该看不到缓存,直接操作。缓存是底层数据层自己实现的。这样改缓存逻辑。只需要改底层就好了。
keramist
2018-08-24 20:01:30 +08:00
系统架构有问题 三台服务器负载均衡 挂一台还有两台顶着 最好四台 万无一失
ghos
2018-08-24 22:09:46 +08:00
@swulling 其实我觉得应该是根据业务来定义缓存内容,数据层并不知道这个数据适不适合缓存,但是缓存存取逻辑应该由框架统一处理 不应该由手写代码处理。
swulling
2018-08-24 22:28:41 +08:00
@ghos 可以传入一些控制参数给数据层,但是使用缓存的方式要做到和没有缓存一样才好。
cheava
2018-08-24 22:47:19 +08:00
之前看《大型网站架构演化》作者提出了统一数据访问模块,包括了缓存和数据库的访问处理,业务无感地获取数据,目前也没看到有相应的开源方案或框架
gemini767
2018-08-25 12:42:38 +08:00
@swulling 过于理想化了,db 肯定要有缓存,但那也应该是热点数据。而不应该来承载整个业务的缓存,业务有自己逻辑,写缓存和读缓存业务并不相同。反而数据由于统一底层承担增加数据损坏的风险。
yunshansimon
2018-08-25 14:36:27 +08:00
那要看你的数据操作使用那个级别的对象。最差的情况下,数据操作没有单独的界面,缓存操作充斥各个对象。按照以下步骤进行重构:1.重写一个缓存对象,100%复制原来的从对象名到接口 api 的规范,包裹原来的缓存对象,然后,不做任何修改,转发到原来的 api 上,上线测试。目的:用于找出所有使用的 api。2.为新的缓存对象建立 hook api,类似 before_xxx,和 after_xxx 的调用。将调试日志写到 hooks 里,保证 hooks 都可用。3.将新逻辑写到 hooks 里面。
ljzxloaf
2018-08-26 07:23:10 +08:00
1.有必要,因为先删缓存再删数据库,数据库失败就 gg ;而先删数据库,即使缓存删除失败也就影响一段时间。可以搜下 58 沈剑的相关博客 2.抽象一下缓存逻辑,也可以找找这类开源框架。这是很普遍的业务场景,早就有成熟方案了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/482945

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX