Redis

Redis

Redis是什么?

​ Redis是开源的,C语言编写的,支持网络交互的,非关系型数据库(也可以用作缓存和消息中间件)。

缓存:将数据存储到内存中(程序使用时,可以缓存数据,具有临时性,速度快)

​ SqlSession 一级缓存

​ SqlSessionFactory 二级缓存 可设置有效时间

优点:减轻数据库压力

Redis支持多种类型的数据结构,如字符串(Strings),散列(hashes),列表(lists),集合(sets),有序集合(sorted sets)与范围查询,bitmaps,hyperloglogs和地理空间(geospatial)索引半径查询。

关系型数据库与非关系型数据库

关系型数据库

Mysql,sqlServer,Oracle这些都是关系型数据库

关系型数据库先建表,再添加列,然后表示表与表之间的关系。

表中的一行就是一条记录,一列就是一个字段。

优点:

  • 容易理解
  • 使用方便,通用的sql语言
  • 易于维护,丰富的完整性(实体完整性,参照完整性,用户定义完整性)大大降低了数据的冗余和数据不一致的缺点

缺点:

  • 磁盘I/O是并发的瓶颈(从硬盘读数据)
  • 海量数据查询效率低
  • 横向扩展困难,无法简单的通过添加硬件和服务节点来扩展性能和负载能力,当需要对数据库进行升级和扩展时,需要停机维护和数据迁移
  • 多表的关联查询以及复杂的数据分析类型的复杂sql查询时性能欠佳,因为要保证ACID

非关系型数据库

非关系型数据库,分布式,一般不保证遵循ACID原则的数据存储系统。键值对存储,结构不固定。

优点:

  • 根据需要添加字段,不需要多表联查。仅需id取出对应的value
  • 严格上讲不是一种数据库,而是一种数据结构化的存储方法的集合

缺点:

  • 只适合存储一些简单的数据
  • 不适合复杂查询的数据
  • 不适合持久存储的海量数据

安装Redis

安装准备

1.检查gcc版本:gcc -v

​ Redis6以上版本要求gcc必须在5.3以上,CentOS7默认安装gcc版本4.8.5,升级gcc,CentOS忽略此操作

​ 升级gcc步骤,升级到gcc9.3:

yum -y install centos-release-scl

yum -y install devtoolset-9-gcc devtoolset-9-gcc-c++devtoolset-9-binutils

scl enable devtoolset-9 bash

需要注意的是scl命令启用只是临时的,退出shell或重启就会恢复原系统gcc版本。如果要长期使用gcc9.3的话执行下面命令

echo -e"\nsource/opt/rh/devtoolset-9/enable">>/etc/profile

开始安装

方式一:

下载:https://redis.io/download
在这里插入图片描述

在线下载 或者 在官网下载

https://download.redis.io/releases/redis-6.2.4.tar.gz

方式二:

上传压缩包

解压:tar -zxvf redis-6.24.tar.gz

cd redis-6.2.4

预编译:make

创建文件:mikdir -p /usr/local/redis/ install

安装到指定目录:make prefix=/usr/local/redis install

进入安装文件bin目录:cd /usr/local/redis/bin

启动服务:./redis-server
在这里插入图片描述

基本设置

从 redis 的源码目录中复制 redis.conf 到 redis 的安装目录

cp redis.conf /usr/local/redis/bin/

修改 redis.conf 文件 vim redis.confvi redis.conf

​ 1.后台运行:daemonize no 改为 daemonize yes

​ 2.设置密码:requirepass 你的密码

​ 文件内查找: /搜索内容 回车 n下一个 N上一个

​ 3.注释 绑定的id,运来默认只能本机访问,注释后就可以远程访问了
在这里插入图片描述

启动命令:

./redis-server redis.conf

查看Redis运行状态:

ps -ef|gref redis

进入客户端模式:

./redis-cli

输入密码:

anth 密码

测试 ping

​ 成功回复 pong

Ctrl+c 退出客户端模式

Redis数据类型

redis支持五种数据类型:

string(字符串)

hash(哈希)

list(列表)

set(集合)

zset (sortedset:有序集合)

string(字符串)

string是redis最基本的类型,一个key对应一个value。

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

string类型是Redis最基本的数据类型,string类型的值最大能存储512MB。

存 > set name"jim"

取 > get name

删 > del name

实例:

redis127.0.0.1:6379> SET name"jim"
OK
redis127.0.0.1:6379> GET name"jim"

