Redis讲解

野性酷女 2022-11-09 12:35 308阅读 0赞

一、redis使用

1.1 开启reids服务器端

在这里插入图片描述

1.2 开启redis客户端

在这里插入图片描述
基本使用(修改密码):
方法一:直接在客户端进行修改

  1. 查看当前的密码 config get requirepass
  2. 设置新的密码 config set requirepass 123456
  3. 再次查询密码时,出现:(error) NOAUTH Authentication required.
  4. 此时报错了!现在只需要密码认证就可以了: auth 123456
  5. 再次查询密码 127.0.0.1:6379> config get requirepass
  6. 1) "requirepass"
  7. 2) "123456"
  8. 密码已经得到修改。

方法二:修改配置文件。(修改完了要重启redis才生效)

二、redis为什么有16个db

Redis是一个字典结构的存储服务器,一个Redis实例提供了多个用来存储数据的字典,客户端可以指定将数据存储在哪个字典中。这与在一个关系数据库实例中可以创建多个数据库类似(如下图所示),所以可以将其中的每个字典都理解成一个独立的数据库。
在这里插入图片描述
reids Desktop Manager连接本机redis后
在这里插入图片描述
客户端与Redis建立连接后会默认选择0号数据库,不过可以随时使用SELECT命令更换数据库。

2.1 切库命令

  1. # 切库
  2. redis> SELECT 1 # 默认0号db,切换为1号db
  3. 127.0.0.1:6379> select 1
  4. OK
  5. 127.0.0.1:6379[1]> get w2
  6. "w2val111111"
  7. 127.0.0.1:6379[1]> select 6
  8. OK
  9. 127.0.0.1:6379[6]> get w6
  10. "w6val"

idea整合redis配置:

  1. #redis相关配置
  2. # Redis数据库索引(默认为0)!!!!!!!这里选择库
  3. spring.redis.database=15
  4. # Redis服务器地址
  5. spring.redis.host=localhost
  6. # Redis服务器连接端口
  7. spring.redis.port=7019
  8. # Redis服务器连接密码(默认为空)
  9. spring.redis.password=
  10. # 连接池最大连接数(使用负值表示没有限制)
  11. spring.redis.lettuce.pool.max-active=8
  12. # 连接池最大阻塞等待时间(使用负值表示没有限制)
  13. spring.redis.lettuce.pool.max-wait=-1ms
  14. # 连接池中的最大空闲连接
  15. spring.redis.lettuce.pool.max-idle=8
  16. # 连接池中的最小空闲连接
  17. spring.redis.lettuce.pool.min-idle=0
  18. # redis的key过期时间(单位分钟)
  19. spring.cache.redis.time-to-live=1440

2.2 正确理解Redis的“数据库”概念

由于Redis不支持自定义数据库的名字,所以每个数据库都以编号命名。开发者则需要自己记录存储的数据与数据库的对应关系。另外Redis也不支持为每个数据库设置不同的访问密码,所以一个客户端要么可以访问全部数据库,要么全部数据库都没有权限访问

  1. # 清空一个Redis实例中所有数据库中的数据
  2. redis 127.0.0.1:6379> FLUSHALL

清空结果如下图所示
在这里插入图片描述
该命令可以清空实例下的所有数据库数据,这与我们所熟知的关系型数据库所不同。关系型数据库多个库常用于存储不同应用程序的数据 ,且没有方式可以同时清空实例下的所有库数据。所以对于Redis来说这些db更像是一种命名空间,且不适宜存储不同应用程序的数据。比如可以使用0号数据库存储某个应用生产环境中的数据,使用1号数据库存储测试环境中的数据,但不适宜使用0号数据库存储A应用的数据而使用1号数据库B应用的数据,不同的应用应该使用不同的Redis实例存储数据。Redis非常轻量级,一个空Redis实例占用的内在只有1M左右,所以不用担心多个Redis实例会额外占用很多内存。

2.3 集群在的redis数据库

以上所说的都是基于单体Redis的情况。而在集群的情况下不支持使用select命令来切换db,因为Redis集群模式下只有一个db0。

