当前位置: 首页 > news >正文

Redis 特性/应用场景/通用命令

目录

1. Redis 特性

2. Redis 应用场景

3. 安装 Redis

4. Redis 命令

4.1 set & get

4.2 全局命令/通用命令

4.2.1 keys

4.2.2 exists

4.2.3 del

4.2.4 expire

4.2.5 ttl

4.2.6 type

5. Redis 过期策略 [经典面试题]

6. [拓展] 通过定时器实现 Redis 过期策略

6.1 基于优先级队列/堆

6.2 基于时间轮


1. Redis 特性

Redis 是一个在内存中存储数据的中间件, 而它最常见的用途是作为缓存或者数据库使用.

  • 内存: 指的是计算机的 RAM(随机存取存储器), 是一个真实的物理硬件组件.
  • 缓存: 是一种技术思想, 作用是临时存储那些会被频繁访问的 "热点" 数据, 从而加快访问速度.

Redis 具有以下优秀特性:

  1. 将数据存储在内存中, 并且支持多种数据结构类型, 如: strings(字符串)/hashs(哈希)/lists(列表)/sets(集合)/sorted(有序集合)/streams(流)/...
    1. Redis 主要是通过 "键值对" 的方式来存储数据, 其中 key 都是 字符串, 而 value 就是上述的数据结构. 因此, Redis 为 "非关系型数据库".
    2. 而 MySQL 是以 "表" 的方式来存储数据的, 称为 "关系型数据库".
  2. 可编程的:  操作 Redis 时, 可以直接通过简单的交互式命令进行操作, 也可以通过编写脚本, 批量执行一些操作(可以执行一些逻辑). 
    1. 对于 Redis 的编程操作, 主要使用 Lua ("露啊") 作为脚本语言.
  3. 可拓展性: Redis 提供了一组 API, 用户可以在 Redis 原有功能的基础上, 使用 C/C++/Rust/... 编写 Redis 扩展(本质上是一个动态链接库).
    1. 比如: Redis 提供了多种数据结构和命令. 通过扩展, 就可以让 Redis 支持更多的数据结构和命令.
  4. 持久性: Redis 也可以持久化的保存数据, 不仅存在内存中, 也存在硬盘上.
    1. 如果只是将数据存到内存中, 那么系统重启/进程退出 内存上的数据都会丢失. 因此, Redis 不只是将数据存储在内存上, 也会把存到硬盘中. 但是, 是以 "内存为主, 硬盘为辅", 硬盘上的数据只是作为 "备份", 以防数据丢失.
    2. Redis 对数据进行增删改查操作, 都是针对内存数据进行的, 硬盘数据只是内存数据的 "备份", 如果 Redis 重启了, 就会重新加载硬盘中的备份数据, 使 Redis 中的数据恢复到重启前的状态.
  5. 支持集群: 一个 Redis 存储的数据是有限的(内存空间有限), 因此 Redis 通过 水平扩展 引入多个主机, 部署多个 Redis 节点, 每个 Redis 节点存储一部分数据.
  6. 可用性高: Redis 支持 "主从" 结构的架构模式, 因此 "从节点" 就相当于 "主节点" 的备份, 当 主节点 出现问题时, 从节点就可以临时充当主节点.
  7. Redis 速度快(增删查改都快): 
    1. Redis 把数据存到内存中, 因此比访问硬盘要快得多.
    2. Redis 核心功能都是比较简单的逻辑, 比较简单的操作内存的数据结构
    3. 从网络角度上看, Redis 采用了 IO 多路复用的方式(epoll). (使用一个线程, 管理很多 socket, 也就是, 一个线程, 监听和处理多个网络连接)
    4. Redis 使用的是单线程模型, 因此减少了不必要的线程之间的竞争开销.
      1. 意: 多线程能够提高效率的前提是, 执行的是 CPU 密集型任务. 因此, 这类任务, 可以使用多线程充分利用 CPU 多核资源.
      2. 而 Redis 的核心任务, 就是操作内存上的数据结构, 这不会消耗很多 CPU.
    5. Redis 使用的是 C 语言开发的, 因此速度快. [?? 但是 MySQL 也是 C 开发的...] 

注意:

redis 的 "快" 是相对于 mysql 来说快.

但是如果是直接和 内存中的操作变量 区去比(比如: 直接把键值对存到 HashMap 中), 那就慢很多了:

  1. 存 HashMap 属于内存中的数据操作, 直接在程序的内存空间中进行(这里是堆).
  2. 而 redis 是需要先经过网络, 再操作内存的.
    1. 因为 redis 是 客户端-服务器 程序, 因此 数据操作命令 是在客户端发起的, 那么这个命令就需要经过网络传输到达服务器, 服务器解析后, 再去内存中执行相应的数据操作, 执行完毕后, 操作结果还需要再经过网络传输回客户端, 客户端才收到响应结果.

