Redis不仅仅是缓存,还是……
你需要一个经典数据库吗?
一段时间以来,巨大数量的数据处理迫使所有的应用程序在数据库层前添加缓存策略。即使经典数据库进行了大量的下划线优化,仍然不能提供足够的速度和可用性。主要原因在于数据存储越远,获取数据就越困难。另一个原因是因为数据库中的数据通常保存在磁盘中,而不是在内存。经典数据库却是在内存上嵌入了缓存来优化,但是拥有一个专用的独立缓存也是一种很常用的策略。
在解决访问数据库的性能问题,通常的解决方案是缓存。缓存并不新鲜,缓存实际上是把经常访问的少量数据保存在离你更近的地方。我们在处理器上有缓存,数据库中也有缓存,你甚至可以在自己的应用中编写缓存。
但随着事情的发展,现在我们有来高可用的分布式内存缓存,可以被不同的实例同时使用。
缓存——Redis
也许最流行的分布式内存数据存储是Redis,它不是缓存,但被当作缓存使用。 引用官方的描述如下:
Redis是一个开源的(BSD协议),内存中的数据结构存储,它可以用作数据库,缓存,消息代理。它支持的数据结构包括字符串,哈希,列表,集合,有序集合,位图,超级日志,具有半径查询和流的地理空间索引和流,Redis具有内置复制,Lua脚本,LRU驱逐,事务和不同级别的磁盘持久化,并通过Redis哨兵和Redis集群自动分区。
Redis速度很快,它被认为是目前最快的数据存储之一。它对CPU缓存进行了优化,并且没有上下文切换。从一开始它就被设计成了内存数据库,这不仅意味着将数据从磁盘移动到内存,它从一开始就针对性的优化了。
由于Redis速度非常快,可以存储各种数据结构,因此它是分布式缓存的一个很好的备选。
因为作为缓存,Redis获得了非常高的人气。有一些缓存加载器库在使用Redis作为应用程序和数据库之间的缓存层。以Redisson地图加载器为例:
因此,使用分布式缓存可以极大的提高性能。但是代码和架构变得更复杂了。数据被复制到数据库和缓存中,我们必须保持它们的数据同步。代码应该管理整个缓存策略,控制缓存失效,重新填充缓存,都是为了保持数据的一致性。我们实现了更高的性能和可伸缩性,但引入了高风险的复杂性。
数据是重复的
你可能会问为什么要在两个地方都保存数据?不能只保存Redis中的数据吗?如果这样做我们可以减少代码的复杂性。但首先让我们看看经典数据库的一下特点和优势,看看我们是否可以直接使用Redis实现这些。
关系型数据库的优点
传统来说,缓存是不会长期保存数据的。我们将数据保存在缓存中只是为了快速的访问,但是为了长时间的持久性,我们通常使用一个中央数据库。
除了数据的持久性以外,关系型数据库提供了数据一致性等其他特点。使用关系型数据库,你可以定义数据间的关系,约束,复杂查询,构建它是为了保证多个相关表间的一致性。
它有一些重要的优势,即使NoSQL数据库很流行,关系型数据库也不会很快消失。
但是使用Redis作为缓存和关系型数据库搭配使用,增加了一层复杂性,因为你必须通过代码保持两者的数据同步。
考虑到你的缓存策略,你不得不构建一些复杂的代码在Redis和数据库间进行数据发送。不要误解我的意思,有时候你必须这么做。就像之前提到的,关系型数据库有它的优点,我们不能把它扔掉。
但是我们必须每次都这么做吗?如果不同数据间不需要非常复杂的关系,而只存储一个键映射就足够了呢?我们是不是可以不用关系型数据库了?
Redis作为中央数据存储
如前所述,关系型数据库的优点是一致性和持久性。如果我们不需要数据之间的关系映射,那么它将只保留持久性。有很多NoSQL数据库提供键映射存储,但我们可以直接使用Redis。
Redis持久化
Redis有两种持久化模型:RDB和AOF。
RDB在指定的时间间隔保存数据快照。它们非常适合快速恢复备份。RDB最大化了Redis的性能,因为父进程所做的唯一工作就是fork创建快照的子进程。
但是由于RDB在一定时间间隔执行计划,如果你无法成熟丢失一些数据,那么这就不是一个好的选择。fork是一个高成本的操作,不能在每次数据变化都进行fork,因此可能会出现最近的数据没有被保存在快照中的情况。
AOF是一个不同的持久化模型。它是由一个只能追加的文件组成,只在其中添加所有数据。它更持久,因为fsync策略通常比整个RDB更有计划性。由于该文件仅用于追加,因此数据是不可更改的。即使在最后一条数据没有完全写完而出现断电,也可以很容易的重新断电前的构建状态。
但是它也有缺点。第一个是AOF文件通常比RDB更大。另外,如果fsync策略被调度的太频繁,举个例子,在每次写命令之后,那么性能会大打折扣。在默认情况下,fsync每秒运行一次。
你应该使用哪个?
如果你想要一个类似Postgres提供的安全级别,你讲不得不两种情况都使用。使用RDB可以让你在重启后更快的恢复备份;使用AOF可以避免数据丢失。但是如果你能成熟一些数据损失,那可以只使用RDB。记住,Redis会把它们合并成一个单一的持久化模型。
其他优势
未来是属于字节寻址的
由于磁盘旋转在很长一段时间都是持久化单元,所以当前的大多数数据库仍然在适应磁盘的旋转方面进行优化。比如数据定位,以减少磁盘旋转滞后,甚至选择了专门的格式,将索引放在了盘片的特定部分。但是这些优化对于当前的技术,比如SSD,是没有意义的。Redis存储数据是为字节殉职优化的。未来是属于字节寻址的,而Redis已经在那里了。
可伸缩性和高可用性
Redis提供了不同的方式来实现伸缩性和高可用性。
你可以在不同的Redis节点上分割数据来实现水平的可扩展性。分片将减轻单个实例的负担,你将受益于多核和计算能力。但是你应该知道分片的局限性,因为不能支持多键操作和事务。
通过复制获得高可用性。主节点是同步复制的,可以免受节点故障,数据中心故障和Redis进程故障。如果主节点宕机,副节点将会取而代之。在不同的AZ中也有一个副本,这将保护你免受灾难时间的影响,比如整个AZ失败。
如果你打算使用Redis企业集群,所有的这些对你都是抽象的,你将拥有分片和高可用性,而不需要额外的代码。你可以通过编码连接到一个Redis实例。
复杂数据结构
Redis不仅可以处理字符串,还可以处理不同的数据结构,如:二进制安全字符串,列表,集合,排序集合,位图,超级日志,流等等。这使得Redis不仅是一个键值存储,更是一个完整的数据结构服务器。
不是银弹
一切听起来都非常棒,但是作为一个事实,没什么东西是银弹,Redis也不是。主要的缺点是所有的数据都应该装进内存中。这使Redis适合那些有足够内存进行存储的数据。如果没有,那就必须将数据拆分。但是你会失去一下保证,如事务,管道,或发布/订阅。
结论
在很长一段时间里,Redis被认为只是一个缓存。一个非常好的分布式缓存,但仍然只是一个应用程序和主数据库之间的缓存。正如你所看到的,Redis不仅仅是一个缓存,它试图摆脱这个误解。Redis不是一个缓存,它是一个分布式数据存储。它可以以线程安全模式以令人难以置信的速度处理不同的数据结构,并为数据持久性提供了不同的机制。
考虑到所有这些,即使Redis被非常成功地用作缓存,它还是可以做更多的事情。如果你不需要一些像关系数据和高存储的SQL属性,为什么你要在应用程序中创建一个复杂的三层系统?Redis作为缓存和还是数据库?在这些情况下,你可以只使用Redis作为主要的持久层。
欢迎关注我的公众号,如果你有喜欢的外文技术文章,可以通过公众号留言推荐给我。
原文链接:https://dzone.com/articles/redis-is-not-just-a-cache
Redis不仅仅是缓存,还是……的更多相关文章
- Redis和memcached缓存技术
缓存的定义:缓存就是在内存中存储的数据备份,当数据没有发生本质变化的时候,我们避免数据的查询操作直接连接数据库,而是去 内容中读取数据,这样就大大降低了数据库的读写次数,而且从内存中读数据的速度 ...
- MySQL与Redis实现二级缓存
redis简介 Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库 Redis 与其他 key - value 缓存产品有以下三个特点: Redis支持数据的持久化, ...
- redis 和 memache 缓存的区别
总结一: 1.数据类型 Redis数据类型丰富,支持set list等类型 memcache支持简单数据类型,需要客户端自己处理复杂对象 2.持久性 redis支持数据落地持久化存储 memcache ...
- SpringBoot 结合 Spring Cache 操作 Redis 实现数据缓存
系统环境: Redis 版本:5.0.7 SpringBoot 版本:2.2.2.RELEASE 参考地址: Redus 官方网址:https://redis.io/ 博文示例项目 Github 地址 ...
- Redis-基本概念、java操作redis、springboot整合redis,分布式缓存,分布式session管理等
NoSQL的引言 Redis数据库相关指令 Redis持久化相关机制 SpringBoot操作Redis Redis分布式缓存实现 Resis中主从复制架构和哨兵机制 Redis集群搭建 Redis实 ...
- Net分布式系统之五:C#使用Redis集群缓存
本文介绍系统缓存组件,采用NOSQL之Redis作为系统缓存层. 一.背景 系统考虑到高并发的使用场景.对于并发提交场景,通过上一章节介绍的RabbitMQ组件解决.对于系统高并发查询,为了提供性能减 ...
- Spring Boot使用redis做数据缓存
1 添加redis支持 在pom.xml中添加 <dependency> <groupId>org.springframework.boot</groupId> & ...
- C#使用Redis集群缓存
C#使用Redis集群缓存 本文介绍系统缓存组件,采用NOSQL之Redis作为系统缓存层. 一.背景 系统考虑到高并发的使用场景.对于并发提交场景,通过上一章节介绍的RabbitMQ组件解决.对于系 ...
- 在AspNetCore 中 使用Redis实现分布式缓存
AspNetCore 使用Redis实现分布式缓存 上一篇讲到了,Core的内置缓存:IMemoryCache,以及缓存的基础概念.本篇会进行一些概念上的补充. 本篇我们记录的内容是怎么在Core中使 ...
随机推荐
- 1.Cobaltstrike 安装与简介
1.Cobaltstrike 安装与简介 一.简介 Cobalt Strike是一款美国Red Team开发的渗透测试神器,常被业界人内称为CS.自去年起, Cobaltstrike升级到3.0版本, ...
- Kafka作为分布式消息系统的系统解析
Kafka概述 Apache Kafka由Scala和Java编写,基于生产者和消费者模型作为开源的分布式发布订阅消息系统.它提供了类似于JMS的特性,但设计上又有很大区别,它不是JMS规范的实现,如 ...
- CountDownLatch、CyclicBarrier、Semaphore、Exchanger 的详细解析
本文主要介绍和对比我们常用的几种并发工具类,主要涉及 CountDownLatch . CyclicBarrier . Semaphore . Exchanger 相关的内容,如果对多线程相关内容不熟 ...
- 新手上路之JDK11的下载、安装与PATH环境变量的配置
目录 JDK11的下载 找到目标JDK JDK的下载 JDK11的安装 PATH环境变量的配置 为什么要配置环境变量? 配置前再检查一遍 配置变量 检查环境变量配置成功与否 细究起来,JDK11与JD ...
- 真香!Python开发工程师都选择这个数据库:因为它免费
数据库类别 既然我们要使用关系数据库,就必须选择一个关系数据库. 目前广泛使用的关系数据库也就这么几种: 付费的商用数据库: Oracle,典型的高富帅: SQL Server,微软自家产品,Wind ...
- 数据库:Flask-SQLAlchemy
一.安装以及使用 1.安装 安装 flask-sqlalchemy pip install flask-sqlalchemy 如果连接的是 mysql 数据库,需要安装 mysqldb pip ins ...
- 阿里云ECS服务器连接MongoDB
第一次接触MongoDB,第一次部署.将一些步骤整理出来,希望以后会用到,也希望能帮组到有这方面需求的小伙伴. 设备说明: 服务器为阿里云ECS服务器,网络为专有网络VPC,Mango为买的阿里云Ma ...
- Python爬虫实战案例:取喜马拉雅音频数据详解
前言 喜马拉雅是专业的音频分享平台,汇集了有声小说,有声读物,有声书,FM电台,儿童睡前故事,相声小品,鬼故事等数亿条音频,我最喜欢听民间故事和德云社相声集,你呢? 今天带大家爬取喜马拉雅音频数据,一 ...
- 第8.3节 Python类的__init__方法深入剖析:构造方法与继承详解
第8.3节 Python类的__init__方法深入剖析:构造方法与继承详解 一. 引言 上两节介绍了构造方法的语法及参数,说明了构造方法是Python的类创建实例后首先执行的方法,并说明如果类 ...
- CSP-S 2020 游记
2020.10.11 初赛了,没怎么做题,之前在网上两次初赛模拟赛 95pts / 94pts,还白嫖了一本书,感觉挺好. 去考场,中途不舒服去了厕所,回来发现有点来不及,阅读程序最后两题不会瞎蒙. ...