Redis实例默认建立了16个db,由于不支持自主进行数据库命名所以以dbX的方式命名。默认数据库数量可以修改配置文件的database值来设定。对于db正确的理解应为“命名空间”,多个应用程序不应使用同一个Redis不同库,而应一个应用程序对应一个Redis实例,不同的数据库可用于存储不同环境的数据。最后要注意,Redis集群下只有db0,不支持多db。

三、redis常见基础面试T

3.1 什么是redis

Redis(Remote Dictionary Server) 是一个使用 C 语言编写的,开源的(BSD许可)
高性能非关系型(NoSQL)的键值对数据库。

Redis 可以存储键和五种不同类型的值之间的映射。键的类型只能为字符串,值支持五种数据类型:字符串、列表、集合、散列表、有序集合。

与传统数据库不同的是 Redis 的数据是存在内存中的,所以读写速度非常快,因此 redis 被广泛应用于缓存方向,每秒可以处理超过 10万次读写操作,是已知性能最快的Key-Value DB。另外,Redis 也经常用来做分布式锁。除此之外,Redis 支持事务 、持久化、LUA脚本、LRU驱动事件、多种集群方案。

3.2 关系型数据库 vs 非关系型数据库

关系型数据库:指采用了关系模型来组织数据的数据库。
非关系型数据库:指非关系型的,分布式的,且一般不保证遵循ACID原则的数据存储系统。

非关系型数据库结构


























关系型数据库 非关系型数据库
含义 采用了关系模型来组织数据的数据库。 指非关系型的,分布式的,且一般不保证遵循ACID原则的数据存储系统。

非关系型数据库以键值对存储,且结构不固定,每一个元组可以有不一样的字段,每个元组可以根据需要增加一些自己的键值对,不局限于固定的结构,可以减少一些时间和空间的开销
优点 容易理解、易于维护 简单易部署,
查询速度快基于键值对,数据之间没有耦合性,所以非常容易水平扩展。
缺点 高并发读写需求(遵守ACID)
海量数据的高效率读写
只适合存储一些较为简单的数据,对于需要进行较复杂查询的数据,关系型数据库显的更为合适。不适合持久存储海量数据

3.3 Redis的数据类型

  1. string:最基本的数据类型,二进制安全的字符串,最大512M。
  2. list:按照添加顺序保持顺序的字符串列表。
  3. set:无序的字符串集合,不存在重复的元素。
  4. zset:已排序的字符串集合
  5. hash:key-value对的一种集合。

3.3.1 String字符串

格式: set key value

string类型是二进制安全的。意思是redis的string可以包含任何数据。比如jpg图片或者序列化的对象 。

string类型是Redis最基本的数据类型,一个键最大能存储512MB。String适合做简单的键值对缓存

3.3.2 Hash(哈希)

格式: hmset name key1 value1 key2 value2

Redis hash 是一个键值(key=>value)对集合。

Redis hash是一个string类型的field和value的映射表,hash适合用于存储对象

3.3.3 List(列表)

Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。
list适合于存储列表型数据结构,如文章的用户评论

格式: lpush name value

在 key 对应 list 的头部添加字符串元素

格式: rpush name value

在 key 对应 list 的尾部添加字符串元素

格式: lrem name index

key 对应 list 中删除 count 个和 value 相同的元素

格式: llen name

返回 key 对应 list 的长度

3.3.4 Set(集合)

格式: sadd name value

Set是string类型的无序集合。

集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。

3.3.5 zset(sorted set:有序集合)

格式: zadd name score value

zset 和 set 一样也是string类型元素的集合,且不允许重复的成员,但分数(score)却可以重复。

不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。

Sorted set是set的升级,它在set的基础上增加了一个顺序属性,这一属性值在添加元素的时候指定,每次指定后Zset会自动重新按照新值调整顺序。

在这里插入图片描述

3.4 Redis持久化

持久化就是把内存的数据写到磁盘中去,防止服务宕机了内存数据丢失。

Redis 提供了两种持久化方式:RDB(默认) 和AOF

3.4.1 RDB

RDB是Redis默认的持久化方式。按照一定的时间将内存的数据以快照的形式保存到硬盘中,对应产生的数据文件为dump.rdb。通过配置文件中的save参数来定义快照的周期。Redis启动时再恢复到内存中。