2. Redis 应用场景

  1. 存储实时数据: 把 Redis 当做数据库使用. [对性能要求高的场景, 比如: 搜索引擎] 
    1. 既然把 Redis 当做数据库, 那么就需要把所有的数据都 全量 的存储到 Redis 中, 因此就需要更大的内存空间(扩充硬件资源)
  2. 缓存存储 & 会话存储
    1. 缓存存储: Redis 用作缓存, 就是我们上篇文章提到的 "冷热分离", 把热点数据存到缓存(Redis)中. 
    2. 会话存储: Redis 用来保存应用服务器端的 session 信息.
      1. 背景: 在传统的服务器集群中, 如果将用户 session 保存在单个服务器的内存里, 会产生一个问题: 当负载均衡器将用户的后续请求分配到另一台服务器时, 新服务器无法识别用户的登录状态, 会导致用户需要重新登录.
      2. 解决办法: 
        1. 想办法让负载均衡器把同一个用户的请求分配到同一个机器上.(可以根据 userId 进行分配)
        2. 把 session 从服务器中抽取出来, 存储到一个独立的服务器上(Redis). 哪怕应用服务器重启, session 数据也不会丢失.
  3. 用作消息队列, 实现一个生产者消费者模型(在分布式系统中, 服务器和服务器之间, 需要通过消息队列来 解耦合/削峰填谷). (这里说的 "消息队列" 是一个服务器, 就像 RabbitMQ/Kafka/RocketMQ 那些)

3. 安装 Redis

在 Linux Ubuntu 系统上安装 Redis.

redis 和 mysql 一样, 都是 客户端-服务器 结构的程序, 因此我们需要先安装 redis-server, 再通过 redis 客户端操作 redis.

  1. 首先使用 su 命令切换到 root 用户.
  2. 使用 apt 命令搜索 Redis 相关软件包.
    apt search redis
  3. 使用 apt 命令安装 Redis
    apt insatll redis

此时, 我们已经安装好了 Redis, 使用 netstat 命令查看一下 Redis 网络状态.

发现, Redis 服务器 ip 为 127.0.0.1, 也就意味着这个 Redis 服务器只能由当前主机上的客户端访问, 跨主机就无法访问, 因此, 我们需要修改一下配置文件:

# 进入配置文件目录
cd /etc/redis/

使用 vim 命令编辑 redis.conf , 做出以下修改:

修改完配置后, 重启服务器让配置生效:

service redis-server restart

最后一步, 使用 redis 自带的客户端, 连接本机 redis 服务器:

redis-cli

 也可以通过 redis-cli 连其他的 redis 服务器, 输入服务器对应 ip 和 port 即可:

redis-cli -h [IP] -p [端口]

检验: 输入 ping, 若出现 PONG 则说明连接成功

(使用 ctrl + d 退出 redis 客户端)

4. Redis 命令

4.1 set & get

get 和 set 是 Redis 中最核心的两个命令.

get 和 set 不是全局命令, 它们是专门针对 String 数据类型的命令. (也就是说, key 和 value 都是字符串, 但是不用手动加 引号, Redis 会自动加上)

  1. get: 根据 key 获取 value. (前面说过, Redis 是以 键值对 的形式存储数据的)
  2. set: 存储 key 和 value

其中, key 和 value 都是字符串. 

注意: Redis 中的命令, 不区分大小写, 但是存储的数据区分大小写.

使用 get 根据 key 获取 value 时, 如果 key 不存在, 则返回 nil(如上图所示), nil 和 null/NULL/None 是一个意思.

4.2 全局命令/通用命令

之前提到, Redis 支持很多种数据结构, 比如: 字符串, 列表, 集合, 哈希....

在 Redis 中, 操作不同的数据结构, 使用的命令是不同的, 像上文的 get/set 就是操作字符串的专属命令.

但是, 而 全局命令, 可以操作所有数据结构.

4.2.1 keys

keys 是用来查询 Redis 服务器上所匹配的 key 的全局命令.

语法为: keys pattern

其中, pattern 是 包含特殊符号的字符串, 用来描述要查找的 key 的样式.

