什么是redis?
答:redis是非关系型数据库,使用redis的目的是:减轻数据库访问压力。
数据库是做IO操作,使用redis是内存操作,内存数据库,
效率要比IO效率高。这个就是缓存。
如果数据库值与redis值不同步该怎么解决?
答:清缓存,再同步数据库中的值,然后缓存到redis中。
redis应用场景:减轻数据库访问压力、验证码问题、
分布式锁、解决分布式数据同步。
使用redis实现分布式锁--- 唯一难道释放锁资源。
1、主从复制
作用:(读写分离、备份、集群、宕机容错机制、高可用)
2、哨兵机制
作用: 高可用、监听机制
3、Redis持久化机制
作用:数据恢复、高可用
rdb存储、aof存储优缺点
4、redis是否存在事务。有事务
5、redis发布订阅 -- 消息中间件
6、缓存雪崩、击穿 -- 架构知识点
封装代码:
RedisService.java
package com.leeue.service;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ZSetOperations.TypedTuple;
import org.springframework.data.redis.support.collections.RedisZSet;
import org.springframework.stereotype.Service;
@Service
public class RedisService {
// redis基本数据类型:string list set zset hash
@Autowired
private StringRedisTemplate stringRedisTemplate;
// string
private String strValue = null;
private List listValue = null;
private Set setValue = null;
private Map mapValue = null;
private Set> zsetValue = null;
public void setString(String key, String value) {
this.setObject(key, value, null);
}
public void setString(String key, String value,Long time) {
this.setObject(key, value, time);
}
public void setList(String key, List listValue) {
this.setObject(key, listValue,null);
}
public void setList(String key, List listValue, Long time) {
this.setObject(key, listValue,time);
}
public void setHash(String key, Map mapValue) {
this.setObject(key, mapValue,null);
}
public void setSet(String key, String value) {
this.setObject(key, value,null);
}
public void setZset(String key, String value) {
this.setObject(key, value,null);
}
public void setObject(String key, Object value, Long time) {
if (StringUtils.isEmpty(key) || null == value) {
return;
}
// 判断类型 存放string类型的
if (value instanceof String) {
strValue = (String) value;
stringRedisTemplate.opsForValue().set(key, strValue);
if (time != null) {
stringRedisTemplate.opsForValue().set(key, strValue, time, TimeUnit.SECONDS);
}
return;
}
// 存放list类型
if (value instanceof List) {
listValue = (List) value;
for (String strList : listValue) {
stringRedisTemplate.opsForList().leftPush(key, strList);
if (time != null) {
stringRedisTemplate.opsForValue().set(key, strList, time, TimeUnit.SECONDS);
}
}
return;
}
// 存放set
if (value instanceof Set) {
setValue = (Set) value;
for (String strSet : setValue) {
stringRedisTemplate.opsForSet().add(key, strValue);
}
return;
}
// 存放hash
if (value instanceof Map) {
mapValue = (Map) value;
stringRedisTemplate.opsForHash().putAll(key, mapValue);
return;
}
// 存放Zset 这个不清楚
if (value instanceof RedisZSet) {
zsetValue = (Set>) value;
for (TypedTuple strZset : zsetValue) {
stringRedisTemplate.opsForZSet().add(key, zsetValue);
}
}
}
//默认去调用string类型
public String getStringKey(String key) {
return stringRedisTemplate.opsForValue().get(key);
}
}
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<groupId>com.leeuegroupId>
<artifactId>30_SpringBoot_RedisartifactId>
<version>0.0.1-SNAPSHOTversion>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>1.5.8.RELEASEversion>
parent>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-redisartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>commons-langgroupId>
<artifactId>commons-langartifactId>
<version>2.6version>
dependency>
dependencies>
project>
application.properties
########################################################
###Redis (RedisConfiguration)
########################################################
# 使用的是第0个库
spring.redis.database=0
spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.password=123456
spring.redis.pool.max-idle=8
spring.redis.pool.min-idle=0
spring.redis.pool.max-active=8
spring.redis.pool.max-wait=-1
spring.redis.timeout=5000
Redis怎么存放对象?用什么数据类型好?
答:使用String类型,采用json格式,
将对象转换程json格式存放到redis中。
从redis获取到json的值,反序列化对象。
redis高可用机制:
答:redis主从复制:作用:数据备份、读写分离、集群、宕机容错机制
redis怎么实现主从复制?
只需要修改配置文件。
redis持久化机制:
redis哨兵机制:
redis主从复制只需要修改配置文件
redis只支持一主多从。
图解:
130为主服务器
131、132为从服务器
主服务器拥有读、写
从服务器只有读的操作
如果主挂了,redis有个哨兵机制,监听每台服务器上的redis,
如果发现主服务器挂了,会在从服务器中选出一个服务器为主服务器。
如果有服务器挂了,使用keepalived监听,自动重启。
哨兵机制就是选举出主服务器。
如果一直重启失败,就会邮件通知运维人员。
redis高可用:哨兵机制+keepalived监听
mysql主从复制实现原理:通过二进制文件来实现。
redis主从复制实现原理:是使用快照文件的,也是实时同步的
搭建服务器集群:第一点使用root账号登陆,第二点关闭所有防火墙。
步骤:
1、在linux找到redis目录下的etc目录下,修改redis.conf文件如图:
2、修改如下:
3、启动主从redis:
命令:
启动redis
./redis-server /usr/local/redis/etc/redis.conf
连接redis
./redis-cli -h 127.0.0.1 -p 6379 -a '123456'
最后主服务器redis中使用info命令来查看。可以知道配置成功没有
从节点不能做写操作:如图:
redis哨兵机制:就是如果主挂了,就会在从服务器中选取一个举做为主服务器。
找到redis安装目录:copy文件到 local下面的redis的etc下
命令:cp sentinel.conf /usr/local/redis/etc
这个设置每隔多少毫秒监听主服务器
设置主服务器下面有几台从服务器
当主服务器的redis挂了shutdown 哨兵机制打印出来的日志
这里选择了131为主服务器了
哨兵机制是redis单独程序。
什么是Redis持久化?就是将内存数据保存到硬盘上。
redis持久化是通过AOF与RDB两种模式来实现的。
可以混用。
灾难备份:
Redis特征:值存放在在内存中。
redis宕机后:值是否会消失,答不会消失。
不会的,redis支持持久化机制:
1、rdb存储:是以二进制文件存储,不是实时才能吃。存储超过10key以上,开始持久化机制。优点体积小。、
2、aof存储:是实时存储。日志文件方式存储。文件大。
rdb存储:在redis.conf里面可以看出
这个表示更改了一个key时间隔了900秒,就会进行持久化存储生成一个
dump.rdb文件。更改了10个key300秒进行存储。以此类推。
同时redis如果shotdown 内存中还是有这个文件。
断开连接的时候,会再进行备份一次dump.rdb文件的。
rdb存储在灾难备份的时候不会这样使用的,
因为rdb存储需要达到一定的次数才会备份。
aof存储:是以操作日志实时进行存储的,缺点就是体积大。
在redis.conf文件找到appendonly yes
在持久化中rdb存储和aof存储是一起使用的。
总结:redis宕机之后,redis值会失效吗?
答:不会,redis默认开启rdb存储的,
注明:redis存储方式在规定的时间内,
key、value达到一定存储次数才开始做数据持久化。
如果是断电、直接杀死redis进程,
导致redis宕机,操作没有达到次数,redis值就会失效。
rdb存储方式在redis断开连接的时候就会进行备份。
最好采用aof方式来进行持久化。因为aof是实时进行保存的。
redis事务:开启事务命令 : multi 提交事务命令:exec
redis类似消息中间件的功能就是发布订阅。 点对点进行通讯。
redis发布定义含义:创建一个频道
如图所示就是redis中的发布订阅
创建频道命令:SUBSCRIBE leeue 这边发布
订阅该频道: publish leeue 这边接受实时显示。