V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
nnegier
V2EX  ›  程序员

我想询问 Redis 的刚需在哪里呢?

  •  2
     
  •   nnegier · 2023-05-09 04:10:48 +08:00 · 6857 次点击
    这是一个创建于 598 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我对 Redis 的看法,它是一个运行在内存中的数据结构数据库服务器,也因此我不知道在什么时候应该用 Redis ,因为既然是数据结构既然是内存,我完全可以自己写一个数据结构如 HashMap 存在自己的进程内部,而我也是这样干的。

    也有人拿它来做磁盘关系型数据库的缓存,但我个人也想过,不过我用了 MyBatis 来做 MySQL 的访问中间层,二级缓存 MyBatis 本身也能做,配置上加个 cache 就好了,甚至还可以自定义缓存实现。

    所以,我比较想知道这个知名工具 Redis 解决的核心痛点是什么?

    yuelang85
        1
    yuelang85  
       2023-05-09 04:36:18 +08:00
    你可以自己写一个内存数据库,事实上各种语言也都有这样的工具。可是有两个问题:

    1 ,功能,速度,是否能达到你的需求,如果要达到,需要多少工作量?

    2 ,单进程应用还好,多个进程需要共享数据怎么办?
    TuringHero
        2
    TuringHero  
       2023-05-09 04:44:14 +08:00 via iPhone   ❤️ 6
    你也可以看作多节点下的共享内存方案。而且还实现了像集群、持久化、消息队列、地理搜索、Lua 等一些功能,缓存单独部署可靠性也高一些。项目想不到哪里有用的话就不要用,本地缓存可以实现的话就没必要增加复杂度引入 Redis
    Jhon11
        3
    Jhon11  
       2023-05-09 07:11:28 +08:00
    作用类似数据库,本地内存替代不了的
    tulongtou
        4
    tulongtou  
       2023-05-09 07:14:01 +08:00
    1. redis 开始流行的时候,PHP 还大行其道,而 php 是单进程模式,没有办法自己写内存缓存。
    2. 大型缓存服务可能不止在一台机器上,假设有 10 台机器用作缓存,直接用 redis 会比自己开发节省时间的。
    Akitora
        5
    Akitora  
       2023-05-09 07:54:37 +08:00 via Android
    分布式锁
    crysislinux
        6
    crysislinux  
       2023-05-09 08:05:09 +08:00 via Android
    单进程当然可以进程缓存了。但是多进程甚至多机器进程缓存就会有不一致的问题了。另外单独的缓存服务器可以加大内存,但是你给每个应用服务器搞很大的缓存就比较浪费了。
    Yeen
        7
    Yeen  
       2023-05-09 08:10:47 +08:00
    那么楼主 memcache 可以了解一下,
    这些技术无非就是数据库上层做更特殊需求用的(性能、非持久化 /半持久化等等),而且也不止 redis 一种技术,轮子太多了
    hhjswf
        8
    hhjswf  
       2023-05-09 08:12:03 +08:00 via Android
    啊这,如果你一个应用有两个实例呢,你能保证这两个实例各自内存数据一致性吗
    chaleaochexist
        9
    chaleaochexist  
       2023-05-09 08:13:27 +08:00
    单体应用问题不大.
    考虑分布式场景.
    clusterRedis 是一方面
    还有分布式应用依赖 redis 场景.
    darkengine
        10
    darkengine  
       2023-05-09 08:23:57 +08:00
    除了楼上说的多进程共享数据问题。如果你用 HashMap 解决缓存问题,每次重启进程都所有“缓存”都会丢失。
    matrix1010
        11
    matrix1010  
       2023-05-09 08:41:35 +08:00   ❤️ 1
    Redis 没有刚需,但这类远程缓存服务有一个刚需场景是 serverless. 其实 Redis 作为纯缓存相比 memcache/keydb/dragonflydb 这些支持多线程的没有优势,Redis 流行是因为数据结构 /功能多。Redis 自己也认识到纯缓存性能问题所以加了 Client-side caching 的功能,但 Client-side caching 是 Redis server 辅助 client ,需要 client 自己实现内存缓存,所以现在用的还不多
    xiaowowo
        12
    xiaowowo  
       2023-05-09 08:45:48 +08:00
    1.支持多种数据结构和数据查询方式
    2.多进程多实例共享同步
    3.业务和缓存隔离,更新业务不会导致缓存丢失
    4.支持持久化
    5.很多语言无法实现内存缓存或实现性能不佳
    6.支持横向扩容,支持分布式
    Maboroshii
        13
    Maboroshii  
       2023-05-09 08:48:19 +08:00 via Android
    稳定性。 没那么容易挂
    fox0001
        14
    fox0001  
       2023-05-09 08:54:28 +08:00 via Android
    楼上都讲清楚了。我觉得是:高性能、数据共享、集群
    lower
        15
    lower  
       2023-05-09 08:58:40 +08:00
    这类缓存工具核心肯定是给数据库“减负”……
    具体到各种缓存工具的使用,肯定要看实际场景啊,比如虽然我是单体应用,但是只要把会话信息存 redis 里,单体应用就是无状态啦,可以很方便部署多个实例
    性能的话,走网络的 redis 肯定不如进程内缓存

    我甚至觉得 redis 可以作为好多种工具的底层 kv 存储,提供一套统一的插件开发接口,上层开发各种各样工具,除了它已经搞的分布式锁、发布订阅;还可以把服务注册、配置管理、分布式事务之类这种功能全在它上面开发插件实现,搞一个真正的大一统超级缝合怪😂
    wanguorui123
        16
    wanguorui123  
       2023-05-09 09:00:52 +08:00
    分布式下作为共享内存用
    dayeye2006199
        17
    dayeye2006199  
       2023-05-09 09:06:47 +08:00 via Android
    缓存很多时候都不是必须的
    mineralsalt
        18
    mineralsalt  
       2023-05-09 09:13:49 +08:00
    单实例软件确实没必要用, 你以后用到分布式部署就知道了
    dif
        19
    dif  
       2023-05-09 09:17:25 +08:00   ❤️ 1
    第一、免费。
    第二、好用,能适用与绝大部分场景,因为用的公司多也比较成熟,很难遇到 bug 。
    第三、专业的事情由专业的团队去做。我只需要调用 api 就行。节约成本
    第四、可以找借口优化拿钱,其实很多项目做 1-2 期基本上就很难迭代下去了,然后就会进入维护期,维护期很难有成果,那么就可以把一个接口从 5 秒逐渐优化到 100ms (中间会经历 sleep(300),sleep(200),sleep(60)。。。。 上 redis )。搞完了还能写一篇公众号《通过这个小技巧,我把接口的响应时间降低了 3000 倍》,double win -> win win
    raysonlu
        20
    raysonlu  
       2023-05-09 09:24:56 +08:00
    有生之年我会不会见到类似《我想询问 Mysql 的刚需在哪里呢?》的帖子?
    wxw752
        21
    wxw752  
       2023-05-09 09:26:56 +08:00   ❤️ 1
    你能问出这样的问题,那么说明你接触到的项目小了
    chunworkhard
        22
    chunworkhard  
       2023-05-09 09:28:42 +08:00
    学习一下
    c3de3f21
        23
    c3de3f21  
       2023-05-09 09:31:08 +08:00
    - 无状态服务好像没法儿用 session?
    - 大概会出现 cookie 里的 sessionID 拿到后台找不到 session 的情况?
    - 那我们用 sessionID 做 Key ,值做 value 是不是就能解决一部分问题?
    当然我接触的项目有些小,不足以体现 redis 的优势。。。
    RedisMasterNode
        24
    RedisMasterNode  
       2023-05-09 09:40:34 +08:00
    https://github.com/alibaba/canal
    canal v1.1.5 版本的管理后台组件就是直接使用内存来缓存登录后的 session 的,猜猜会有什么问题?

    对,当部署了多台机器(容器)的时候管理后台登录之后就无法访问了,提示重新登录
    yalin
        25
    yalin  
       2023-05-09 09:41:46 +08:00
    集中会话管理
    brader
        26
    brader  
       2023-05-09 09:46:14 +08:00
    为了自己无需重复造轮子,难道我今天需要 k-v 结构数据,我自己可以简单撸一个增删改查,然后明天需要列表,我又自己撸一个增删改查?后天呢?这不管是对于使用的自己,还是接手的同事,带来多少麻烦?
    brader
        27
    brader  
       2023-05-09 09:48:45 +08:00
    而且你只简单的想到了单应用的使用,如果多应用或者多项目之间合作交互呢?比如你前台有个 redis-key ,有时候需要在管理后台对它提前生成、刷新、删除,你自己写的 HashMap 的话,你另一个后台项目怎么操作它?难道你闲的自己再开个端口服务来操作它?
    gbw1992
        28
    gbw1992  
       2023-05-09 09:49:26 +08:00
    如果是单例应用,那的确是。能使用 redis 的场景,几乎都能编码实现。
    业务平台时间长了都会分开
    大部分公司控制不住项目代码腐烂进度,时间长了就分开了
    缓存共享只是基础用法,还有分布式事件订阅推送等
    自己写?当然可以。最后谁写的谁维护就行了。
    你也不想被领导知道,你写的状态维护模块崩了的事情吧😏
    plutome
        29
    plutome  
       2023-05-09 09:50:10 +08:00
    举一个例子:
    每天有一亿条流水,里面会有重复,需要根据 id 去重后入库。

    a )每次入库之前查询数据库,判断记录是否存在?
    b )维护一个 map 在内存里面,判断 key 是否存在?
    c) 其他方案,redis 等...


    可以简单思考一下这个场景的代码怎么设计。
    Imindzzz
        30
    Imindzzz  
       2023-05-09 09:52:00 +08:00 via Android
    先 hash map 也行,当你需要缓存的数据多了,你会想着封装一套操作 api(自动过期,批量过期等)。
    然后就会想着怎么重启服务不丢失,多机器共享等问题,就可以用 redis 了,
    whh945atsyzx
        31
    whh945atsyzx  
       2023-05-09 09:54:01 +08:00
    单体应用可以 hashmap ,分布式呢?你可以说你专门开一个服务来做缓存,恭喜你,这就是 redis
    Imindzzz
        32
    Imindzzz  
       2023-05-09 09:54:44 +08:00 via Android
    为什么都是项目开始就直接引入 redis ?因为引入成本非常低
    as5739
        33
    as5739  
       2023-05-09 10:13:33 +08:00
    因为写内存里 重启会丢,而 redis 作为中间件一般不重启,而且也有持久化机制
    ShuWei
        34
    ShuWei  
       2023-05-09 10:14:45 +08:00
    我个人理解,有几个比较明显的理由
    1 、性能,尤其是数据量较大时
    2 、跨应用共享
    3 、部分依赖数据可靠性的场景
    4 、部分编程语言,比如 php

    如果是单体部署的应用,大部份时候可能对 redis 的依赖确实不强
    jaylee4869
        35
    jaylee4869  
       2023-05-09 10:28:54 +08:00
    尽可能保障服务无状态能让服务本身可以大胆地水平扩缩容。
    cohen121
        36
    cohen121  
       2023-05-09 10:56:03 +08:00
    分布式场景。还有你有没有考虑过用 hashmap 存在进程内存,如何在扩容时(多进程 /多机器)同步状态。
    zzzmh
        37
    zzzmh  
       2023-05-09 11:00:59 +08:00
    java 发现爬虫 ip 存 redis ,下次请求 lua+nginx 直接从最前端拦截,以此类推
    另外我个人感觉是相比 java 用 redis 效率更高更省内存
    bugmakerxs
        38
    bugmakerxs  
       2023-05-09 11:08:21 +08:00
    多实例数据共享
    cyningxu
        39
    cyningxu  
       2023-05-09 11:30:22 +08:00   ❤️ 1
    所以楼主一直开发的都是单机单实例?
    liuxu
        40
    liuxu  
       2023-05-09 11:36:33 +08:00
    1. 多进程模型语言
    2. 需要超过应用生命周期的缓存
    qsnow6
        41
    qsnow6  
       2023-05-09 11:36:58 +08:00
    @raysonlu #20 还真有,能 sqlite 为什么要用 MYSQL😋
    hankai17
        42
    hankai17  
       2023-05-09 11:44:10 +08:00
    集群 就这一条
    quicksand
        43
    quicksand  
       2023-05-09 11:46:12 +08:00
    @darkengine #10 确实, 我以前也想过自己基于内存写一个能持久化数据的 HashMap 来代替, 后来发现其实实现起来是有些麻烦的, 要考虑的东西很多, 还不如直接用 redis
    dqzcwxb
        44
    dqzcwxb  
       2023-05-09 11:52:48 +08:00
    其他的上面都说了,我说一个没人说的:保证原子性
    seth19960929
        45
    seth19960929  
       2023-05-09 12:08:35 +08:00
    Redis 主要两个作用:
    缓存:
    这个你可以用文件实现, 单机器用 map 比 Reids 性能好多,
    如果部署一百台机器的话, 比如你缓存有 100M, 那 map 就是 100M*100, redis 只用 100M

    分布式锁, session 这些, 队列其他功能:
    这个 map 实现不了
    coyoteer
        46
    coyoteer  
       2023-05-09 15:03:10 +08:00   ❤️ 2
    redis!=缓存。redis 跟 mysql 一样都是数据库,只是一个是非关系型的、一个是关系型的,一个存储在内存中使用磁盘进行备份,一个存储在磁盘中使用内存进行缓存。。。
    sunmlight
        47
    sunmlight  
       2023-05-09 15:04:45 +08:00
    路走窄了
    daiv
        48
    daiv  
       2023-05-09 15:10:29 +08:00
    我现在用 Golang, 由于是单机服务运行, 所以直接用 Map 放到内存中去, 每次重启 数据库 > 内存 , 目前使用还好, 速度也比 Redis 快很多
    yule111222
        49
    yule111222  
       2023-05-09 15:12:04 +08:00
    分布式缓存呀
    unco020511
        50
    unco020511  
       2023-05-09 15:22:43 +08:00
    多节点
    lshero
        51
    lshero  
       2023-05-09 15:33:41 +08:00
    多机器共享缓存
    懒得装消息队列临时充当一下消息队列
    协议简单,异构的系统之间好集成不同语言都有客户端。我之前工作过的一个公司用 Redis 协议作为 RPC 的通讯协议开发了一套服务治理系统。
    di94sh
        52
    di94sh  
       2023-05-09 18:25:54 +08:00
    就一个,你用 HashMap 怎么解决多台机器数据同步问题。a 机器更新了,b 机器还用旧的?
    pkoukk
        53
    pkoukk  
       2023-05-09 18:33:17 +08:00
    就一条,多机器共享内存
    没错,你可以说干嘛非要共享内存,写数据库又稳又方便
    数据库顶不住可以加配置嘛,搞物理机 mysql ,36C500G 内存的 mysql 强行顶
    daimubai
        54
    daimubai  
       2023-05-09 18:34:50 +08:00
    分布式
    Lucups
        55
    Lucups  
       2023-05-09 19:03:04 +08:00
    Redis 的功能远大于 “一个数据结构如 HashMap 存在自己的进程内部”。

    理论上自己实现一个类似 Redis 功能的工具并不难,但是稳定、性能等无法与 Redis 匹敌,更不要说 Redis 还有丰富的生态与社区支持了。

    PS: Redis 的通信协议 RESP 设计的也非常优秀。
    janus77
        56
    janus77  
       2023-05-09 19:24:43 +08:00
    当他从一个单纯的缓存( hashmap )进化成数据库以后,他的功能就复杂多了,随便举例:
    多进程,多节点、集群、分布式,吞吐量、性能,同步、数据恢复……
    roundgis
        57
    roundgis  
       2023-05-09 22:54:20 +08:00 via Android
    redis 什麼都能做

    消息隊列 cache ipc

    性能也還過得去 接入也容易

    真的成為瓶頸 換掉也不麻煩

    對大多數的系統而言根本就沒機會換掉它
    zhaogaz
        58
    zhaogaz  
       2023-05-09 23:23:33 +08:00
    现有的问题解决不了,引入 redis 解决了,这就算痛点吧。可以以这个角度分析
    Al0rid4l
        59
    Al0rid4l  
       2023-05-10 01:56:58 +08:00
    你也说了单进程直接存进程内存, 其实论性能这毫无疑问比 Redis 更好

    但假如你要多线程 /多进程, 你自己实现共享内存, 管理并发安全.

    假如你还要支持各种缓存策略, 又要自己实现

    假如你继续支持分布式和更多需求...

    当你都实现了, 恭喜你, 做了个 low 配 Redis.
    eDeeraiD0thei6Oh
        60
    eDeeraiD0thei6Oh  
       2023-05-10 02:25:16 +08:00
    分布式啊。说明你的服务都是单机运行??? 量级太小了吧??
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   946 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 20:05 · PVG 04:05 · LAX 12:05 · JFK 15:05
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.