Redis持久化数据吗?

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

150304 次浏览

我建议你在http://redis.io/topics/persistence上读到这个。当您仅使用内存存储来提高性能时,基本上就失去了保证的持久性。想象一下这样一个场景:插入到内存中,但是在它被持久化到磁盘之前失去了电源。会有数据丢失。

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

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

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

在以下情况下保存数据:

  • 时不时地自动
  • 当你手动调用BGSAVE命令
  • 当redis关闭时

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

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

注意: BGSAVE RAM需求是一个真正的问题,因为redis继续工作,直到没有更多的RAM运行,但它更早地停止将数据保存到HDD(大约在10分钟左右)。50%的RAM)。

更多信息见复述,持久性

你可以选择完全不坚持。更好的性能,但所有的数据丢失时,Redis关闭。

Redis有两种持久机制:RDB和AOF。RDB使用调度程序全局快照,AOF将更新写入与MySql类似的只能追加的日志文件。

你可以用其中一个,也可以两个都用。当Redis重新启动时,它通过读取RDB文件或AOF文件来构造数据。

最好的决策将由项目的技术和业务需求驱动。

根据关于持久性的Redis文档,你可以设置你的实例,以每次查询或每次查询时将数据保存到磁盘。它们提供了两种策略/方法AOF和RDB(请阅读文档查看详细信息),您可以单独使用它们,也可以同时使用它们。

如果你想要一个“类似SQL的持久性”,他们说:

一般的提示是,如果你想要达到与PostgreSQL提供的数据安全程度相当的数据安全性,你应该同时使用这两种持久性方法。

答案通常是是的,然而更完整的答案实际上取决于你试图存储什么类型的数据。一般来说,更完整的简短回答是:

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

话虽如此,默认情况下,Redis 以周期性的间隔持久化数据快照(显然这是每1分钟,但我还没有验证这一点-这是由下面的文章描述的,这是一个很好的基本介绍):

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


博士TL;

官方文档:

  • RDB持久性 (默认)以指定的间隔执行数据集的时间点快照。
  • AOF持久性 [需要显式配置]记录服务器接收到的每个写操作,该操作将在服务器启动时再次播放,重新构造 李原始数据集。< / >

如果需要,Redis必须为显式配置以实现AOF持久性,这将导致性能损失以及不断增长的日志。对于有限数量的数据流的相对可靠的持久性来说,它可能足够了。

许多消息不灵通和相对较新的用户认为Redis只是缓存,而不是可靠的持久性的理想选择。 现实是DB, Cache(以及更多类型)之间的界限现在是模糊的

它都是可配置的,作为用户/工程师,我们可以选择将其配置为缓存,DB(甚至是混合)。

每个选择都有收益和成本。Redis也不例外,所有知名的分布式系统都提供了配置不同方面的选项(持久性、可用性、一致性等)。所以,如果你在默认模式下配置Redis,希望它能神奇地给你高可靠的持久性,那么这是团队/工程师的错误(而不是Redis的错误)。

我已经在我的博客在这里中更详细地讨论了这些方面。

另外,这里是Redis本身的链接

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

这是一个很好的开始链接,但它没有向您展示全貌。


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

Redis文档没有谈到:

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

AWS上的1x x1.16xlarge实例-它们不能实现低于2ms的延迟:

从请求的第一个字节到达集群到'写'响应的第一个字节被发送回客户端,延迟是在哪里测量的

他们在一个更好的硬盘(Dell-EMC VMAX)上进行了额外的标配,这导致<1毫秒的操作延迟(!!),从70K ops/秒(写密集测试)到660K ops/秒(读密集测试)。漂亮impresive ! !

enter image description here

< >强但是< / >强它需要一个(非常)熟练的devops来帮助你创建这个基础设施,并随着时间的推移维护它。

  1. 有人可能(错误地)认为,如果你有一个redis节点集群(带有副本),现在你就有了完全的持久性。这是虚假声明:
  • 所有db (sql,non-sql,redis,…)都有相同的问题-例如,在node1上运行set x 1,在所有其他节点上进行此(或任何)更改需要多长时间。因此,额外的读取将收到相同的输出。它取决于很多fucator和构型。
  • 处理多个节点(任何DB类型)中键值的不一致是一场噩梦。你可以从Redis Author (antirez): http://antirez.com/news/66读到更多关于它的信息。下面是一个在redis中存储状态的实际恶梦的简短示例(+一个解决方案- 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

上面的示例并不适用,并且存在一个真正的问题,即预先知道每个时刻实际有多少节点(和活动的)。

其他db也会有同样的问题。也许他们有更好的api,但问题仍然存在。

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

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


总结本研究,我们要做的是:

  1. 你的团队有多少开发人员(所以这项任务不会拖你后腿)?
  2. 你有一个熟练的devops吗?
  3. 你们团队的分布式系统技能是什么?
  4. 花钱买硬件?
  5. 是时候投资解决方案了吗?
  6. 也许更多……