Redis是否持久保存数据?

时间:2014-08-15 14:31:07

标签: redis

我知道Redis提供来自内存的所有数据,但它在服务器重启时也会持续存在,这样当服务器重新启动时,它会从磁盘读取内存中的所有数据。或者它总是一个空白的商店,它只是在应用程序运行时没有持久性存储数据?

7 个答案:

答案 0 :(得分:46)

我建议您在http://redis.io/topics/persistence上阅读此内容。基本上,当您通过仅使用内存存储来提高性能时,您将失去保证的持久性。想象一下你插入内存但在它被持久化到磁盘失去电源之前的情况。将会有数据丢失。

Redis支持所谓的“快照”。这意味着它将在某些时间点(例如每整个小时)对内存中的内容进行完整的复制。当您在两个快照之间断电时,您将丢失从上次快照到崩溃之间的时间内的数据(不必是断电......)。与大多数NoSQL-DB一样,Redis交易数据安全性与性能。

大多数NoSQL数据库遵循多个节点之间的复制概念,以最大限度地降低此风险。 Redis被认为是更快速的缓存,而不是保证数据一致性的数据库。因此,它的用例通常与真实数据库的用例不同: 例如,您可以使用无与伦比的性能存储会话,性能计数器或其他任何内容,并且在发生崩溃时不会有真正的损失。但处理订单/购买历史等被视为传统数据库的工作。

答案 1 :(得分:20)

Redis服务器不时将其所有数据保存到HDD,从而提供一定程度的持久性。

它在以下某种情况下保存了数据:

但redis中的数据并不是持久的,因为:

  • redis进程崩溃意味着丢失自上次保存以来的所有更改
  • BGSAVE操作只能在有足够的可用RAM(额外RAM的数量等于redis DB的大小)时才能执行。

NB: BGSAVE RAM要求是一个真正的问题,因为redis会继续工作,直到没有更多的RAM运行,但它会更早地停止将数据保存到HDD(约占RAM的50%。

有关详细信息,请参阅Redis Persistence

答案 2 :(得分:7)

这是一个配置问题。您可以在Redis上没有,部分或完全持久保存数据。最佳决策将取决于项目的技术和业务需求。

根据Redis documentation about persistence,您可以设置实例,以便不时或在每个查询中将数据保存到磁盘中。他们提供了两种策略/方法AOF和RDB(阅读文档以了解当时的详细信息),您可以单独使用或一起使用。

如果你想要“像持久性一样的SQL”,他们会说:

  

一般的迹象是,如果您希望一定程度的数据安全性与PostgreSQL可以提供的数据相当,则应使用两种持久性方法。

答案 3 :(得分:4)

你可以选择没有持久性。更好的性能,但Redis关闭时所有数据都会丢失。

Redis有两种持久性机制:RDB和AOF.RDB使用调度程序全局快照,AOF将更新写入类似于MySql的仅限apappend的日志文件。

您可以使用其中一个或两者。当Redis重新启动时,它会通过读取RDB文件或AOF文件来构建数据。

答案 4 :(得分:1)

许多不了解情况和相对较新的用户认为 Redis 只是一种缓存,而不是可靠持久性的理想选择。 现实情况是,如今 DB、Cache(以及更多类型)之间的界限已经模糊。

<块引用>

这一切都是可配置的,作为用户/工程师,我们可以选择将其配置为缓存、数据库(甚至混合)。

每种选择都有好处和成本。这不是 Redis 的例外,但所有著名的分布式系统都提供了配置不同方面(持久性、可用性、一致性等)的选项。因此,如果您在默认模式下配置 Redis,希望它能神奇地为您提供高度可靠的持久性,那么这是团队/工程师的错(而不是 Redis 的错)。

我在我的博客 here 上更详细地讨论了这些方面。

此外,这是来自 Redis 本身的 link

答案 5 :(得分:0)

答案通常是,但是更完整的答案实际上取决于您要存储的数据类型。通常,更完整的简短答案是:

  • Redis并不是持久存储的最佳选择,因为它主要关注性能
  • Redis确实更适合可靠地存储/缓存 当前状态 数据,特别是通过为跨多个客户端使用的数据提供中央数据源来实现可伸缩性/服务器

话虽如此,默认情况下,Redis 以周期性间隔(显然是每1分钟一次,但仍未验证数据)保留数据快照下面的文章对此进行了介绍,这是一个很好的基本介绍):