在这里插入图片描述

Redis会单独创建fork()一个子进程,将当前父进程的数据库数据复制到子进程的内存中,然后由子进程写入到临时文件中,持久化的过程结束了,再用这个临时文件替换上次的快照文件,然后子进程退出,内存释放。

优点

  1. 只有一个文件 dump.rdb,方便持久化。
  2. 容灾性好,一个文件可以保存到安全的磁盘。
  3. 性能最大化,fork 子进程来完成写操作,让主进程继续处理命令,所以是 IO 最大化。使用单独子进程来进行持久化,主进程不会进行任何 IO 操作,保证了 redis 的高性能
  4. 相对于数据集大时,比 AOF 的启动效率更高

缺点

  1. 数据安全性低。RDB 是间隔一段时间进行持久化,如果持久化之间 redis 发生故障,会发生数据丢失。所以这种方式更适合数据要求不严谨的时候) 。 需要注意的是,每次快照持久化都会将主进程的数据库数据复制一遍,导致内存开销加倍,若此时内存不足,则会阻塞服务器运行,直到复制结束释放内存;都会将内存数据完整写入磁盘一次,所以如果数据量大的话,而且写操作频繁,必然会引起大量的磁盘I/O操作,严重影响性能,并且最后一次持久化后的数据可能会丢失。

3.4.2 AOF

AOF是将Redis执行的每次写命令(读操作不记录)记录到单独的日志文件中,当重启Redis会重新将持久化的日志中文件恢复数据。
主要有两种方式触发:有写操作就写每秒定时写(也会丢数据)

在这里插入图片描述

优点

  1. 数据安全,aof 持久化可以配置 appendfsync 属性,有 always,每进行一次 命令操作就记录到 aof 文件中一次。
  2. 通过 append 模式写文件,即使中途服务器宕机,可以通过 redis-check-aof 工具解决数据一致性问题。
  3. AOF 机制的 rewrite 模式。AOF 文件没被 rewrite 之前(文件过大时会对命令 进行合并重写),可以删除其中的某些命令(比如误操作的 flushall))

缺点

  1. AOF 文件比 RDB 文件大,且恢复速度慢。
  2. 数据集大的时候,比 rdb 启动效率低。

3.4.3 使用对比

  1. 如果两个都配了优先加载AOF
  2. AOF文件比RDB更新频率高,优先使用AOF还原数据。
  3. AOF比RDB更安全也更大
  4. RDB性能比AOF好

当两种方式同时开启时,数据恢复Redis会优先选择AOF恢复。一般情况下,只要使用默认开启的RDB即可,因为相对于AOF,RDB便于进行数据库备份,并且恢复数据集的速度也要快很多。

  1. 开启持久化缓存机制,对性能会有一定的影响,特别是当设置的内存满了的时候,更是下降到几百reqs/s
  2. 所以如果只是用来做缓存的话,可以关掉持久化。

3.5 Redis 有哪些架构模式?讲讲各自的特点

3.5.1 单机版

在这里插入图片描述

特点:简单
缺点:1、内存容量有限 2、处理能力有限 3、无法高可用。

3.5.2 主从复制

在这里插入图片描述

Redis 的复制(replication)功能允许用户根据一个 Redis 服务器来创建任意多个该服务器的复制品,其中被复制的服务器为主服务器(master),而通过复制创建出来的服务器复制品则为从服务器(slave)。 只要主从服务器之间的网络连接正常,主从服务器两者会具有相同的数据,主服务器就会一直将发生在自己身上的数据更新同步 给从服务器,从而一直保证主从服务器的数据相同。

特点

1、master/slave 角色

2、master/slave 数据相同

3、降低 master 读压力在转交从库

问题

1、无法保证高可用

2、没有解决 master 写的压力

3.5.3 哨兵

在这里插入图片描述
Redis sentinel 是一个分布式系统中监控 redis 主从服务器,并在主服务器下线时自动进行故障转移。其中三个特性:

监控(Monitoring): Sentinel 会不断地检查你的主服务器和从服务器是否运作正常。

提醒(Notification): 当被监控的某个 Redis 服务器出现问题时, Sentinel 可以通过 API 向管理员或者其他应用程序发送通知。