在以上实例中我们使用了Redis的SET和GET命令。键为name,对应的值为jim

hash(哈希)

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

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

存的是字符串和字符串值之间的映射,比如一个用户要存储其全名、姓氏、年龄等等,就很适合使用哈希。

存 > hmset user name‘jim’ age20

取 > hget user name

删 > hdel user name

实例:

redis127.0.0.1:6379> HMSET user name"jim" age 20
OK
redis127.0.0.1:6379> HGET user name 
"jim"
redis127.0.0.1:6379> HGET user age 
"20"

HMSET设置了两个field=>value对,HGET获取对应field对应的value。每个hash可以存储(2^32)-1键值对(40多亿)。

List(列表)

Redis列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。

存> lpush name redis 插入到列表的左边

​ rpush name redis 插入到列表的右边

取> lindex name redis

改> lset name redis newredis

查> lrange name 0 100 (从第1位开始,查询100个)

长度> llen name

移除> lpop name rpop name 从左/右删除第一个元素

删除> lrem name 1 66 删除值为66的元素,只删除1个

删除list> del name

实例:

redis127.0.0.1:6379> DEL name 
redis127.0.0.1:6379>lpush name redis
(integer) 1
redis127.0.0.1:6379>lpush name mongodb
(integer) 2
redis127.0.0.1:6379>lpush name rabbitmq
(integer)3
redis127.0.0.1:6379>lrange name 0 10
1) "rabbitmq"
2) "mongodb"
3) "redis"

列表最多可存储(2^32)-1元素(4294967295,每个列表可存储40多亿)。

Set(集合)

Redis的Set是string类型的无序集合,集合成员是唯一的,这就意味着集合中不能出现重复的数据。

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

添加一个String元素到key对应的set集合中,成功返回1,如果元素已经在集合中返回0。

存> sadd name redis mongodb rabbitmq (不能存重复值)

判断是否存在> sismember name redis

移除> srem name redis

查询> smembers name

实例:

redis127.0.0.1:6379> DEL name
redis127.0.0.1:6379> sadd name redis
(integer)1
redis127.0.0.1:6379> sadd name mongodb
(integer)1
redis127.0.0.1:6379> sadd name rabbitmq
(integer)1
redis127.0.0.1:6379> sadd name rabbitmq
(integer)0
redis127.0.0.1:6379> smembers name
1)"redis"
2)"rabbitmq"
3)"mongodb"

zset(sorted set:有序集合)

zset和set一样也是string类型元素的集合,且不允许重复的成员。

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

zset的成员是唯一的,但分数(score)却可以重复。

zadd命令

添加元素到集合,元素在集合中存在则更新对应score

zadd key score member

redis127.0.0.1:6379>zadd name 1 redis
(integer)1
redis127.0.0.1:6379>zadd name 2 mongodb
(integer)1
redis127.0.0.1:6379>zadd name 3 rabbitmq
(integer)1
redis127.0.0.1:6379>zadd name 3 rabbitmq
(integer)0
redis127.0.0.1:6379>ZRANGEBYSCORE name 0 1000
1)"redis"
2)"mongodb"
3)"rabbitmq"

设置失效时间

有时候我们并不希望redis的key一直存在。例如缓存,验证码等数据,我们希望它们能在一定时间内自动的被销毁。redis提供了一些命令,能够让我们对key设置过期时间,并且让key过期之后被自动删除.

方式一:设置值时直接设置有效时间
在这里插入图片描述

EX表示以秒为单位

PX表示以毫秒为单位

EX,PX不区分大小写

set name jim EX30 设置失效时间为30秒

ttl 键 查看剩余时间(秒)

pttl 键 查看剩余时间(毫秒)

方式二:设置值后设置有效时间

expire 键 时间(秒)

pexpire 键 时间(毫秒)

SpringBoot集成使用Redis

概述

Jedis是Redis官方推出的一款面向Java的客户端,提供了很多接口供Java语言调用。可以在Redis官网下载.

Spring-data-redis是spring大家族的一部分,提供了在srping应用中通过简单的配置访问redis服务,对reids底层开发包(Jedis,JRedis,andRJC)进行了高度封装,RedisTemplate提供了redis各种操作.

