Redis 是一个基于内存的非关系型 NoSQL 数据库,用来解决高并发的问题
redis-server --service-install redis.windows.conf --loglevel verbose
brew install redis
方案1
方案2
# 1.配置文件中对应的配置
requirepass 123456 #其中123456为设置的密码
# 2.修改完成侯重启Reids服务
systemctl restart redis
# 3.客户端连接测试
redis-cli -h 127.0.0.1 -p 6379 -a 123456
127.0.0.1:6379>PING
# 1.注释掉配置文件中的本地IP地址绑定
bind 127.0.0.1
# 2.关闭保护模式(把yes改为no)
protected-mode no
# 3.重启Redis服务
systemctl restart redis
适用于所有数据类型
命令 | 描述 |
---|---|
SELECT index | 选择所在库(index在0~15之间) |
KEYS * | 查看所有的KEY |
TYPE key | 查看KEY数据类型 |
DEL key | 删除KEY |
FULSHDB | 清空当前库 |
FLUSHALL | 清除所有库数据 |
字符串类型是redis中最简单的数据类型,它存储的值可以是字符串,其最大字符串长度支持到512M。基于此类型,可以实现博客的字数统计,实现一个博客的的点赞操作、实现短信验证码的存储、实现网站首页缓存等
(在Redis中,字符串、数值都会以字符串的格式来存储)
命令 | 描述 |
---|---|
SET key value | 按指定的键设置值 |
GET key | 获取键的值 |
SET key value nx | nx表示当key不存在时进行设置 |
SET key value ex seconds | 指定过期时间 |
MSET key value key value … | 同时设置多个键值 |
MGET key key key … | 同时获取多个值 |
STRLEN key | 获取字符串长度 |
命令 | 描述 |
---|---|
INCRBY key increment | 将键的整数值按给定的量递增 |
DECRBY key increment | 将键的整数值按给定的量递减 |
INCR key | 将键的整数值递增1 |
DECR key | 将键的整数值递减1 |
INCRBYFLOAT key increment | 将键的浮点值按给定的量递增 |
@PostMapping("sendMessage)
public JsonResult sendMessage(String phone){
1.接收手机号;
2.校验手机号的合法性;
3.生成6位的随机验证码;
4.调用第三方短信平台接口发送短信;
5.将手机号和验证码保存到Redis数据库;
5.1 数据类型选择: 字符串
5.2 key-value设计: {"sms_13603263409": 123456}
5.3 Redis命令: SET sms_13603263409 123456 ex 600
6.返回响应;
}
@PostMapping("login")
public JsonResult login(String phone, String code){
1.接收手机号和验证码;
2.从Redis中获取当时生成的验证码serverCode: GET sms_13603263409
3.情况1: serverCode为null,返回:验证码已过期,请重新获取;
情况2: serverCode!=code,返回:验证码有误,请重新输入;
情况3: serverCode==code,返回:登录成功,删除key-value,释放资源: DEL sms_13603263409;
}
public JsonResult weiboIndex(){
//1.从Redis中获取首页数据
redis_data: GET weibo_index
//2.如果Redis中无数据,则到MySQL中查询;
List weiboIndexVOS = weiboMapper.selectIndex()
//3.缓存到Redis中
SET weibo_index '[{第一条微博信息},{},{},...]' ex 30
//4.返回响应
return JsonResult.ok(weiboIndexVOS);
//2.如果Redis中存在数据,则直接返回响应
return JsonResult.ok(redis_data);
}
Redis 的 list 类型相当于 java 中的 LinkedList ,其原理就就是一个双向链表。支持正向、反向查找和遍历等操作,插入删除速度比较快,元素允许重复,经常用于实现队列,栈等结构
命令 | 描述 | 说明 |
---|---|---|
LPUSH key value1 [value2] | 在列表头部压入一个或多个元素 | |
RPUSH key value1 [value2] | 在列表尾部压入一个或多个元素 | |
LPOP key | 删除并获取列表中的第一个元素 | |
RPOP key | 删除并获取列表中最后一个元素 | |
BLPOP key timeout | 删除并获取列表中的第一个元素,或者阻塞直到一个可用 | timeout如果为3,表示最多阻塞3秒;timeout如果为0,表示永久阻塞,直到有元素可以弹出 |
BRPOP key timeout | 删除并获取列表中最后一个元素,或者阻塞直到一个可用 | timeout如果为3,表示最多阻塞3秒;timeout如果为0,表示永久阻塞,直到有元素可以弹出 |
LLEN key | 获取列表的长度 | |
LRANGE key start stop | 从列表中获取一系列元素 | |
LINSERT key BEFORE | AFTER pivot value | 在列表中的另一个元素之前或之后插入一个元素 | |
LSET key index value | 通过索引设置列表中元素的值 | |
LREM key count value | 从列表中删除元素 | count>0表示从头部开始向表尾搜索,移除与value相等的元素,数量为count;count<0表示从尾部开始向表头搜索,移除与value相等的元素,数量为count;count=0表示移除表中所有与value相等的值 |
LTRIM key start stop | 将列表修剪到指定范围 |
工程中做任务队列,生产者将任务推送到Redis的列表中,由Redis的列表维护整个任务队列,将任务发送给消费者去执行,比如:并发发短信任务、并发发邮件任务
Redis的列表可以做任务队列,但是企业工程中还有其他的专门做任务队列的框架,比如RabbitMQ等
@PostMapping("reg")
public JsonResult reg(@RequestBody UserRegParam userRegParam){
1.接收数据;
2.校验合法性;
3.校验用户名是否被占用;
4.在数据表中插入数据;
5.给该用户的邮箱发送一封激活邮件;[需要2秒钟]
6.返回响应;
}
Redis 散列类型相当于 Java 中的 HashMap,实现原理跟 HashMap 一致,一般用于存储对象信息,存储了字段(field)和字段值的映射,一个散列类型可以包含最多2^32-1个字段
命令 | 描述 |
---|---|
HSET key field value | 设置哈希字段的字符串值 |
HSETNX key field value | 尽在哈希字段不存在时设置该字段的值 |
HMSET key field1 value1 [field2 value2] | 将多个哈希字段设置为多个值 |
HLEN key | 获取哈希中的字段数 |
HGET key field | 获取存储在指定键处的hash字段的值 |
HGETALL key | 获取按指定键存储在hash中的所有字段和值 |
HKEYS key | 获取hash中的所有字段 |
HVALS key | 获取hash中的所有值 |
HMGET key field1 [field2] | 获取所有给定哈希字段的值 |
HDEL key field1 [field2] | 删除一个或者多个hash字段 |
HINCRBY key field increment | 将hash字段的整数值按给定的量递增 |
HINCRBYFLOAT key field increment | 将hash字段的浮点值按给定的量递增 |
存储对象类型的数据,存储购物车数据、用户信息各个维度数据统计等
命令 | 描述 |
---|---|
SADD key member1 [member2] | 将一个或多个成员添加到集合中 |
SMEMBERS key | 获取集合中的所有成员 |
SCARD key | 获取集合中的成员数 |
SISMEMBER key member | 确定给定值是否为集合的成员 |
SRANDMEMBER key count | 从集合中获取一个或多个随机成员 |
SINTER key1 key2 | 获取多个集合的交集 |
SINTERSTORE destination key1 key2 | 获取多个集合的交集并将结果存储到目标集合中 |
SDIFF key1 key2 | 获取多个集合的差集 |
SDIFFSTORE destination key1 key2 | 获取多个集合的差集并将结果存储到目标集合中 |
SUNION key1 key2 | 获取多个集合的并集【自动去重】 |
SUNIONSTORE destination key1 key2 | 获取多个集合的并集并将结果存储到目标集合中 |
分值 | 2 | 4 | 6 | 8 | 10 |
---|---|---|---|---|---|
成员 | 西瓜 | 葡萄 | 芒果 | 香蕉 | 苹果 |
分值 | 6000 | 8000 | 10000 | 12000 |
---|---|---|---|---|
成员 | lucy | tom | jim | jack |
命令 | 描述 |
---|---|
ZADD key score1 member1 [score2 member2] | 将一个或多个成员添加到有序集合中 |
ZCARD key | 获取有序集合中的成员数 |
ZRANGE key start stop [WITHSCORES] | 按索引返回有序集合中的成员范围 |
ZREM key member [member …] | 从有序集合中删除一个或多个成员 |
ZRANK key member | 确定有序集合中成员索引[升序] |
ZREVRANK key member | 确定有序集合中成员索引[降序] |
ZINCRBY key increment member | 增加有序集合中成员的分数 |
ZUNIONSTORE destination numkeys key [key …] [weights 权重值] [AGGREGATE SUM|MIN|MAX] | 获取多个有序集合的并集 |
ZINTERSTORE destination numkeys key [key …] [weights 权重值] [AGGREGATE SUM|MIN|MAX] | 获取多个有序集合的交集 |
各种排行榜[文章点击率排行榜,积分系统排行榜,音乐播放次数排行榜]
这两条命令都是让 Redis 立即执行数据的全量备份,将数据备份到 /var/lib/redis/dump.rdb 文件中
总结:这两条命令不需要开发者手动执行,满足配置文件中的配置策略后,会自动触发 BGSAVE 执行全量备份
save 60 10000 # 这里表示每隔60s,如果有超过10000个key发生了变更,那么就进行一次全量备份
save 300 10
save 900 1
AOF 数据持久化备份的是 Redis 的命令,通过在 appendonly.aof 文件中追加命令的方式实现备份,默认是关闭的,需要在配置文件中进行开启
配置文件:/etc/redis.conf
# 是否开启AOF,默认关闭,yes表示开启
appendonly yes
# 1.每次收到写命令就立即强制写入磁盘,是最安全的。
appendfsync always
# 2.每秒钟强制写入磁盘一次,在性能和持久化方面做平衡,推荐该方式
appendfsync everysec
# 3.完全依赖OS的写入,一般为30秒左右一次,性能最好但是持久化最没有保证,不推荐
appendfsync no
# 当前AOF文件大小是上次日志重写得到AOF文件大小的二倍时,自动启动新的日志重写过程。
auto-aof-rewrite-percentage 100
# 当前AOF文件启动新的日志重写过程的最小值,避免刚刚启动Redis时由于文件尺寸较小导致频繁的重写。
auto-aof-rewrite-min-size 64mb
因为单个Redis支持的读写能力有限,所以可以使用多个redis来提高并发处理能力;通常搭建主从 (Master/Slave) 架构实现,在主从架构中
在从服务器的配置文件中添加如下配置:
replicaof 主服务器的ip地址 主服务器的端口号
# 注意:如果主服务器[master]没有密码则不填写此项配置
masterauth 主服务器的密码
哨兵 sentinel 是在 Redis 主从架构的模式下,实现高可用性的一种机制,可以监视主服务器和其下的所有从服务器,当主服务器下线时自动进行故障转移
创建哨兵配置文件,比如:/etc/sentinel.conf
# 配置1:哨兵服务端口
port 26379
# 配置2:sentinel monitor
# master-redis-name 主节点名称,可以自定义。客户端访问时会用到
# master-redis-ip 主节点IP
# master-redis-port 主节点端口
# quorum 故障切换投票数(整数值),下面配置,表示如果有1个sentinel认同切换主节点,就执行切换
sentinel monitor name 127.0.0.1 6379 1
# 配置3:主节点登录密码,如果主节点无密码此项配置不写
sentinel auth-pass name 123456
第1步:停止原有6379的Redis服务
systemctl stop redis
第2步:创建主节点(master)的配置文件,名字为redis-6379.conf
cp -p /etc/redis.conf /etc/redis-6379.conf
第3步:创建6379 6380 6381的数据目录
mkdir data
cd data/
mkdir 6379 6380 6381
第4步:修改 redis-6379.conf 文件内容,具体内容如下:
# 配置1:默认端口6379
port 6379
# 配置2: pidfile
pidfile /var/run/redis_6379.pid
# 配置3: 设置数据目录 (这个目录需要我们手动自己创建)
dir /var/lib/redis/data/6379
# 配置4:日志文件
logfile '/var/log/redis/redis-6379.log'
# 配置5:设置redis的登录密码
requirepass 123456
# 配置6:主节点认证
masterauth 123456
第5步:创建从节点 redis-6380.conf 配置文件,其修改的内容如下
cp -p /etc/redis-6379.conf /etc/redis-6380.conf
# 配置1:默认端口
port 6380
# 配置2: pidfile
pidfile /var/run/redis_6380.pid
# 配置3: 设置数据目录(这个目录需要我们手动自己创建)
dir /var/lib/redis/data/6380
# 配置4:日志文件
logfile '/var/log/redis/redis-6380.log'
# 配置5:设置redis的登录密码
requirepass 123456
# 配置6:主节点认证
masterauth 123456
# 配置7:设置要连接的master的ip和端口
replicaof 127.0.0.1 6379
第6步:创建从节点redis-6381.conf配置文件,其修改的内容如下
cp -p /etc/redis-6380.conf /etc/redis-6381.conf
# 配置1:默认端口
port 6381
# 配置2: pidfile
pidfile /var/run/redis_6381.pid
# 配置3: 设置数据目录(这个目录需要我们手动自己创建)
dir /var/lib/redis/data/6381
# 配置4:日志文件
logfile '/var/log/redis/redis-6381.log'
# 配置5:设置redis的登录密码
requirepass 123456
# 配置6:主节点认证
masterauth 123456
# 配置7:设置要连接的master的ip和端口
replicaof 127.0.0.1 6379
第7步:启动主从节点服务(可以打开多个窗口,在不同窗口启动不同服务)
第8步:登录主节点,并检查主从架构状态
redis-cli -p 6379
127.0.0.1:6379>auth 123456
127.0.0.1:6379>info replication
第9步:主节点写入数据,从节点会同步数据
主节点写入数据,从节点查看数据确认
redis-cli -p 6379
127.0.0.1:6379>set k1 100
第10步:停止原来的哨兵服务
systemctl stop redis-sentinel
第11步:在用/etc/目录下创建哨兵配置文件:sentinel.conf,添加内容如下:
# 哨兵服务端口
port 26379
# sentinel monitor
# master-redis-name 主节点名称,可以自定义。客户端访问时会用到
# master-redis-ip 主节点IP
# master-redis-port 主节点端口
# quorum 故障切换投票数(整数值),下面配置,表示如果有1个sentinel认同切换主节点,就执行切换
sentinel monitor name 127.0.0.1 6379 1
# 主节点登录密码
sentinel auth-pass name 123456
第12步:启动哨兵Sentinel,检查主从架构
redis-sentinel sentinel.conf
第13步:kill主节点6379进程
ps -aux | grep redis
kill -9 进程号
第14步:检查主节点宕机后 sentinel 是否选择了新的主节点,查看终端日志
第15步:重新启动 6379 的服务,检查哨兵是否将其设置为新的从,查看终端日志
org.springframework.boot
spring-boot-starter-data-redis
com.fasterxml.jackson.core
jackson-databind
2.15.3
spring.redis.host=localhost
spring.redis.port=6379
#如果Redis没有密码此项可以不设置
#spring.redis.password=123456
spring.redis.database=0
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate redisTemplate = new RedisTemplate<>();
// 设置连接工厂
redisTemplate.setConnectionFactory(redisConnectionFactory);
//设置字符串序列化器
redisTemplate.setKeySerializer(RedisSerializer.string());
redisTemplate.setValueSerializer(RedisSerializer.json());
//设置hash的序列化器
redisTemplate.setHashKeySerializer(RedisSerializer.json());
redisTemplate.setHashValueSerializer(RedisSerializer.json());
return redisTemplate;
}
}
//类中自动装配
@Autowired
private RedisTemplate redisTemplate;
//方法中直接使用
redisTemplate.opsForValue().set(key, value);