V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
orangeChu
V2EX  ›  程序员

关于分布式缓存,有点疑问,不吝赐教

  •  
  •   orangeChu · Jan 28, 2021 via iPhone · 5587 views
    This topic created in 1921 days ago, the information mentioned may be changed or developed.
    如果网站有大数据需要缓存(最大键值可能有 10M 左右,我觉得这么大的数据都缓存,太离谱了,但是实际又需要),有什么好的分布式缓存解决方案吗?
    尝试了一下 memcached,键值太大的时候,读写太慢了。没有自带的本地缓存快。
    小于 1m 的读写速度倒是跟本地缓存速度几乎一样。
    ps:c#开发
    Supplement 1  ·  Jan 30, 2021
    我举个例子来说明我们现在的缓存使用情况。
    比如区域数据,先从数据库把所有的区域数据(大约 5W 条数据的 List 集合)都取出来,放在微软的 WebCache 里。
    然后用到省份的数据时,直接把区域集合拿出来,抽取父级为空的区域数据。
    选完省份后,根据省份,继续拿集合抽取父级为选取省份主键下的市级数据。
    以此类推。

    目前看到框架,用缓存都是这个使用情况。
    Supplement 2  ·  Feb 1, 2021
    再次感谢大家的热心回复。
    针对目前的业务,最后打算用#40 的方案来实现一次:
    每个服务都弄个本地缓存,数据有变动的时候再用 mq 或者 zk 做广播通知,服务收到通知更新缓存。
    51 replies    2021-02-01 13:45:31 +08:00
    hangszhang
        1
    hangszhang  
       Jan 28, 2021
    怎么可能一样, 除开读写速度之外还有序列化与网络 IO 的成本...
    orangeChu
        2
    orangeChu  
    OP
       Jan 28, 2021 via iPhone
    @hangszhang 感谢回复。哈哈,可能我测试的不太严谨,扔本地测试,确实速度相当。哈哈…
    thet
        3
    thet  
       Jan 29, 2021 via iPhone
    数据不能拆开吗
    eason1874
        4
    eason1874  
       Jan 29, 2021
    memcached 默认最大 1M,要手动配置才支持 1M 以上,你确定改配置支持 10M 了吗?为什么不用 Redis,现在好像分布式内存缓存都用这个。

    10M 数据载入内存我觉得正常,内存够用整站载入都没问题。
    laminux29
        5
    laminux29  
       Jan 29, 2021
    为什么要用分布式缓存?
    orangeChu
        6
    orangeChu  
    OP
       Jan 29, 2021
    @laminux29 感谢回复。因为想负载均衡,部署多个站点。缓存要一致。
    orangeChu
        7
    orangeChu  
    OP
       Jan 29, 2021
    @thet 感谢回复。原先用的自带缓存,直接把数据缓存。如果拆开数据,业务逻辑要调整较多,所以想先把分布式缓存用起来,后续再做业务逻辑及数据的拆分。
    orangeChu
        8
    orangeChu  
    OP
       Jan 29, 2021
    @eason1874 感谢回复。已经修改了配置,支持更大的键值存储。因为一开始用的自带缓存,把数据直接缓存,redis 的性能尝试了一下,在没有改变数据结构的情况下,读写性能一般,甚至还没有 memcached 优秀。
    我想尽量这种大数据,直接先缓存起来,把应用先跑起来,后续对业务级数据结构再进行优化。
    但是目前还没想到好的方案来处理。
    melkor
        9
    melkor  
       Jan 29, 2021 via iPhone
    这么大数据,不如考虑共享内存本地缓存
    orangeChu
        10
    orangeChu  
    OP
       Jan 29, 2021
    @melkor 感谢回复。如果站点部署在多个不同的服务器上,实现您说的想法,我需要做点什么?
    Jooooooooo
        11
    Jooooooooo  
       Jan 29, 2021
    10M 就放在本地吧
    orangeChu
        12
    orangeChu  
    OP
       Jan 29, 2021
    @Jooooooooo 感谢回复。但是多站点共享缓存咋解决~~~~(>_<)~~~~
    Jooooooooo
        13
    Jooooooooo  
       Jan 29, 2021
    @orangeChu 用定时推送的方法吧, 比如 2 分钟推一次. 真正用还是从本地拿.
    YouLMAO
        14
    YouLMAO  
       Jan 29, 2021 via Android   ❤️ 1
    10m
    名字叫分布式文件系统
    你应该使用类似 Amazon s3 之类的系统或者协议
    emSaVya
        15
    emSaVya  
       Jan 29, 2021
    缓存都在 redis 按周期刷到进程内 cache 进程内使用只读不写 写更新内容走 log kafka
    tailf
        16
    tailf  
       Jan 29, 2021
    多机共享缓存也不叫“分布式缓存”,分布式指的是缓存本身是由多台机器提供的。

    你这个需求单独部署一台 redis 秒解,10M 无压力。
    orangeChu
        17
    orangeChu  
    OP
       Jan 29, 2021 via iPhone
    @Jooooooooo 好想法!我会尝试一下,再次感谢。
    orangeChu
        18
    orangeChu  
    OP
       Jan 29, 2021 via iPhone
    @tailf 感谢回复。10M 如果直接序列化保存,或者用 set 保存集合,读取的时候速度太慢了。本地缓存几十 ms,redis 要几秒反序列化。
    tailf
        19
    tailf  
       Jan 29, 2021
    @orangeChu 反序列化都要几秒的话,说明数据量过大,不适合做单体缓存了。
    orangeChu
        20
    orangeChu  
    OP
       Jan 29, 2021 via iPhone
    @tailf 是的。数据量确实很大。比如把全国的区域级联数据集合都缓存起来,大概有 5w 条数据。之前都是直接放站点缓存里,倒是很快。多站点共享缓存就痛苦了。
    orangeChu
        21
    orangeChu  
    OP
       Jan 29, 2021 via iPhone
    @emSaVya 目前来看,这个方案应该可行。我会尝试一下。再次感谢您的回复。
    orangeChu
        22
    orangeChu  
    OP
       Jan 29, 2021 via iPhone
    @YouLMAO 是这样吗?我会了解一下,看看是否有帮助,感谢回复。
    zzh7982
        23
    zzh7982  
       Jan 29, 2021
    @emSaVya 直接入 db 就可以了吧,本地定时读 db 更新缓存,多上个 redis 和 kafka 有点复杂
    securityCoding
        24
    securityCoding  
       Jan 29, 2021
    用进程内缓存吧,比如 guava cache+lazyloading,这么大不适合走网络 io
    melkor
        25
    melkor  
       Jan 29, 2021 via iPhone
    @orangeChu 每台机器都搞缓存呗。如果对数据实时性要求不高的话,可以在服务进程启动的时候拉全量数据缓存下来,请求来了只从缓存里找,找不到就拉倒;同时有另一个进程在后台定时把全量数据拉回本地写入共享内存中。
    melkor
        26
    melkor  
       Jan 29, 2021 via iPhone
    @orangeChu 这个方案速度应该是最快的,毕竟是共享内存。但是要仔细设计一下结构,写的时候如果是往后加还好,如果要改中间的数据、甚至要删数据,需要注意加锁(可以简单用文件锁),否则可能直接读到错的数据。
    orangeChu
        27
    orangeChu  
    OP
       Jan 29, 2021
    @melkor 好的,你的方案很具体,太感谢您的回复了。我打算用这个方案来实现一次。
    onion83
        28
    onion83  
       Jan 29, 2021
    是 10Mb 还是 10MB ?如果是后者每秒 10 个并发就打爆千兆网卡 100 个并发打爆万兆网卡!
    ferock
        29
    ferock  
    PRO
       Jan 29, 2021 via iPhone
    @orangeChu #20

    为什么不静态化
    mybyons
        30
    mybyons  
       Jan 29, 2021
    这些数据如果每次只是做 过滤 抽取 取其中的部分子集的话 可以考虑 lua script OR function 直接过滤 这样网络压力会小很多
    zhuawadao
        31
    zhuawadao  
       Jan 29, 2021
    可以走 cdn 吗这个数据
    opengps
        32
    opengps  
       Jan 29, 2021 via Android
    我以前把线上 memcached 用到过一个内核爆满,memcached 对于集群下应用,目前来说确实不像 redis 那么方便
    laminux29
        33
    laminux29  
       Jan 29, 2021
    @orangeChu

    你嫌弃 redis 与 memcached 速度慢,具体是指:

    api 调用延迟高?

    还是每秒吞吐量低?
    orangeChu
        34
    orangeChu  
    OP
       Jan 30, 2021
    @laminux29 感谢回复。速度慢主要是指存储和读取回来后,反序列化成对象或集合,这整个过程的耗时比自带缓存慢。
    orangeChu
        35
    orangeChu  
    OP
       Jan 30, 2021
    @orangeChu 自带缓存用的是微软的 WebCache 。
    orangeChu
        36
    orangeChu  
    OP
       Jan 30, 2021
    @onion83 是的。高并发时,单机器卡爆,站点访问缓慢。原来框架设计如此,搞得我来维护的时候,也很头疼。
    orangeChu
        37
    orangeChu  
    OP
       Jan 30, 2021
    @zhuawadao 感谢回复。之前倒是没考虑到,大数据用 cdn 倒是个不错的方案,后续会考虑一下这个方案。再次感谢。
    orangeChu
        38
    orangeChu  
    OP
       Jan 30, 2021
    @ferock 可以具体说一下吗?我有点不太明白。
    orangeChu
        39
    orangeChu  
    OP
       Jan 30, 2021
    @mybyons 我举个例子来说明我们现在的缓存使用情况。
    比如区域数据,先从数据库把所有的区域数据(大约 5W 条数据的 List 集合)都取出来,放在微软的 WebCache 里。
    然后用到省份的数据时,直接把区域集合拿出来,抽取父级为空的区域数据。
    选完省份后,根据省份,继续拿集合抽取父级为选取省份主键下的市级数据。
    以此类推。

    目前看到框架,用缓存都是这个使用情况。
    yanyimin
        40
    yanyimin  
       Jan 30, 2021   ❤️ 1
    每个服务都弄个本地缓存,数据有变动的时候再用 mq 或者 zk 做广播通知,服务收到通知更新缓存
    ZiLong
        41
    ZiLong  
       Jan 30, 2021   ❤️ 1
    可以构造多级缓存,一级用本地,把最热的数据放里面(可以设定个 1m,LRU 更新),二级放 redis/memcached 都行,一般一开始不要用分布式,10M 的缓存都不算大.但是不建议放一个 key 里面,大 key 和热 key 是性能杀手,按某个规则(比如不同省份,不同城市)作为 key
    ferock
        42
    ferock  
    PRO
       Jan 30, 2021 via Android
    @orangeChu #38

    你是前端使用还是后端用?地区信息一般后端不需要的吧
    mybyons
        43
    mybyons  
       Jan 30, 2021
    感觉你要重新设计 key
    ”业务逻辑调整较多“ 不影响你重新设计 key 对外的接口协商好 具体内部怎么实现 外部看不到
    orangeChu
        44
    orangeChu  
    OP
       Feb 1, 2021
    @ferock 感谢回复。数据比较多都是前端用,后端一般用到用户信息。
    orangeChu
        45
    orangeChu  
    OP
       Feb 1, 2021
    @mybyons 是的。有这个打算。要重新整理一下。
    orangeChu
        46
    orangeChu  
    OP
       Feb 1, 2021
    @yanyimin 感谢回复。目前打算用这个方案了。
    pavelpiero
        47
    pavelpiero  
       Feb 1, 2021
    @yanyimin 做过类似的骚操作,不过用的是 redis 的订阅发布 一样的道理
    ferock
        48
    ferock  
    PRO
       Feb 1, 2021   ❤️ 1
    @orangeChu #44

    那你生成一个 json 文件走 cdna 给前端自己解析不就好了
    boowx
        49
    boowx  
       Feb 1, 2021   ❤️ 1
    @orangeChu 可以考虑用 json 文件,修改数据后更新 json 文件,api 给前端传文件 key 。可以用 websocket 通知前端缓存文件。
    eason1874
        50
    eason1874  
       Feb 1, 2021   ❤️ 1
    才发现居然不是多机同步的,网络再快也有消耗啊,这么大的数据走实时网络,流量大点,内网都能给你堵了
    orangeChu
        51
    orangeChu  
    OP
       Feb 1, 2021
    @eason1874 哈哈哈,是的,现在高并发时,单机的整个系统就会缓慢。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   2530 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 84ms · UTC 12:08 · PVG 20:08 · LAX 05:08 · JFK 08:08
    ♥ Do have faith in what you're doing.