自动故障迁移(Automatic failover): 当一个主服务器不能正常工作时, Sentinel 会开始一次自动故障迁移操作

特点

1、保证高可用

2、监控各个节点

3、自动故障迁移

缺点
1、主从模式,切换需要时间丢数据

2、没有解决 master 写的压力

3.5.4 集群(proxy 型)

在这里插入图片描述

Twemproxy 是一个 Twitter 开源的一个 redis 和 memcache 快速/轻量级代理服务器; Twemproxy 是一个快速的单线程代理程序,支持 Memcached ASCII 协议和 redis 协议。

特点
1、多种 hash 算法:MD5、CRC16、CRC32、CRC32a、hsieh、murmur、Jenkins

2、支持失败节点自动删除

3、后端 Sharding 分片逻辑对业务透明,业务方的读写方式和操作单个 Redis 一致

缺点:增加了新的 proxy,需要维护其高可用。

3.5.5 集群(直连型)

在这里插入图片描述

从redis 3.0之后版本支持redis-cluster集群,Redis-Cluster采用无中心结构,每个节点保存数据和整个集群状态,每个节点都和其他所有节点连接。

特点:

1、无中心架构(不存在哪个节点影响性能瓶颈),少了 proxy 层。

2、数据按照 slot 存储分布在多个节点,节点间数据共享,可动态调整数据分布。

3、可扩展性,可线性扩展到 1000 个节点,节点可动态添加或删除。

4、高可用性,部分节点不可用时,集群仍可用。通过增加 Slave 做备份数据副本

5、实现故障自动 failover,节点之间通过 gossip 协议交换状态信息,用投票机制完成 Slave到 Master 的角色提升。

缺点:

1、资源隔离性较差,容易出现相互影响的情况。

2、数据通过异步复制,不保证数据的强一致性

3.6 缓存处理流程及异常

缓存处理流程:前台请求,后台先从缓存中取数据,取到直接返回结果,取不到时从数据库中取,数据库取到更新缓存,并返回结果,数据库也没取到,那直接返回空结果。

在这里插入图片描述

3.6.1 缓存穿透

描述
缓存穿透是指缓存和数据库中都没有的数据,而用户发起大量请求。如发起为id为“-1”的数据或id为特别大不存在的数据。这时的用户很可能是攻击者,攻击会导致数据库压力过大。

解决方案:

  1. 接口层增加校验,如用户鉴权校验,id做基础校验,id<=0的直接拦截;
  2. 从缓存取不到的数据,在数据库中也没有取到,这时也可以将key-value对写为key-null,缓存有效时间可以设置短点,如30秒(设置太长会导致正常情况也没法使用)。这样可以防止攻击用户反复用同一个id暴力攻击

3.6.2 缓存击穿

描述:
缓存击穿是指缓存中没有但数据库中有的数据一般是缓存时间到期),这时由于并发用户特别多,同时读缓存没读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,造成过大压力

解决方案:

  1. 设置热点数据永远不过期;
  2. 加互斥锁

3.6.3 缓存雪崩

描述
缓存雪崩是指缓存中数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至down机
和缓存击穿不同的是,缓存击穿指并发查同一条数据,缓存雪崩是不同数据都过期了,很多数据都查不到从而查数据库。

解决方案:

  1. 缓存数据的过期时间设置随机,防止同一时间大量数据过期现象发生。
  2. 如果缓存数据库是分布式部署,将热点数据均匀分布在不同搞得缓存数据库中。
  3. 设置热点数据永远不过期。

以上描述参考链接在此~~~~

3.7 如何保证缓存与数据库双写时的数据一致性?

先更新db再失效缓存的策略

觉大多数高并发的情况下,对数据的实时更新要求并不是那么严谨。作为一个缓存数据,它的更新时间是17:01.001还是17:01.789,这个其实不是很重要。

缓存本质上是存储分布

要求严格高一致就没缓存啥事~~~~~

3.8 reids vs Memcached

两者都是非关系型内存键值数据库,现在公司一般都是用 Redis 来实现缓存,而且 Redis 自身也越来越强大了!Redis 与 Memcached 主要有以下不同:
(1) memcached所有的值均是简单的字符串,redis作为其替代者,支持更为丰富的数据类型