pattern 的使用如下:

  • ? 匹配任意一个字符 => h?llo 匹配 hello/hallo/hbllo/...
  • * 匹配 0 个或多个任意字符 => h*llo 匹配 hllo/heeeeello/haaaallo
  • [abc] 只能匹配 a b c 其中一个字符 => h[abc]llo 匹配 hallo/hbllo/hcllo, 不匹配 habllo//hdllo
  • [^e] 匹配任意一个不是 a 的单一字符 => h[^e]llo 不能匹配 hello
  • [a-c] 匹配 a - c 范围内的任意一个字符(左闭右闭) => h[a-c]llo 匹配 hallo/hbllo/hcllo 

注意:

keys 是从服务器中一个一个的找有没有符合条件的 key 的, 因此时间复杂度为 O(N).

在生产环境中, key 是非常多的, 而 Redis 是一个单线程服务器, 执行 keys 的时间就会非常长, Redis 服务器就会处于阻塞状态, 也就无法给其他 Redis 客户端提供服务了. 这是一个非常严重的事情!!

因此, 在生产环境中, 一般会禁用 keys 命令, 尤其是 keys *(查询 Redis 上的所有 key)

4.2.2 exists

exists 命令用于判断 key 是否存在(可以一次查一个或者多个 key).

语法: exists key1 [key2 ...]

返回值: 返回 key 存在的个数. 时间复杂度为 O(1)

注意: Redis 是用哈希表来管理所有的 key 的, 因此时间复杂度为 O(1). 正因如此, Redis 中的 key 是唯一的, 如果存入了重复的 key, 那么新的 value 会覆盖旧的 value.

注意:

一次的 exists hallo hcllo(一次网络 IO)是比单独的一次的 exists hallo 加上单独的一次的 exists hcllo 效率要高的(两次网络 IO).

因为 Redis 是客户端-服务器结构的程序, 客户端和服务器之前是通过网络来通信的.

4.2.3 del

del 命令用于删除某个键值对(可以一次删除一个或多个 key).

语法: del key1 [key2 ...]

返回值: 删除掉的 key 的个数.

时间复杂度: O(1)

4.2.4 expire

expire 是给指定的 key 设置过期时间, 单位为 秒, 到期后 key 就会自动被删除. (如果想设置毫秒, 使用 pexpire)

语法: expire key seconds

返回值: 设置成功返回 1, 设置失败返回 0 (如果 key 不存在, 就会返回 0)

时间复杂度: O(1)

expire 有很多的使用场景, 比如:

  1. 手机验证码: 超过指定时间后, 服务器从 Redis 中就查不到这个值了, 就会判定用户验证失败.  
  2. 外卖平台优惠券有效时间
  3. 基于 Redis 实现分布式锁: 在分布式系统中, 是针对不同的服务器加锁, 当一个服务器获取锁后, 若这个服务器突然挂机, 那么这把锁就无法被释放, 其他服务器就无法获取该锁. 为避免上述情况, 就会在加锁的时候设置一下锁的过期时间, 到期后锁就会自动释放. (基于 Redis 实现分布式锁, 就是在 Redis 中写入一个特殊的 key-value, 给这个 key 设置一个超时时间, 到期后这个 key 就会自动被删除, 也就释放锁了)

4.2.5 ttl

ttl(time to live), 查看 key 剩余的过期时间(秒), (key 还有多久过期), 通常和 expire 搭配使用.

语法: ttl key

返回值: 剩余过期时间, -1 表示这个 key 没有设置过期时间(秒), -2 表示 key 不存在.

若查看剩余的毫秒, 使用 pttl

4.2.6 type

type 用来查询 key 对应的 value 的数据类型. 

语法: type key

返回值: value 的数据类型. 常见的类型有:

  1. none: key 不存在
  2. string: 字符串
  3. list: 列表
  4. hash: 哈希
  5. set: 集合
  6. zset: 有序集合
  7. stream: Redis 作为消息队列时, 才使用这个类型的 value

注: Redis 中, key 对应的 value 可能存在多种类型, 不同类型对应的命令不同, 因此要使用某个 value 时, 可以先用 type 查一下类型, 再使用对应的命令去操作.

5. Redis 过期策略 [经典面试题]

一个 Redis 服务器中, 可能存在存在非常多的 key, 那 Redis 是怎样判断哪些 key 过期了, 那哪些 key 没有过期呢? 如果是一个一个遍历, 那么时间复杂度为 O(N), 效率很低.

Redis 采取的是 "惰性删除" 和 "定期删除" 结合的策略:

  • 惰性删除: 假设某个 key 已经到期了, 但是 Redis 没有主动的删除他, 而是当用户后续请求访问这个 key 时, Redis 才发现他已经过期了, 于是这次访问触发了 Redis 对这个 key 的删除操作, 同时给这次请求返回一个 nil
  • 定期删除: 每隔一段时间, 抽取一部分的 key, 验证他们的过期时间, 如果过期就删除. (因为 Redis 中存的 key 是很多的, 如果检查所有的 key , 那么效率是很低的, 因此就通过控制抽取 key 的数量, 来约束消耗的时间. )