http://qnimate.com/redis-permanent-storage/


TL; DR

来自official docs

  
      
  • RDB持久性 [默认] 以指定的时间间隔执行数据集的时间点快照。
  •   
  • AOF持久性 [需要显式配置] 记录服务器接收到的每个写入操作,这些操作将在服务器启动时再次播放,从而重建   原始数据集。
  •   
如果需要,必须对

Redis进行显式配置,以实现AOF持久性,这将导致性能下降和日志增长。对于有限数量的数据流的相对可靠的持久性可能就足够了。

答案 6 :(得分:0)

所有答案都在谈论redis持久化数据的可能性:https://redis.io/topics/persistence(每次写(更改)后使用AOF+)。

这是一个很好的入门链接,但显然没有向您展示全貌。


您真的可以/应该在 Redis 上保留不可恢复的数据/状态吗?

但是redis docs没有讲:

  1. 哪些 redis 提供程序支持此(AOF + 每次写入后)选项:
  • 几乎没有 - 云上的 redis 实验室不提供此选项。您可能需要购买内部部署版本的 redis-labs 来支持它。由于并非所有公司都愿意进行内部部署,因此他们会遇到问题。
  • 其他 Redis 提供程序根本没有指定是否支持此选项。 AWS 缓存、Aivan、...
  • AOF + 每次写入后 - 此选项很慢。您必须在生产硬件上自行测试,看看它是否符合您的要求。
  • Redis 企业提供了这个选项,从这个链接:https://redislabs.com/blog/your-cloud-cant-do-that-0-5m-ops-acid-1msec-latency/ 让我们看看一些基准:

AWS 上的 1x x1.16xlarge 实例 - 他们无法实现低于 2 毫秒的延迟:

<块引用>

从请求的第一个字节到达集群到“写”响应的第一个字节发送回客户端的时间测量延迟

他们在更好的硬盘 (Dell-EMC VMAX) 上进行了额外的基准测试,结果是 < 1 毫秒的操作延迟 (!!) 和从 70K ops/sec(写密集测试)到 660K ops/sec(读密集测试)。相当令人印象深刻!!!

enter image description here

但是它肯定需要(非常)熟练的 DevOps 来帮助您创建此基础架构并随着时间的推移对其进行维护。

  1. 有人可能(假的)争辩说,如果您有一个 redis 节点集群,那么现在您就拥有了完全的持久​​性。这是虚假声明:
  • 所有数据库(sql、non-sql、redis...)都存在相同的问题——例如,在 node1 上运行 set x 1,进行此(或任何)更改需要多长时间在所有其他节点中。所以额外的读取将收到相同的输出。嗯,这取决于很多因素和配置。
  • 在多个节点(任何数据库类型)中处理一个键的值不一致是一场噩梦。您可以从 Redis Author (antirez) 阅读更多相关信息:http://antirez.com/news/66。以下是在 redis 中存储状态的实际 ngihtmare 的简短示例(+ 解决方案 - WAIT 命令以了解其他 redis 节点收到了多少最新更改):
    def save_payment(payment_id)
        redis.rpush(payment_id,”in progress”) # Return false on exception
        if redis.wait(3,1000) >= 3 then
            redis.rpush(payment_id,”confirmed”) # Return false on exception
            if redis.wait(3,1000) >= 3 then
                return true
            else
                redis.rpush(payment_id,”cancelled”)
                return false
            end
        else
            return false
    end

上面的例子不够完整,并且有一个真正的问题是提前知道每个时刻实际上有多少(和活着的)节点。

其他数据库也会有同样的问题。也许他们有更好的 API,但问题仍然存在。

据我所知,很多应用程序甚至都没有意识到这个问题。

总而言之,选择更多的dbs节点不是一键配置。这涉及到很多。


要结束这项研究,要做什么取决于:

  1. 您的团队有多少开发人员(因此这项任务不会减慢您的速度)?
  2. 您有熟练的 DevOps 吗?
  3. 您团队中的分布式系统技能是什么?
  4. 花钱买硬件?
  5. 是时候投资解决方案了吗?
  6. 可能还有更多...