【Redis】1.Redis特性

文章目录

  • [1. 初识 Redis](#1. 初识 Redis)
    • [1.1 Redis 特性](#1.1 Redis 特性)
      • [1.1.1 速度快](#1.1.1 速度快)
      • [1.1.2 基于键值对的数据结构服务器](#1.1.2 基于键值对的数据结构服务器)
      • [1.1.3 丰富的功能](#1.1.3 丰富的功能)
      • [1.1.4 简单稳定](#1.1.4 简单稳定)
      • [1.1.5 客户端语言多](#1.1.5 客户端语言多)
      • [1.1.6 持久化(Persistence)](#1.1.6 持久化(Persistence))
      • [1.1.7 主从复制(Replication)](#1.1.7 主从复制(Replication))
      • [1.1.8 高可用(High Availability)和分布式(Distributed)](#1.1.8 高可用(High Availability)和分布式(Distributed))
    • [1.2 Redis 使用场景](#1.2 Redis 使用场景)
      • [1.2.1 Redis和MySQL](#1.2.1 Redis和MySQL)
      • [1.2.2 Redis 可以做什么](#1.2.2 Redis 可以做什么)
      • [1.2.3 为什么要用Redis](#1.2.3 为什么要用Redis)
    • [1.3 Redis 使用场景](#1.3 Redis 使用场景)
      • [1.3.1 Redis 可以做什么](#1.3.1 Redis 可以做什么)
      • [1.3.2 Redis 不可以做什么](#1.3.2 Redis 不可以做什么)

1. 初识 Redis

1.1 Redis 特性

Redis 之所以受到如此多公司的青睐,必然有之过人之处,下面是关于 Redis8 个重要特性:

  1. 速度快
  2. 基于键值对的数据结构服务器
  3. 丰富的功能
  4. 简单稳定
  5. 客户端语言多
  6. 持久化
  7. 主从复制
  8. 高可用 和 分布式
  • MySQL主要是通过"表"的方式来存储组织数据的"关系型数据库"

  • Redis主要是通过"键值对"的方式来存储组织数据的"非关系型数据库"

    key都是stringvalue则可以是strings,hashes,lists,sets,streams......
    针对Redis的操作,可以直接通过简单的交互式命令进行操作。也可以通过一些脚本的方式,批量执行一些操作(可以带有一些逻辑)

redis主要用Lua(读音:撸啊)作为编写脚本的语言

Redis提供了一组 API,可以在 Redis原有的功能基础上再进行扩展。

通过CC++Rust通过这几个语言编写Redis扩展(本质上就是一个动态链接库)自己去扩展Redis 的功能。

比如,Redis自身已经提供了很多的数据结构和命令。通过扩展,让Redis支持更多的数据结构,以及支持更多的命令


1.1.1 速度快

正常情况下,Redis 执行命令的速度非常快,官方给出的数字是读写性能可以达到 10 万 / 秒,当

然这也取决于机器的性能,但这里先不讨论机器性能上的差异,只分析一下是什么造就了 Redis 如此之快,可以大概归纳为以下四点:

  1. Redis 的所有数据都是存放在内存中的,表 1-1 是谷歌公司 2009 年给出的各层级硬件执行速度,所以把数据放在内存中是 Redis 速度快的最主要原因。

  2. Redis核心功能都是比较简单的逻辑。核心功能都是比较简单的操作内存的数据结构。

  3. 从网络角度上,Redis使用了I/O多路复用的方式(epoll) 。使用一个线程,管理很多个socket

  4. Redis 是用 C 语言实现的,一般来说 C 语言实现的程序 "距离" 操作系统更近,执行速度相对会更快。(不过实际上MySQL也是C语言写的,所以这个说法有待商榷。虽然如果用python写的话,确实比C语言慢,这个只能看自己的主观了。)

  5. Redis 使用了单线程,预防了多线程可能产生的竞争问题。Redis6.0 版本引入了多线程机制,但主要也是在处理网络和 I/O,不涉及到数据命令,即命令的执行仍然采用了单线程模式。这样的单线程模型,减少了不必要的线程之间的竞争开销。

    这里要注意:多线程虽然可以提高效率,但不是所有情况都可以提高,需要具体情况具体分析。

    多线程提高效率的前提是:CPU密集型任务,使用多个线程可以充分利用CPU多核资源。

    但是对于Redis来说,核心任务是操作内存的数据结构,不会消耗很多CPU。如果使用多线程,反而会因为加锁导致锁竞争,唤醒等等导致速度慢。

  6. 作者对于 Redis 源代码可以说是精打细磨,曾经有人评价 Redis 是少有的集性能和优雅于一身的开源代码。

谷歌公司给出的各层级硬件执行速度:


1.1.2 基于键值对的数据结构服务器

几乎所有的编程语言都提供了类似字典的功能,例如 C++ 里的 mapJava 里的 mapPython 里的 dict 等,类似于这种组织数据的方式叫做基于键值对的方式,与很多键值对数据库不同的是,Redis 中的值不仅可以是字符串,而且还可以是具体的数据结构。

这样不仅能便于在许多应用场景的开发,同时也能提高开发效率。Redis 的全程是 REmote Dictionary Server,它主要提供了 5 种数据结构:字符串(string)、哈希(hash)、列表(list)、集合(set)、有序集合(ordered set / zet),同时在字符串的基础之上演变出了位图(Bitmaps)和 HyperLogLog 两种神奇的 "数据结构"。

并且随着 LBSLocation Based Service,基于位置服务)的不断发展,Redis 3.2. 版本中加入有关 GEO(地理信息定位)的功能,总之在这些数据结构的帮助下,开发者可以开发出各种 "有意思" 的应用。


1.1.3 丰富的功能

除了 5 种数据结构,Redis 还提供了许多额外的功能:

  • 提供了键过期功能,可以用来实现缓存。
  • 提供了发布订阅功能,可以用来实现消息系统。
  • 支持 Lua 脚本功能,可以利用 Lua 创造出新的 Redis 命令。
  • 提供了简单的事务功能,能在一定程度上保证事务特性。
  • 提供了流水线(Pipeline)功能,这样客户端能将一批命令一次性传到 Redis,减少了网络的开销。

1.1.4 简单稳定

Redis 的简单主要表现在三个方面。首先,Redis 的源码很少,早期版本的代码只有 2 万行左右,3.0 版本以后由于添加了集群特性,代码增至 5 万行左右,相对于很多 NoSQL 数据库来说代码量相对要少很多,也就意味着普通的开发和运维人员完全可以 "吃透" 它。其次,Redis 使用单线程模型,这样不仅使得 Redis 服务端处理模型变得简单,而且也使得客户端开发变得简单。最后,Redis 不需要依赖于操作系统中的类库(例如 Memcache 需要依赖 libevent 这样的系统类库),Redis 自己实现了事件处理的相关功能。

但与简单相对的是 Redis 具备相当的稳定性,在大量使用过程中,很少出现因为 Redis 自身 BUG 而导致宕掉的情况。


1.1.5 客户端语言多

Redis 提供了简单的 TCP 通信协议,很多编程语言可以很方便地接入到 Redis,并且由于 Redis 受到社区和各大公司的广泛认可,所以支持 Redis 的客户端语言也非常多,几乎涵盖了主流的编程语言,例如 C、C++、Java、PHP、Python、NodeJS 等,后续我们会对 Redis 的客户端使用做详细说明。


1.1.6 持久化(Persistence)

通常看,将数据放在内存中是不安全的,一旦发生断电或者机器故障,重要的数据可能就会丢失,因此 Redis 提供了两种持久化方式:RDBAOF,即可以用两种策略将内存的数据保存到硬盘中(如图 1-1 所示),这样就保证了数据的可持久性,后续我们将对 Redis 的持久化进行详细说明。图 1-1 Redis 内存到硬盘的持久化


1.1.7 主从复制(Replication)

Redis 提供了复制功能,实现了多个相同数据的 Redis 副本(Replica)(如图 1- 2 所示),复制功能是分布式 Redis 的基础。后续我们会对 Redis 的复制功能进行详细演示。图 1-2 Redis 主从复制架构


1.1.8 高可用(High Availability)和分布式(Distributed)

Redis 提供了高可用实现的 Redis 哨兵(Redis Sentinel),能够保证 Redis 结点的故障发现和故障自动转移。也提供了 Redis 集群(Redis Cluster),是真正的分布式实现,提供了高可用、读写和容量的扩展性。


1.2 Redis 使用场景

1.2.1 Redis和MySQL

Redis是在内存中存储数据的,只有在分布式系统中才能发挥威力。如果只是单机程序,直接通过变量存储数据的方式,是比使用Redis更优的选择。

进程有隔离性,每个进程的进程空间都是被隔离开的,也就是A进程无法读取进程B内存中的数据。

因此,在分布式系统上,一个进程想要读取其他进程就变得困难起来了。因为其他进程有隔离性,而且可能在不同的主机上。

Redis就相当于针对上述的需求点,进行了一个封装。虽然进程有隔离性,但是存在进程间通信。而且可以通过网络跨主机,进行进程间通信。Redis就是基于网络,把自己内存中的变量给其他的进程,甚至别的主机的进程进行使用。

MySQL最大的问题在于,访问速度比较慢。很多互联网产品中,对于性能要求很高。

相对于MySQL的频繁I/ORedis也可以作为数据库使用,而且快很多,内存的操作速度比外存大概快十万倍。光这么看的话,似乎应该都选Redis,但是实际上很难定量衡量Redis到底比MySQL快很多。因为两者相差的功能和使用场景各有差异,无法控制变量来进行速度的快慢比较。

Redis的最大的劣势在于,存储空间有限。内存虽然快,但是小。而且虽然很多互联网产品中,对于性能要求很高。但是更多的互联网产品对性能的要求没那么高。

如果要又大又快,可以实现吗?可以把RedisMySQL结合起来使用。例如:把Redis当成MySQLcache。根据二八定律,20%的热点数据,能满足80%的访问需求。那么,20%的热点数据用Redis,其余80%的非热点数据用MySQL全量存储。不过这么做的话,系统的复杂度大大提升,而且如果数据修改会涉及到RedisMySQL的数据同步问题。

redis其实最初被研发出来,就是用来作为一个"消息中间件"的(消息队列)-------为了解决分布式系统下的"生产者消费者模型"。结果发展起来后,做数据库或者缓存更好用。当前也很少用redis作为消息中间件,因为有更好用的消息中间件。


1.2.2 Redis 可以做什么

要充分理解 Redis 的作用,需要对网站的架构有一定的基础理解,可以先看一下这个博主的这篇文章:

服务端高并发分布式结构演进之路


1.2.3 为什么要用Redis

cookie是实现用户身份信息保存的,只是在浏览器这边存储了一个用户的身份标识sessionId。需要session配合。

之前的session是存储在应用服务器上的。服务器这里真正存储用户数据。

总不至于让用户再登陆一次把?
如何解决上述问题?

  1. 想办法让负载均衡器,把同一个用户的请求始终打到同一个机器上(也就是不能轮询了,而是要通过userld之类的方式来分配机器,同一台userid到一个机器上)

  2. 把会话数据单独拎出来,放到一组独立的机器上存储(Redis:应用程序重启了,会话不丢失)


1.3 Redis 使用场景

1.3.1 Redis 可以做什么

  1. 缓存(Cache

    缓存机制几乎在所有大型网站都有使用,合理地使用缓存不仅可以加速数据的访问速度,而且能够有效地降低后端数据源的压力。Redis 提供了键值过期时间设置,并且也提供了灵活控制最大内存和内存溢出后的淘汰策略。可以这么说,一个合理的缓存设计能够为一个网站的稳定保驾护航。

  2. 排行榜系统

    排行榜系统几乎存在于所有的网站,例如按照热度排名的排行榜,按照发布时间的排行榜,按照各种复杂维度计算出的排行榜,Redis 提供了列表和有序集合的结构,合理地使用这些数据结构可以很方便地构建各种排行榜系统。

  3. 计数器应用

    计数器在网站中的作用至关重要,例如视频网站有播放数、电商网站有浏览数,为了保证数据的实时性,每一次播放和浏览都要做加 1 的操作,如果并发量很大对于传统关系型数据的性能是一种挑战。Redis 天然支持计数功能而且计数的性能也非常好,可以说是计数器系统的重要选择。

  4. 社交网络

    赞 / 踩、粉丝、共同好友 / 喜好、推送、下拉刷新等是社交网站的必备功能,由于社交网站访问量通常比较大,而且传统的关系型数据不太合适保存这种类型的数据,Redis 提供的数据结构可以相对比较容易地实现这些功能。

  5. 消息队列系统

    消息队列系统可以说是一个大型网站的必备基础组件,因为其具有业务解耦、非实时业务削峰等特性。Redis 提供了发布订阅功能和阻塞队列的功能,虽然和专业的消息队列比还不够足够强大,但是对于一般的消息队列功能基本可以满足。


1.3.2 Redis 不可以做什么

实际上和任何一门技术一样,每个技术都有自己的应用场景和边界,也就是说 Redis 并不是万金油,有很多合适它解决的问题,但是也有很多不合适它解决的问题。我们可以站在数据规模和数据冷热的角度来进行分析。

站在数据规模的角度看,数据可以分为大规模数据和小规模数据,我们知道 Redis 的数据是存放在内存中的,虽然现在内存已经足够便宜,但是如果数据量非常大,例如每天有几亿的用户行为数据,使用 Redis 来存储的话,基本上是个无底洞,经济成本相当高。

站在数据冷热的角度,数据分为热数据和冷数据,热数据通常是指需要频繁操作的数据,反之为冷数据,例如对于视频网站来说,视频基本信息基本上在各个业务线都是经常要操作的数据,而用户的观看记录不一定是经常需要访问的数据,这里暂且不讨论两者数据规模的差异,单纯站在数据冷热的角度上看,视频信息属于热数据,用户观看记录属于冷数据。如果将这些冷数据放在 Redis 上,基本上是对于内存的一种浪费,但是对于一些热数据可以放在 Redis 中加速读写,也可以减轻后端存储的负载,可以说是事半功倍。

所以,Redis 并不是万金油,相信随着我们对 Redis 的逐步学习,能够清楚 Redis 真正的使用场景。

相关推荐
奶糖 肥晨1 小时前
DBeaver 安装与 MySQL 连接配置教程
数据库·mysql
chexus1 小时前
21. 深入 Nginx HTTP 缓存源码:CDN功能
nginx·http·缓存
woshihuanglaoshi1 小时前
数据迁移与版本管理 - Flutter在鸿蒙平台实现数据库升级策略
数据库·学习·flutter·华为·harmonyos·鸿蒙·鸿蒙系统
java_logo3 小时前
Apache Doris Docker 部署指南:实时分析数据库实战
数据库·docker·apache·doris·apache doris·轩辕镜像·docker部署doris
广州灵眸科技有限公司11 小时前
xfce桌面触摸校准:基于灵眸科技EASY-EAl-Orin-Nano
数据库·windows·科技
憧憬成为web高手13 小时前
皮卡丘靶场速通--sql 2
数据库·sql·mybatis
段一凡-华北理工大学14 小时前
向量数据库实战:选型、调优与落地~系列文章12:文本分块策略实战:chunk_size 怎么选?重叠多少?
开发语言·数据库·后端·oracle·rust·工业智能体·高炉智能化
二宝哥14 小时前
CentOS 7.9 系统下 Redis 5.0.4 单机安装与源码编译安装指南
redis·centos
oradh16 小时前
Oracle XTTS实现跨版本迁移和升级(Oracle 11g单库升级至19C RAC集群)
数据库·oracle·11g升级19c·xtts跨版本迁移和升级