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

redis 本身有持久化,为什么还要写进 mysql 呢?

  •  
  •   chuanwu · 2015-09-10 09:34:10 +08:00 · 33146 次点击
    这是一个创建于 3344 天前的主题,其中的信息可能已经有所发展或是发生改变。

    redis 本身的持久化做得挺靠谱的,为什么还要多一个定时任务来写进 mysql?
    如果是因为防止恶意攻击被 flush 的话, mysql 也不大可能会幸免啊。

    62 条回复    2022-09-23 15:58:00 +08:00
    broadliyn
        1
    broadliyn  
       2015-09-10 09:36:26 +08:00
    思维固化吧。
    总提心吊胆的觉得 mysql 才是持久之道, redis 只能做 cache
    lovedboy
        2
    lovedboy  
       2015-09-10 09:39:02 +08:00
    可能为了以后清 cache 吧。
    snailsir
        3
    snailsir  
       2015-09-10 09:43:57 +08:00
    sefemp
        4
    sefemp  
       2015-09-10 09:47:02 +08:00
    感觉是不是为了某些特定的数据持久化?
    bigbook
        5
    bigbook  
       2015-09-10 09:53:03 +08:00
    当然也可以不写入,写入的好处肯定更多,有时候会有各种需求还是基于 mysql 更方便
    比如统计数据分析数据使用 mysql 更方便
    kslr
        6
    kslr  
       2015-09-10 09:55:59 +08:00
    思维固化+1 redis 的持久化还是很好用的。
    struCoder
        7
    struCoder  
       2015-09-10 09:57:49 +08:00
    我觉得不是思维固化。。也有一定的原因,毕竟新浪那些工程师也不是不知道这些。坐等大侠前来解答
    msxcms
        8
    msxcms  
       2015-09-10 09:58:35 +08:00
    数据安全不是有持久化就好的
    wy315700
        9
    wy315700  
       2015-09-10 10:03:52 +08:00
    MySQL 在崩溃处理,数据恢复方面比 redis 要好,
    Hakmor
        10
    Hakmor  
       2015-09-10 10:04:48 +08:00
    redis 作为数据库查询功能太弱了。
    sefemp
        11
    sefemp  
       2015-09-10 10:05:05 +08:00
    redis 可以针对某些特定的 key,或者 field 做持久化吗?
    adjusted
        12
    adjusted  
       2015-09-10 10:06:21 +08:00
    我觉得是完全可以只用 redis 的,可能还是因为熟悉 mysql 的人比较多吧
    looyao
        13
    looyao  
       2015-09-10 10:08:12 +08:00
    SQL 查询还是要强大很多吧,简单分析需求可能一个 SQL 就搞定了。还有一种就是如果数据量多了, Redis 会吃满内存,内存爆掉会有丢数据的风险,这时序列化到 MySQL 就是一种解决方案,将一些冷数据从 Redis 转移到 MySQL ,降低 Redis 内存使用。
    Redis 的确很强大,但是内存这块吃紧就不好玩了,国人 SSDB 在这块可能好些(题外话)。
    socrates
        14
    socrates  
       2015-09-10 10:10:47 +08:00
    定时任务写进 mysql 确实感觉很鸡肋啊,实时的异步写入觉得更有意义一些
    zeayes
        15
    zeayes  
       2015-09-10 10:12:30 +08:00
    最重要就是 mysql 是 SQL 数据库, redis 重启后数据加载会耗时
    shawngao
        16
    shawngao  
       2015-09-10 10:15:22 +08:00 via Android
    Redis 持久存储和内存占用是 1:1 的关系,体会下~
    nightspirit
        17
    nightspirit  
       2015-09-10 10:19:22 +08:00
    是一种冗余的安全机制么?
    songco
        18
    songco  
       2015-09-10 10:33:39 +08:00
    还是要看具体的应用. 比如有人需要 redis 高速处理请求, 然后 sync 到 mysql 做一些 sql 查询.
    Redis 的持久化有 rdb 和 append only file
    RDB 定时(一般比较长..)刷到磁盘, 丢数据的风险比较大. 当然有些应用是可以忍受这种级别的丢数据的. RDB 加载很快.
    Append only file 貌似每秒 fsync 一次, 没看过具体的代码, 不知道开启了对请求处理速度有没有影响. 这个也会丢数据, recover 速度比较慢. 不过大部分情况下开启 aof 就够用了. 除非有 sql 查询的需求.

    以前我设计开发过一个 key-value DB, 丢数据 /性能权衡的问题非常麻烦...

    上面的都是根据比较老的版本的, 新版本可能有更多的功能.
    wingoo
        19
    wingoo  
       2015-09-10 10:37:51 +08:00
    kv 的数据可能和你的数据结构不相关
    比如你计数, 在 redis 中就是一个 key 不停的累加
    但在表里的一行数据, 这个计数就有了其他的属性
    当你想做这个属性的统计时, mysql 比 kv 的要方便和直观的多了
    wingoo
        20
    wingoo  
       2015-09-10 10:40:27 +08:00
    我们曾经做过一个项目, 广告数据
    开始的版本全部存储在 memcached 里面, 当你想查些问题时, 非常烦, 你要一个一个的拼 key 去检查
    后期的版本改成 log 文件, 结构化存储, 然后解析入库
    好处是非常直观, 找什么数据, cat grep 一下就可以
    caoyue
        21
    caoyue  
       2015-09-10 10:41:54 +08:00
    有些数据还是结构化的比较容易使用吧
    stackpop
        22
    stackpop  
       2015-09-10 10:46:57 +08:00
    没有人提到事务么?
    lavadore
        23
    lavadore  
       2015-09-10 10:52:18 +08:00
    请科普关系型数据库
    neoblackcap
        24
    neoblackcap  
       2015-09-10 10:53:59 +08:00
    @stackpop 事务+1,明明很多人的主程序就是从 MySQL 读数据的,写进去不是很正常么?

    若是把 redis 作为唯一的持久化机制,当然可以不写 MySQL ,只不过你的程序需要另外实现事务而已。这没什么。然而当加上事务以及开启持久化特性之后,这样一个写的过程我觉得可能还不如直接写 MySQL 来得快
    zonghua
        25
    zonghua  
       2015-09-10 11:12:27 +08:00 via iPhone
    比如博客网站侧边栏的标签,归档和相关的内容是在缓存里面的吧,不可能是都查询一次。
    line
        26
    line  
       2015-09-10 11:27:32 +08:00
    sql 查询,很方便
    snailsir
        27
    snailsir  
       2015-09-10 11:27:38 +08:00
    @socrates “实时的异步写入” 要怎么做呢?求教
    jsjscool
        28
    jsjscool  
       2015-09-10 11:30:25 +08:00
    用 MySQL 落地主要是为了自己后期轻松点。经常有如下场景:
    1.同步数据。千万级别的历史数据用 MySQL 直接导出 SQL 给需求方就行了。 Redis 总会麻烦一些。
    2.数据分析师经常找你要数据,而且大多数分析软件不支持 Redis ,这个时候你怎么弄?

    所以用 MySQL 落地对自己和公司都是有大大的好处。
    linescape
        29
    linescape  
       2015-09-10 11:33:00 +08:00
    这是一道很好的面试题
    wy315700
        30
    wy315700  
       2015-09-10 11:33:55 +08:00
    @snailsir 修改 redis 源码,,以前听说个大牛,一天就搞定了
    snailsir
        31
    snailsir  
       2015-09-10 11:41:04 +08:00
    @wy315700 这么牛逼,求学习
    shoaly
        32
    shoaly  
       2015-09-10 12:01:37 +08:00
    我觉得 是因为 sql 的方式可以很好的把 项目分表, 去分开, redis 这种给人解决先天性就是 kv 模式 很难去解剖复杂的数据结构
    tesion99
        33
    tesion99  
       2015-09-10 12:06:14 +08:00
    redis 的数据存于内存中,如果突然断电的话,服务器 redis 中的内存数据就丢失了,写进 mysql 有确保数据不丢失的安全考虑吧
    chuanwu
        34
    chuanwu  
    OP
       2015-09-10 12:14:47 +08:00
    统一回复一下吧:
    1. 有朋友提到说 Redis 会吃满内存,从而爆掉。
    但一般来说 redis 的使用场景(仅从我的角度来看),是在可能需要频繁读写数据,但该数据又并不太重要或者可能只是用一次时,比如点赞,短信验证等,该类数据的话,如前者,存到 mysql 也并不能减少内存压力啊,短信验证的话,用 redis ,设置 expire ,比 mysql 要更好啊,也不会累积太多数据。
    2. 实时异步存储

    在实际使用时,还是需要从 redis 里面来获取最新数据啊。

    3. redis 重启后数据加载耗时
    我在实际使用中, mysql 持久只是担心服务器挂掉从而丢失数据,但这类情况特别少见。这边请有经验的前辈分享一下。什么样的数量级会导致 redis 加载过慢? 而且 redis 重启,肯定还是需要从 mysql 再把数据搞回来,这样的话,速度会比 redis 自身的要快很多吗?

    wingoo 提到的,也是我现在遇到的问题,每一次要用到某个数据时,比较麻烦,需要去拼 key 。
    但不现拼现 get 的话,数据不一定是最新的啊。
    neoblackcap 提到的问题,如果是这种情况的话,完全可以在使用到该数据时,来实时存储啊,否则数据可能不准确。
    个人愚见。
    msg7086
        35
    msg7086  
       2015-09-10 12:24:58 +08:00   ❤️ 10
    随便说几点。

    1. 权限控制
    MySQL 有权限控制,用户可以精确到每个 IP 的每个账户,目标可以精确到每个表的每个操作。
    Redis 则是天生设计成完全开放权限,包括完全删除数据库的操作,任何人都可以执行。要么就只能把指令重命名成空的,完全禁止任何人执行。

    2. 数据完整
    MySQL 的数据库保存在磁盘中,万一崩溃断电,也有数据库日志可以用以完成数据库事务。
    MySQL 支持主从备份,所有的写入操作都可以实时发送到异地,哪怕突然机房被核弹轰炸,也不会丢失数据(可能除了最后几条语句)。
    Redis 的崩溃……嗯小心数据全丢。
    Redis 的 Replication 备份……嗯小心数据全丢。

    3. 负载均衡
    MySQL 可以单主多从,也可以胆子够大在内网做双主,也可以用 innodb 配合 galera 做集群,每台机器都有一个独立的拷贝,因此服务器之间只要传输写指令即可。
    Redis 可以单主多从(然而小心数据全丢),但是不能做多主互联。最多最多只能做 sharding ,也就是每台机器只保存一部分数据,读写一律被分散到其他机器上。直接后果就是内网流量大增。

    4. 数据隔离
    MySQL 里我可以选择删掉某个应用的所有数据而保留另一个应用的所有数据。
    Redis 里要么依赖 11 个 DB 的选择,要么依赖命名空间。

    5. 性价比
    MySQL 是内存+硬盘,上个 SSD 配合 Query Cache 那速度已经是很快了。
    Redis 是纯内存。乖乖掏钱加内存换至强啦。而且你还是得配备高性能磁盘,因为定时刷到磁盘和开机加载数据的操作还是要磁盘性能的。
    vikeria
        36
    vikeria  
       2015-09-10 12:30:47 +08:00 via Android
    感觉好像前段时间看过这个帖子
    tigerz
        37
    tigerz  
       2015-09-10 12:36:54 +08:00
    可能的问题:
    1. redis 的持久化是异步的,出现异常丢数据的概率很高。
    2. mysql 可以做复杂的查询。
    hippoboy
        38
    hippoboy  
       2015-09-10 12:43:06 +08:00
    @chuanwu 能否说说如何实现?特别是这个定时任务写到 mysql 如何实现?搜索关键词也行....第一次接触 redis 搞的无头绪啊,orz
    22too
        39
    22too  
       2015-09-10 12:48:40 +08:00
    我是做统计的,公司各种统计任务

    1. 改写之前的 sql 统计习惯?

    不可能的,这个太难了,再说,好不容易学了一些一个 sql 就能解决的统计问题,现在你告诉我,让我全部使用 redis 的规则来写,然后数据处理全部使用编程语言进行

    2. 我的思维是固化的

    我只知道我统计出来的数据很重要或者不重要,重要的数据为何我要冒险使用可能会有问题,或者自己不熟的操作方式去做,不重要的数据,我为何要写个程序去做?而不是仅仅写一个条嵌套 sql 。

    3. 需求不同

    开发这样想是对的,但是其他的人可能会面临新的压力,新的技术挑战,所以需求定位是最终的出发点,除非哪天 redis 的统计也能做的很溜

    个人意见
    xmbaozi
        40
    xmbaozi  
       2015-09-10 12:49:23 +08:00 via Android
    1.持久化不是实时的
    2.只能用键查询
    fxxkgw
        41
    fxxkgw  
       2015-09-10 13:12:19 +08:00
    1 ,突然掉电
    2 ,内存出问题
    hooopo
        42
    hooopo  
       2015-09-10 13:32:11 +08:00
    MySQL 不只是存储啊,还有 SQL 这样的查询接口...
    zhujin
        43
    zhujin  
       2015-09-10 13:41:58 +08:00
    为什么没人提 Redis 的时效时间呢....
    ablegao
        44
    ablegao  
       2015-09-10 14:05:34 +08:00
    我阐述一下我的观点,


    1.我记得是先有得 memcache , 后推出的 redis , 增加了数据运算功能, hash 和队列等,当时都不支持固化,起点都是提高访问速度,减少数据压力, redis 分析市场需求,尝试推出的本地固化功能,可实际应用中是这样的, 数据会分为热数据和冷数据,或者称为活跃数据和非活跃数据,全都在 redis ,显然长期下来并不合理, redis 的 RDB 快照和 AOF 纪录都会有一定的硬盘负担。关系数据库又是必不可少的,项目中多少都会用, 既然少不了, 索性不如更多的利用起来, redis 可以是一个小硬盘,多内存的专属服务器集群, 专心做缓存。 mysql 专心做存储。(补充, redis 在热数据冷数据的区分上,是支持的,可以将冷数据固化起来,有需要时提取出来, 但作为 key 的值,会一直在内存中。)

    2. 没有可靠的先例或者有谁把 redis 本身的固化机制用的很好又不出问题。那在这个前提下, redis 本身在内存崩溃和重启数据恢复复杂且不确定是否数据完整的情况下,过渡依赖 redis 自身固化机制, 是在给上线的项目找麻烦。所以,同上观点, 把数据转储到一个关系数据反而更容易一些。

    其实这些都是需求催生的, 所以有了很多类似于 leveldb 这种纯硬盘的 kv 数据库。 redis 的起点是 cache 。
    Bluecoda
        45
    Bluecoda  
       2015-09-10 14:43:29 +08:00   ❤️ 2
    redis 相比 mysql 有几个缺点:
    1 ,内存占用巨大
    2 ,持久化并不一定是实时的,此时掉电或者其他故障可能会有大量的数据丢失

    存 mysql 有几个好处:
    1 ,内存占用相比 redis 小很多
    2 , mysql 除了存储,还有 sql 这个强大的东西

    结论,楼上说什么思维固化,不是这么一回事,我们用东西,要看清楚每一种工具的适用场景,而不是一味的相信新技术就必然好于旧的技术。而是要,遇到什么问题,就用什么工具。说思维固化的那些人,其实他们的思维才真正的固化,做不到灵活的使用手上的工具。
    jiangyz
        46
    jiangyz  
       2015-09-10 16:08:14 +08:00
    @msxcms +1
    yanze0613
        47
    yanze0613  
       2015-09-10 17:44:02 +08:00
    主要还是方便支持后期的数据整理工作吧,然后相对来说,大家还是更熟悉 sql
    xgdyhaiyang
        48
    xgdyhaiyang  
       2015-09-10 18:31:03 +08:00
    redis 不支持事务,查询不方便
    wangchen
        49
    wangchen  
       2015-09-10 18:58:54 +08:00
    * mysql flush 数据到磁盘也是“异步”的,也会有丢失数据的可能。

    原因:

    首先,数据总有“冷”、“热”之分,前者放在 redis 里显然浪费资源。

    其次,性能、成本,最终是一个权衡的问题。举例,有 model ( name, last_updated_at ),需求是通过 name 获取 last_updated_at 。看来放 reds 里面又快又美,但当数据到一定量级时,比如 1 亿、 10 亿条, reds 方案的成本会相当高,而 mysql 方案牺牲一点点性能,可以节省大量成本。
    nandaye
        50
    nandaye  
       2015-09-10 19:03:23 +08:00 via Android
    技术还是基于业务的 使用新技术风险比较大 安全稳定才是王道 为了安全稳定花的金钱和时间都是值得的 数据出现一次问题那后果就很大了 我们公司因为北京某银行出现一次故障推荐所有入职员工不要办理这个银行的公积金联名卡
    hellokittyer
        51
    hellokittyer  
       2015-09-10 19:22:03 +08:00 via Android
    为什么不吃玉米替代主食米饭呢?
    redis 能事务么
    RemRain
        52
    RemRain  
       2015-09-10 20:53:52 +08:00
    不错的面试题啊~
    1. 场景不一样, redis 的持久化是附加功能, mysql 的持久化是核心功能
    2. redis 的 flushdb 、 flushall 太犀利了,用 redis 来持久化数据总感觉不靠谱
    3. 持久化机制不一样,举个例子来说,当数据量达到 10G 的时候,你改了几条数据, mysql 只增量地持久化这几条数据;而 redis 只知道自己该持久化了,然后把 10G 数据完整地从内存 dump 到磁盘,是不是很过瘾
    GitFree
        53
    GitFree  
       2015-09-10 21:38:50 +08:00
    只用 redis 废弃 mysql ,使用的时候确实很爽,突然有需求做个统计或者架构改变做数据迁移就闷逼了
    binux
        54
    binux  
       2015-09-10 21:45:16 +08:00
    3 年前的感想: redis 的持久化,特别是 AOF 一点也不靠谱,对性能影响太大, 开过之后再也不想开了. RDB 会丢数据.
    rrfeng
        55
    rrfeng  
       2015-09-10 22:02:30 +08:00
    redis 的持久化并不靠谱。当然是相对于各种 DB 来说。而且无论是 RDB 还是 AOF 对性能影响都不小,缓存就做好缓存的事情吧。
    socrates
        56
    socrates  
       2015-09-11 18:24:25 +08:00
    @snailsir 用个异步队列就 OK 了
    chuanwu
        57
    chuanwu  
    OP
       2015-09-12 11:43:44 +08:00
    @binux 能具体说说当时的场景吗?

    @hippoboy 用 cron 事件,通过时间,或者根据新增数据的数量。
    konakona
        58
    konakona  
       2016-04-24 13:38:46 +08:00
    写入 MYSQL 可以进行一些查询和管理界面咯。
    XDMonkey
        59
    XDMonkey  
       2017-04-18 14:31:43 +08:00
    @stackpop 事务+1
    binaryify
        60
    binaryify  
       2019-06-26 18:57:21 +08:00
    redis 的存储是为了恢复状态,尽可能保留数据,正经数据肯定得存到正常数据库的
    wudanyang
        61
    wudanyang  
       2019-07-08 16:00:10 +08:00
    @msg7086 即使是 redis 崩溃了,也不至于数据全丢吧?
    kaojistream
        62
    kaojistream  
       2022-09-23 15:58:00 +08:00
    @nandaye 用 redis 肯定是不重要的数据
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3193 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 52ms · UTC 12:39 · PVG 20:39 · LAX 04:39 · JFK 07:39
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.