spring-data-redis针对jedis提供了如下功能:

  1. 连接池自动管理,提供了一个高度封装的“RedisTemplate”类

  2. 针对jedis客户端中大量api进行了归类封装,将同一类型操作封装为operation接口

    ​ ValueOperations:简单K-V操作

    ​ HashOperations:针对map类型的数据操作

    ​ ListOperations:针对list类型的数据操作

    ​ SetOperations:set类型数据操作

    ​ ZSetOperations:zset类型数据操作

  3. 将事务操作封装,有容器控制。

  4. 针对数据的“序列化/反序列化”,提供了多种可选择策略(RedisSerializer)

搭建

1.添加redis依赖
在这里插入图片描述
2.配置连接redis
在这里插入图片描述
3.注入RedisTemplate
在这里插入图片描述

4.测试
在这里插入图片描述
需要被Redis缓存的类,必须实现序列化接口

主从复制

​ 主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器。前者称为主节点(master),后者称为从节点(slave),数据的复制是单向的只能由主节点到从节点。

​ 使用一个Redis实例作为主机,其余的作为备份机。主机和备份机的数据完全一致,主机支持数据的写入和读取等各项操作,而从机则只支持与主机数据的同步和读取。也就是说,客户端可以将数据写入到主机,由主机自动将数据的写入操作同步到从机。主从模式很好的解决了数据备份问题,并且由于主从服务数据几乎是一致的,因而可以将写入数据的命令发送给主机执行,而读取数据的命令发送给不同的从机执行,从而达到读写分离的目的。

主从复制的作用主要包括:

1.数据冗余:主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式。

2.故障恢复:当主节点出现问题时,可以由从节点提供服务,实现快速的故障恢复;实际上是一种服务的冗余。

3.负载均衡:在主从复制的基础上,配合读写分离,可以由主节点提供写服务,由从节点提供读服务(即写Redis数据时应用连接主节点,读Redis数据时应用连接从节点),分担服务器负载;尤其是在写少读多的场景下,通过多个从节点分担读负载,可以大大提高Redis服务器的并发量。

4.高可用(集群)基石:除了上述作用以外,主从复制还是哨兵和集群能够实施的基础,因此说主从复制是Redis高可用的基础。

哨兵机制

​ 哨兵模式是一种特殊的模式,首先Redis提供了哨兵的命令,哨兵是一个独立的进程,作为进程,它会独立运行。其原理是哨兵通过发送命令,等待Redis服务器响应,从而监控运行的多个Redis实例。

监听所有服务,一旦主机宕机会重新选举一台作为主机

缓存穿透

查询的数据在数据库中不存在,缓存中没有,仍然去数据库查询,如果有人恶意攻击,查询没有的数据,缓存就相当于失效了。

解决办法:

1.使用布隆过滤器(BloomFilter)或者压缩filter提前拦截.

2.将这个空对象设置到缓存里边去。下次再请求的时候,就可以从缓存里边获取了。这种情况我们一般会将空对象设置一个较短的过期时间.

3.拉黑该IP地址.

4.对参数进行校验,不合法参数进行拦截.

缓存击穿

数据在数据库中存在,但在redis中的某个时间节点过期了,此时刚好有大量请求到达程序,都会去数据库查询,这是大并发的请求可能瞬间就将数据库压垮。

解决办法:

1.热点数据设置永不过期

2.加上互斥锁:上面的现象是多个线程同时去查询数据库的这条数据,那么我们可以在第一个查询数据的请求上使用一个互斥锁来锁住它,其他的线程走到这一步拿不到锁就等着,等第一个线程查询到了数据,然后将数据放到redis缓存起来。后面的线程进来发现已经有缓存了,就直接走缓存.

缓存雪崩

在高并发的情况下,大量缓存失效或redis服务出现故障同时有很多请求到达数据库,使数据库挂掉。

解决办法:

1.随机设置key失效时间,避免大量key集体失效。

​ setRedis(Key,value,time+Math.random()*10000);

2.若是集群部署,可将热点数据均匀分布在不同的Redis库中也能够避免key全部失效问题

3.不设置过期时间

4.跑定时任务,在缓存失效前刷进新的缓存

总结

穿透是redis里不存在这个缓存key;

击穿是redis某一个热点key突然失效;

雪崩是大面积的key缓存失效

三者最终的受害者都是数据库

事发前: 实现Redis的高可用(主从架构+Sentinel(哨兵),尽量避免Redis挂掉这种情况发生。

事发中: 万一Redis真的挂了,我们可以设置本地缓存(ehcache)+限流,尽量避免我们的数据库被干掉(起码能保证我们的服务还是能正常工作的)

事发后: redis持久化,重启后自动从磁盘上加载数据,快速恢复缓存数据

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值