为啥要定期删除:

因为 Redis 是单线程的程序, 主要的任务(处理每个命令, 如: get set/扫描过期 key)都是在一个线程中完成的, 如果扫描过期 key 消耗的时间太多, 那么就会导致 处理正常请求的命令(上面的各种 get/set/...) 被阻塞, 用户看起来就像 Redis 挂了一样. (会产生类似 keys * 的效果)

虽然 Redis 采取的是 惰性删除 和 定期删除 结合的策略, 但是效果一般, 仍然会存在很多过期 key 残留的情况, 因此, Redis 还采取了 内存淘汰策略.

注意: 除了上述的策略外, 网上还流传 "定时删除" (给 key 创建定时器, 时间到了就删除)的策略, 但实际上,  Redis 并没有采取这种方式.

6. [拓展] 通过定时器实现 Redis 过期策略

定时器: 当约定的时间到达后, 就执行某个任务. 

在 Redis 这里, 就是到达 key 的过期时间后, 删除这个 key.

实现方式有两种:

  1. 优先级队列/堆
  2. 时间轮

注意: Redis 并没有采取这两种方式, 仅为拓展.

6.1 基于优先级队列/堆

根据 key 的过期时间, 定义优先级规则: 把过期时间早的 key, 放到堆顶, 也就是最先出队列.

分配一个线程, 去检查堆顶元素的剩余过期时间, 如果堆顶元素到达过期时间了, 就把堆顶元素移除. 此时, 这个线程只需关注堆顶元素即可, 如果堆顶元素都还没有过期, 那么其他元素也一定没有过期.

注意: 检查堆顶元素的操作, 不能检查的太频繁, 如果以循环的方式去检查, 那么就类似 "忙等", 会一直消耗 CPU 资源. 那么, 可以根据当前时刻 和 堆顶元素的过期时间, 给线程设置一个等待, 当 堆顶元素 快要过期时, 再去唤醒这个线程. (比如: 堆顶元素 12 点过期, 现在是 11 点, 那么就让线程休眠 1h, 1h 后再唤醒这个线程)

如果在线程休眠的过程中, 来了一个新的 key(可能比当前堆顶元素更提前执行), 那么就可以在添加元素的时候, 唤醒线程, 根据时间差距再重新设置一下阻塞时间.

6.2 基于时间轮

时间轮, 就是把时间分成很多时间段.(每小段时间的粒度, 根据实际需求调整) 

有一个时间指针, 这个时间指针每隔一个时间段, 就会移动一下, 并且执行对应格式上的任务.


END

http://www.dtcms.com/a/513403.html

相关文章:

  • 学生个人网站建设模板网站为什么做站外推广
  • 零基础学网站建设 知乎长治长治那有做网站的
  • RPC服务
  • 北京外贸网站设计备案邯郸网页
  • 素马网站制作开发腾讯朋友圈广告怎么投放
  • 网站开发包括哪些网站推广怎么做
  • SwiftUI自定义一个水平渐变进度条
  • 电力电子技术 第四章——半导体功率器件
  • 网站运营专员具体每天怎么做wordpress音乐加载慢
  • 网站建设中图片是什么意思推特是谁的公司
  • 免费做手机网站有哪些wordpress注册邮箱收不到
  • 搜狗网站排名软件国内图片下载网站
  • wordpress 百度平台网站优化排名
  • 22.unordered_map和unordered_set的封装
  • 网站框架图片二维码生成器网页版
  • 做3d效果的网站wordpress中文问答模块
  • 杭州网站推广优化哪里好wordpress编辑文章更新失败
  • 工信部网站 地址呼伦贝尔网站建设维护
  • 帝国网站数据库配置文件网站建设程序员
  • 找别人做淘客网站他能改pid吗全网营销策划公司
  • 温州建设小学瓯江校区网站wordpress 订阅推送
  • 全屏网站帮助2021十条重大新闻
  • 自动识别手机和电脑版本网站阿里网站建设视频教程
  • 银行网站建设中优化大师下载电脑版
  • 网站建设的通知网站维护分工关键词爱站网关键词挖掘工具
  • 盘锦市住房和城乡建设厅网站济南的企业网站建设
  • Aspose.Total for .NET Crack
  • 企业建设银行网站登录不了网络推广方案有哪些
  • 苏州网站建设免费网站制作平台
  • 做外贸的网站有何用处阜阳企业网站推广