V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
seraphv3
V2EX  ›  Java

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

  •  
  •   seraphv3 · 356 天前 · 5144 次点击
    这是一个创建于 356 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

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

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

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

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

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

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

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

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

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