写了一个开源的面向数据库 IO 的零冗余数据缓存框架,希望大佬们给些意见

2022-06-29 17:49:28 +08:00
 Kould

业余时间花了一年左右写了一个开源缓存框架 Kache ,主要用于以类似 Spring cache 的使用方式下沉到数据库持久化操作。可以将有限的空间放大应用于更多的缓存上,增强缓存命中率和降低缓存变动成本 仓库地址: https://gitee.com/Kould/kache

希望各位大佬多多给予意见,能 star 或推荐一下!

1773 次点击
所在节点    Java
15 条回复
guisheng
2022-06-29 18:34:28 +08:00
关注一下 开源不易加油,估计后面会被抄袭一个版本
Kould
2022-06-29 18:41:58 +08:00
@guisheng 感谢支持,不过请问抄袭是指 fork 吗
dqzcwxb
2022-06-29 22:05:06 +08:00
看了下文档,你想复用在 redis 里面的数据,有一点拙见想说一下
有没有想过一个问题,哪怕是一样的数据他们的刷新时间和策略是不一样的,比如说 A 和 B 用户的数据相同在你的框架里被指向了同一个数据,但是此时 A 要清空数据那么问题来了 A 和 B 的数据是同一个,A 删除数据 B 也没了,A 不删除数据那么数据怎么判定为空后重新拉取刷新?
类似的问题应该还有很多,感觉会很影响业务
fpure
2022-06-29 23:09:05 +08:00
这玩意儿花了一年?你是怎么做到的
NoBugDie
2022-06-30 00:05:54 +08:00
已 star ,有空来研究一下
Kould
2022-06-30 09:47:35 +08:00
@dqzcwxb 本身定位的话仍然是主要面向数据库 IO 的,而您说的问题大多是牵扯到外键,本身这个框架是可以与 Spring Cahe 结合,可以做到 Spring Cache 负责 Service 层用于外键的 Bean 装填处理,而 Kache 应当做好的是对数据库的一层旁路,用于最大化避免数据重新走入数据库之中,目前 Kache 对于数据的感应都是通过应用的,也是兼容分布式的,但是如果是外置工具操作数据库的话确实可能会导致数据变化而 Kache 无法感知,后继有使用 binlog 等手段的可能。
简而概之就是尽可能不要要外键填充的操作放入的持久化操作之中,否则持久化的方法难以复用并且会导致数据千变万化,Kache 本身注解有个 involve 属性用于干涉其他 Bean 类型缓存的清除,但尚未有完美解决这个问题的方案
Kould
2022-06-30 09:48:51 +08:00
@fpure 项目驱动学习,原型只是一个 AOP ,再逐渐变成 spring starter 再分离变成 Proxy 与 spring starter
fzdwx
2022-06-30 09:49:55 +08:00
@Kould 昨天看到老哥 star 了我写的 `websocket spring boot starter`哈哈,好巧。
Kould
2022-06-30 09:52:12 +08:00
@fzdwx 因为看到了你的浏览记录,感觉 websocket spring boot starter 很不错,所以 star 了一下
dqzcwxb
2022-06-30 09:52:24 +08:00
@Kould #6 所以这个问题其实没法完全参考 jvm 里的对象管理概念,因为业务缓存的一致性不仅仅是在于数据内容还有过期时间和刷新策略所以单纯的用数据内容做对比去实现复用会出现问题
如果要强行解决这个问题,应该是需要在 update 的同时进行判断是否需要 insert 新的数据跟旧数据分离,这又会带来新的原子性问题
感觉很难完美处理,期待你的解决方案
Kould
2022-06-30 10:02:17 +08:00
@dqzcwxb 在过期时间上的处理话,在存入缓存时会先向 redis 中去重,得到缺少的数据再存入,而重复的 id 则会延长存活时间。而刷新策略目前属于较为悲观的该类型所有索引缓存全删,不过相对于 spring cache 的缓存删除成本来说小很多。目前的数据冗余判断依据是依照数据库中主键的概念,做不到非常深层次的数据重用。
dqzcwxb
2022-06-30 10:27:39 +08:00
@Kould #11 "而刷新策略目前属于较为悲观的该类型所有索引缓存全删"你这句话让我想到这篇讲 myabtis 二级缓存的文章 https://blog.csdn.net/isea533/article/details/44566257
Kould
2022-06-30 10:39:04 +08:00
@dqzcwxb 是的,这就是我所不满意 Spring Cache 所作的:“将命名空间下所有缓存删除”;这篇文章中“针对一个表的某些操作不在他独立的 namespace 下进行。”这句话也就是之前所说外键之间的无奈,所以我仍然认为 service 中进行外键数据填充操作是最佳实践。
不过言归正传,Kache 因为缓存实体是分离的,对于条件方法之间的缓存是以索引的形式再次指向实体的结构,因此当实体更新时不会像 spring cache 将缓存全盘删除,而是仅仅将多个条件方法的“索引缓存”(类似一个 list<指针>)删除掉,相较于 spring cache 来说可以避免缓存的重复序列化而可以再删除后写入缓存时只需要存入索引缓存即可,避免数据序列化和冗余。并且因为获取缓存脚本与本身缓存结构,缓存删除与读取是无锁并行的。
THESDZ
2022-06-30 16:08:31 +08:00
好家伙,倒序索引?那可以优化 参数->id 这个映射,参考 elasticsearch bitmaps/roaring bitmaps
Kould
2022-06-30 19:09:52 +08:00
@THESDZ 学习到了,非常感谢

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

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

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

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

© 2021 V2EX