(2) redis的速度比memcached快很多

(3) redis可以持久化其数据

在这里插入图片描述

3.9 Redis主要有哪些功能?

1.哨兵(Sentinel)和复制(Replication)
Redis服务器毫无征兆的罢工是个麻烦事,如何保证备份的机器是原始服务器的完整备份呢?这时候就需要哨兵和复制。

哨兵Sentinel可以管理多个Redis服务器,它提供了监控,提醒以及自动的故障转移的功能,Replication则是负责让一个Redis服务器可以配备多个备份的服务器。

Redis也是利用这两个功能来保证Redis的高可用的。

2.事务
很多情况下我们需要一次执行不止一个命令,而且需要其同时成功或者失败。redis对事务的支持也是源自于这部分需求,即支持一次性按顺序执行多个命令的能力,并保证其原子性

3.LUA脚本
在事务的基础上,如果我们需要在服务端一次性的执行更复杂的操作(包含一些逻辑判断),则lua就可以排上用场了。

4.持久化
redis的持久化指的是redis会把内存的中的数据写入到硬盘中,在redis重新启动的时候加载这些数据,从而最大限度的降低缓存丢失带来的影响。

5.集群(Cluster)
单台服务器资源的总是有上限的,CPU资源和IO资源我们可以通过主从复制,进行读写分离,把一部分CPU和IO的压力转移到从服务器上,这也有点类似mysql数据库的主从同步。

3.10 RedisTemplate

RedisTemplate详解

3.xx redis常用命令

Redis常用命令?

Keys pattern

*表示区配所有

以bit开头的

查看Exists key是否存在

Set

设置 key 对应的值为 string 类型的 value。

setnx

设置 key 对应的值为 string 类型的 value。如果 key 已经存在,返回 0,nx 是 not exist 的意思。

删除某个key

第一次返回1 删除了 第二次返回0

Expire 设置过期时间(单位秒)

TTL查看剩下多少时间

返回负数则key失效,key不存在了

Setex

设置 key 对应的值为 string 类型的 value,并指定此键值对应的有效期。

Mset

一次设置多个 key 的值,成功返回 ok 表示所有的值都设置了,失败返回 0 表示没有任何值被设置。

Getset

设置 key 的值,并返回 key 的旧值。

Mget

一次获取多个 key 的值,如果对应 key 不存在,则对应返回 nil。

Incr

对 key 的值做加加操作,并返回新的值。注意 incr 一个不是 int 的 value 会返回错误,incr 一个不存在的 key,则设置 key 为 1

incrby

同 incr 类似,加指定值 ,key 不存在时候会设置 key,并认为原来的 value 是 0

Decr

对 key 的值做的是减减操作,decr 一个不存在 key,则设置 key 为-1

Decrby

同 decr,减指定值。

Append

给指定 key 的字符串值追加 value,返回新字符串值的长度。

Strlen

取指定 key 的 value 值的长度。

persist xxx(取消过期时间)

选择数据库(0-15库)

Select 0 //选择数据库

move age 1//把age 移动到1库

Randomkey随机返回一个key

Rename重命名

Type 返回数据类型

发表评论

表情:
评论列表 (有 0 条评论,308人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Redis集群讲解

    在服务开发中,单机都会存在单点故障的问题,及服务部署在一台服务器上,一旦服务器宕机服务就不可用,所以为了让服务高可用,分布式服务就出现了,将同一服务部署到多台机器上,即使其中几

    相关 Redis基础讲解

    前言:本文章为慕课网上Java企业级电商项目架构演进之路Tomcat集群与Redis分布式的学习笔记.供本人复习之用. 目录 第一章 redis的安装与启动 1.1 li

    相关 Redis Pipeline讲解

    一、pipeline出现的背景 Redis是一种基于客户端-服务端(CS)模型以及请求/响应协议的TCP服务,这意味着通常情况下一个请求会遵循以下步骤: 客户端向

    相关 Redis事务讲解

    一、引言 为了确保连续多个操作的原子性,一个成熟的数据库通常都会有事务支持,Redis 也不例外。Redis 的事务使用非常简单,不同于关系数据库,我们无须理解那么多复杂