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

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

  •  
  •   orangeChu · 2021-01-28 23:05:56 +08:00 via iPhone · 4434 次点击
    这是一个创建于 1155 天前的主题,其中的信息可能已经有所发展或是发生改变。
    如果网站有大数据需要缓存(最大键值可能有 10M 左右,我觉得这么大的数据都缓存,太离谱了,但是实际又需要),有什么好的分布式缓存解决方案吗?
    尝试了一下 memcached,键值太大的时候,读写太慢了。没有自带的本地缓存快。
    小于 1m 的读写速度倒是跟本地缓存速度几乎一样。
    ps:c#开发
    第 1 条附言  ·  2021-01-30 11:35:22 +08:00
    我举个例子来说明我们现在的缓存使用情况。
    比如区域数据,先从数据库把所有的区域数据(大约 5W 条数据的 List 集合)都取出来,放在微软的 WebCache 里。
    然后用到省份的数据时,直接把区域集合拿出来,抽取父级为空的区域数据。
    选完省份后,根据省份,继续拿集合抽取父级为选取省份主键下的市级数据。
    以此类推。

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

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

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

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

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

    api 调用延迟高?

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

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

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

    那你生成一个 json 文件走 cdna 给前端自己解析不就好了
    boowx
        49
    boowx  
       2021-02-01 09:52:01 +08:00   ❤️ 1
    @orangeChu 可以考虑用 json 文件,修改数据后更新 json 文件,api 给前端传文件 key 。可以用 websocket 通知前端缓存文件。
    eason1874
        50
    eason1874  
       2021-02-01 10:36:18 +08:00   ❤️ 1
    才发现居然不是多机同步的,网络再快也有消耗啊,这么大的数据走实时网络,流量大点,内网都能给你堵了
    orangeChu
        51
    orangeChu  
    OP
       2021-02-01 13:45:31 +08:00
    @eason1874 哈哈哈,是的,现在高并发时,单机的整个系统就会缓慢。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2808 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 33ms · UTC 11:47 · PVG 19:47 · LAX 04:47 · JFK 07:47
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.