seraphv3
V2EX  ›  Java

Spring data JPA 开启二级缓存,分布式部署一般用什么方案?

  •  
  •   seraphv3 · Jan 5, 2024 · 10395 views
    This topic created in 1032 days ago, the information mentioned may be changed or developed.

    本小白程序员是写 java 的,但是工作了多年,用到真正的面向对象技术的机会比较少,所以去年自己做了一个面向对象的简单 demo 项目。

    https://zhuanlan.zhihu.com/p/605481077

    用的 Spring data JPA ,比较能够符合面向对象的风格。所谓 JPA ,java persistence architecture ,这个 persistence 就很有面向对象的味道,对象活在内存中,但是也需要在合适的时候持久化到数据库。

    不过 Spring data JPA 的二级缓存才是活在内存中的对象,如果要分布式集群部署服务,一般怎么实现二级缓存的对象共享呢?

    45 replies  •  2024-01-07 19:46:44 +08:00
    fkdog
    fkdog
    Jan 5, 2024
    1
    为什么要上二级缓存?
    wysnxzm
    wysnxzm
    Jan 5, 2024
    2
    jetcache
    seraphv3
    seraphv3
    OP
    Jan 5, 2024
    3
    @fkdog 没有二级缓存的话,每次查询操作都是查库重新创建对象,而不是直接查内存中的对象,感觉不是真正的面向对象
    seraphv3
    seraphv3
    OP
    Jan 5, 2024
    4
    @wysnxzm 感谢感谢,我学习下
    fkdog
    fkdog
    Jan 5, 2024
    5
    @seraphv3 加不加缓存跟是不是面向对象又有什么关系。
    fkdog
    fkdog
    Jan 5, 2024
    6
    @seraphv3 看你的描述是感觉对 jpa 、hibernate 并不熟悉。
    建议是没经验还是别折腾这个,把控不好,缓存事务一致性可以让你喝一壶的,往严重说了就是生产事故了。
    二级缓存你可以在服务层或者展示层实现。
    seraphv3
    seraphv3
    OP
    Jan 5, 2024
    7
    @fkdog 我理解的面向对象,对象都是活在内存里的,只是在必要时候才持久化到数据库
    Ayanokouji
    Ayanokouji
    Jan 5, 2024
    8
    缓存就用 redis 吧,多实例也能生效
    fkdog
    fkdog
    Jan 5, 2024
    9
    @seraphv3 6666
    shigure00
    shigure00
    Jan 5, 2024
    10
    @seraphv3 不明白你为什么会这么理解
    quainter
    quainter
    Jan 5, 2024
    11
    完全错误的面向对象理解
    seraphv3
    seraphv3
    OP
    Jan 5, 2024
    12
    @shigure00 面向对象是要有一个类图,形成对象模型的嘛,对象模型是可运行的,就需要对象存活在内存里面啊
    Plutooo
    Plutooo
    Jan 5, 2024
    13
    你是不是把面向对象的“对象”和 Java 虚拟机中堆内存中的“对象”给搞混了,二者并不是一个概念
    seraphv3
    seraphv3
    OP
    Jan 5, 2024
    14
    @Plutooo java 的对象不就是面向对象的实现嘛
    Leviathann
    Leviathann
    Jan 5, 2024
    15
    请求过来然后从数据库里查询出来不就进到内存里了?
    aibx01
    aibx01
    Jan 5, 2024
    16
    不要执着于 面向对象 还是 非面向对象。

    想想自己要处理什么问题。
    如果要做分布式集群部署。那么就是需要一个统一的缓存中心。redis 支持集群部署并且与应用实例无关。
    你使用二级缓存相当于每台机器都部署一个 redis 。这些缓存无法保持同步的更新,无法保持同步销毁。除非你手写代码进行支持哈。
    seraphv3
    seraphv3
    OP
    Jan 5, 2024
    17
    @Leviathann 每次都查库,如果还有 @OneToMany 等多级关联查询,性能是个问题

    QQ 群里有老哥说级联查询不会走二级缓存,不知道是不是真的

    [少侠] 精通所有技术的马总监(568662344) 17:29:14
    级联操作 不走缓存 findById 索引操作 没有必要走缓存

    [少侠] 精通所有技术的马总监(568662344) 17:29:33
    结论 使用 springDataJPA 不需要关注自身的缓存
    seraphv3
    seraphv3
    OP
    Jan 5, 2024
    18
    @aibx01 工作中没有用过 Spring Data JPA ,只是学习下
    daybreakfangyang
    daybreakfangyang
    Jan 5, 2024 via Android
    19
    你想要对象一直活着?
    28Sv0ngQfIE7Yloe
    28Sv0ngQfIE7Yloe
    Jan 5, 2024
    20
    @daybreakfangyang

    OP 似乎是需要映射数据库表实体的( tableInfo )对象一直存活
    maojun
    maojun
    Jan 5, 2024 via iPhone
    21
    @seraphv3 qq 号起码删了吧
    seraphv3
    seraphv3
    OP
    Jan 5, 2024
    22
    @maojun 完了,没想到,现在删不了了。。。
    seraphv3
    seraphv3
    OP
    Jan 5, 2024
    23
    @daybreakfangyang 是的,我是这样希望的,对象创建出来之后,除非被删掉,期望它一直活着
    NickX
    NickX
    Jan 5, 2024
    24
    “我理解的面向对象,对象都是活在内存里的,只是在必要时候才持久化到数据库”

    看到你对面向对象的理解,我瞬间不知道怎么跟你解释。
    nxforce
    nxforce
    Jan 5, 2024
    25
    缓存一致性又如何解决?
    cnhongwei
    cnhongwei
    Jan 5, 2024
    26
    个人建议不要使用二级缓存,而是使用 Spring cache ,当然过期处理复杂一些。
    likooo125802023
    likooo125802023
    Jan 5, 2024
    27
    ~~~ 真幸福。。。

    当年啥缓存都是我们自己写的。
    NeroKamin
    NeroKamin
    Jan 5, 2024
    28
    1.建议重新理解一下面向对象的概念
    2.缓存一致性是更大的问题
    Mmahaha
    Mmahaha
    Jan 6, 2024
    29
    面向对象是对标面向过程的,不是你说的这个意思
    keepRun
    keepRun
    Jan 6, 2024
    30
    二级缓存处理起来坑爹,要优化性能显然是找到瓶颈去优化,将高频性能损耗点手动加上 redis 缓存即可大大优化性能,而且往往这种优化点不会特别多,封装好了方法后使用起来非常方便、易于理解、支持分布式。
    nnegier
    nnegier
    Jan 6, 2024 via Android
    31
    @NeroKamin 可以讲讲一致性吗?我也很头疼一致性
    siweipancc
    siweipancc
    Jan 6, 2024 via iPhone
    32
    别用,缓存只用来计算结果跟文件处理。
    你顶多用上 hibernate 的 es 跟 env 两个特性。
    bthulu
    bthulu
    Jan 6, 2024
    33
    orm 要什么缓存, 缓存在你接口处实现
    yogogo
    yogogo
    Jan 6, 2024
    34
    @seraphv3 #23 回收机制了解下,单例模式了解下,OOM 了解下,查询缓存了解下,你再回来看看你在说啥内容
    skwyl
    skwyl
    Jan 6, 2024
    35
    @seraphv3 面向对象是面向对象,缓存是缓存,二级缓存其实很烦,不建议使用,我现在就是 hibernate 内存飙升,实际上大多数情况都用不到这个缓存,需要缓存的地方说明得引入 redis 等缓存中间件。
    skwyl
    skwyl
    Jan 6, 2024
    36
    @seraphv3 关于你这个级联查询问题,@OneToMany 确实是直接查数据库的,但是我非常不建议你在实体里面做级联,累一点引入一下 Service 维护起来会好很多,在实体里面做级联非常考验你们表结构设计的合理性,而且不易于维护。
    seraphv3
    seraphv3
    OP
    Jan 6, 2024
    37
    @skwyl 我测试了下,@OneToMany 级联的对象也有二级缓存,不知道 QQ 群的老哥是怎么测试的。实体类里面做级联我认为是实现模型层的一个主要方法,不然你就没有对象模型了
    seraphv3
    seraphv3
    OP
    Jan 6, 2024
    38
    @skwyl 当然也可以手动查库之后加载构建对象模型,这就可以不用 jpa 了。或者你不要对象模型,那就跟直接查库,查库之后手动放 redis ,其实相当于一个不完整的对象模型放在 redis 内存里面,手动维护对象间的关联关系
    stone981023655
    stone981023655
    Jan 6, 2024
    39
    性能不够了再说吧, 不是开始该考虑的问题
    dongzhuo777
    dongzhuo777
    Jan 6, 2024
    40
    @seraphv3
    Spring data JPA 的二级缓存,就是个坑。少看点培训班的视频那玩意没用,写 demo 知道原理的实现就行了。
    做 ToB 项目,用 Spring data JPA 。只是约束下面的人用 HQL ,纯粹是为了解决同时支持国产/mysql/sqlserver/oracle 。
    findbyId 这种方法在我这边一律禁止用。
    数据库就是用来持久化的保证最后的一致性的。等有了性能问题 二级三级缓存自己用别的中间件去写啊。
    生产项目上用这些别人的二级缓存后面怎么死的不知道的
    dongzhuo777
    dongzhuo777
    Jan 6, 2024
    41
    @seraphv3 不要用 @OneToMany 这些 这些都没用,后面性能和缓存会出大问题,这些都是以前 Hibernate 搞出来的。
    那玩意是为了让程序员不用了解 sql 和数据库直接写代码,单这种只针对那种很小的项目没多少业务复杂度和并发量。
    但实际情况是
    以目前 java 、Spring 的体量,能选型用到 java+Spring 的项目肯定是很重业务且规模较大的项目
    如果你用了这些什么 jpa 二级缓存 @OneToMany 。这些学了要么用不上,要么不能用
    java 老老实实研究多线程、网络、jvm 、还有相关的中间件生态更有用,数据库就让它老老实实的 CRUD 做好最后的持久化工作就行了。
    dongzhuo777
    dongzhuo777
    Jan 6, 2024
    42
    面写对象是一个编程的方式或者方法论,对标的是面写过程,要学面写对象 这个 去学设计模式。
    我理解上是,对于哪怕是面向过程的 C ,也有一个结构体,那玩意就是个简单的类。
    C 也是可以按照面向对象的方法来写代码,但是得不偿失
    szq8014
    szq8014
    Jan 7, 2024
    43
    我比较理解楼主的想法,尤其是楼主 PO 的链接内容,我看上面评论的大约也没几个人打开那个链接。对编程的理解,每个人经历不一样,想法更不一样。比如早些年的 asp(没有 .net) 以及 php ,都是把编程语言几乎当成是数据库的脚本来用的,功能无非就是把用户的请求转成一个个的 sql 查询捅到数据库里面,再把查出来的数据沉浸一下就 OK ,好多项目就是这样过来的,又不是不能用,我甚至觉得一定程度上这样也是个非常平衡、稳定的方法。只不过这跟面向对象就没啥关系了,不如叫面向数据库编程。
    面向对象这块本人不才也只知一二,所以看到楼主的想法的时候其实是有共鸣的。按照面向对象的理念来说,希望有一个层或框架或工具能够把数据持久化这块给管理起来,而可以让开发人员把更多的精力放在代码和类的组织上。目前 Spring Data 框架也在往这块努力,比如一个 Entity 你调一下注释就可以把数据从 RDBMS 里面挪到 Redis 里面。
    写这么多只是想给楼主打打气,我有和你一样的困惑,加油
    szq8014
    szq8014
    Jan 7, 2024
    44
    s/沉浸/渲染/g
    seraphv3
    seraphv3
    OP
    Jan 7, 2024
    45
    @szq8014 老哥太实在了,握手
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   5106 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 103ms · UTC 07:42 · PVG 15:42 · LAX 23:42 · JFK 02:42
    ♥ Do have faith in what you're doing.