Redis学习笔记-从理论到实践,不止get/set(转载)

Redis学习笔记
概述:
一、Redis五大数据类型
1.1 Redis-key
1.2 String
1.3 List
1.4 Set
1.5 Hash
1.6 Zset
二、Redis三种特殊数据类型
2.1 geospatial
2.2 hyperloglog
2.3 Bitmap
三、Redis基本的事务操作
四、Redis的乐观锁
监视测试
五、使用Jedis操作Redis
1、导入对应的依赖
2、编码测试
3、常用API
六、通过Jetis再次理解事务
七、SpringBoot集成Redis
八、自定义RedisTemplate
九、RedisConfig配置文件详解
十、Redis持久化
1、RDB(Redis DataBase)
2、AOF(Append Only File)
十一、Redis订阅发布
十二、Redis主从复制
哨兵模式
十三、Redis缓存穿透和雪崩
缓存穿透
布隆过滤器
缓存过滤器
缓存击穿
设置热点数据永不过期
加互斥锁
缓存雪崩
Redis高可用
限流降级
数据预热
概述:
作为学习Redis的学习笔记,学习的课程时b站的up主,遇见狂神说,一边学代码,一边学做人!全体起立!配置redis这里不讲解了,教程喝多,本学习笔记是在linux配置redis后学习所记!
视频链接https://www.bilibili.com/video/BV1S54y1R7SB?p=1

狂神:只要学不死,就往死里学

一、Redis五大数据类型
1.1 Redis-key
1.2 String
1.3 List
1.4 Set
set(集合),其中的值不可以重复。

sadd myset “hello” #set集合中添加元素
sadd myset “xwy”
sadd myset “love”
smembers myset #查看值
sismember myset hello #是否存在hello
1
2
3
4
5
scard myset #元素个数
1
remove
srem myset “hello” #移除set的元素 hello
1
2
#set是无序不重复集合 可以随机获取
srandmember myset #随机抽出一个元素
srandmember myset 2 # 随机抽出俩元素
1
2
3
#随机移除key
spop myset #随机删除一些set集合的元素
1
2
#将一个指定的值,移动到另外一个key中
smove myset myset2 “xwy” # 将xwy移动到myset2
1
2
微博、b站,共同关注功能(并集)
数字集合类:

  • 并集 sunion key1 key2
  • 交集 sinter key1 key2
  • 差集 sdiff key1 key2 # key1 key2不同的元素

1
2
3
4
5
6
7
微博 A用户将所有关注的人放在一个set集合中!将他的粉丝也放在一个集合里
共同关注、共同爱好,二度好友

1.5 Hash
Hash(哈希)

Map集合: key-Map集合!相当于key - ,value是一个Map集合,本质和string没有太大区别

hset myhash filed1 hello
hget myhash filed1
hmset myhash filed1 hello filed2 world # set多个key-vlaue
hget myhash filed1 filed2
hgetall myhash # 获取全部的hash值
1
2
3
4
5
hdel myhash filed1 # 删除指定的hash的key字段,对用的value也就消失了
1
hlen myhash # 获取长度
hexists myhash filed1 # 判断是否存在
1
2
hkeys myhash # 只获取key
hvals myhash # 只获取values
1
2
incr decr
hincr myhash filed3 1 # 加一
hdecr myhash filed3 1
hsetnx myhash filed4 hello # 如果不存在则可以设置,存在则不可以设置
1
2
3
4
hash存储变更的数据,尤其是用户信息的保存,经常变动的信息,hash适合对象的存储,string适合字符串的存储。

1.6 Zset
Zset(有序集合),在set的基础上增加了一个值。set k1 v1 ; zset k1 score v1

zadd myset 1 one
zadd myset 2 two 3 three # 添加多个值
zrange myset 0 -1
1
2
3
#排序如何实现?
zadd salary 2500 xwy
zadd salary 599 xxx
zadd salary 8000 xsk
zrangebyscore salary -inf +inf #从无穷小到无穷大(相当于遍历所有的)
zrangebyscore salary -inf +inf with scores # 带上score

zrevrange salary 0 -1 #从大到小
1
2
3
4
5
6
7
8
zrem salary xwy #移除
1
zcard salary #获取数量
zcount salary 1 3 #获取指定区间的成员数量
1
2
案例:

set 排序,存储班级成绩表,工资表排序

普通消息:1 重要消息 2 带权重判断

排行榜应用,取top N

二、Redis三种特殊数据类型
2.1 geospatial
朋友圈定位,附近的人,打车距离计算

Redis的Geo在Redis3.2版本加入,可以推算地理位置的信息,比如两地的距离,方圆几里的人

#getadd
#两极无法添加,实际我们是使用java程序一次性倒入所有

geoadd china:city 116.40 39.90 beijing
geoadd china:city 121.47 31.23 shanghai
geoadd china:city 106.50 29.53 chongqing
geoadd china:city 114.05 22.52 shenzhen
geoadd china:city 120.16 30.24 hangzhou

1
2
3
4
5
6
7
8

geopos

#获取指定城市的经纬度
#获取当前定位:一定是一个坐标值

geopos china:city beijing
geopos china:city beijing chongqing
1
2
3
4
5
6
#geodist
#m 米 、 km 千米 、 mi 英里 、 ft 英尺
geodist china:city beijing shanghai km #计算距离
1
2
3
#附近的人?(获取附近的人定位),通过半径来查询
#georadius

georadius china:city 110 30 1000 km withdist #显示到中间的距离
georadius china:city 110 30 1000 km withcoord #结显示他人的定位信息
georadius china:city 110 30 1000 km withdist withcoord count 200 # 以 110,30 为中心,半径 1000km 的 200 个城市
1
2
3
4
5
6
#georadiusbymember
#找出位于指定元素周围的其他元素
georadiusbymember china:city beijing 1000 km
1
2
3
#geohash
#返回11位的字符的geohash字符串
#将二维的经纬度转换成一维的字符串,如果两个字符串越相近,距离越近
#不常用
geohash china:city beijing chongqing
1
2
3
4
5
geo的底层实现原理就是zset,我们可以使用zset命令操作geo!

2.2 hyperloglog
什么事基数?

A{1,3,5,7,9}

B{1,3,5,7,8}

基数(不重复的元素) =5 ,可以接受误差!

简介

Redis 2.8.9更新了Hyperloglog数据结构。

Redis Hyperloglog基数统计的算法。

优点:占用内存的固定的,2^64不同元素的技术,只需要12kb内存!

网页的UV(一个人访问一个网站多次,但是还是算做一个人)

传统的方式是使用set,保存用户id,然后统计set的元素作为标准判断。

这个方式如果保存大量用户id,就会比较麻烦!

0.81%错误率!可以接受!统计uv任务,可以忽略不计!如果不允许容错,就使用set或者自己的数据类型!

pfadd mykey a b c d e f g h i j
pfcount mykey #统计基数数量
pfmerge mykey mykey2 mykey3 # 合并两组元素到mykey3!
1
2
3
2.3 Bitmap
位存储

统计疫情感染人数: 0 0 0 1 0

统计粉丝活跃、用户登陆未登陆、365天打卡!

只要是两个状态的都可以使用bitmap!

都是操作二进制位来进行记录,只有0和1两个状态

#周一到周六的打卡记录
setbit sign 0 1
setbit sign 1 1
setbit sign 2 0
setbit sign 3 1
setbit sign 4 1
setbit sign 5 0
1
2
3
4
5
6
7
#查看某一天是否打卡
getbit sign 3
1
2
#统计打卡天数
bitcount sign
1
2
三、Redis基本的事务操作
MySQL: ACID!

Redis单条命令保证原子性,但是事务不保证原子性

**Redis事务没有隔离级别的概念!**所有的命令在事务中,并没有直接被执行,只有发起执行命令才会执行!

Redis事务本质,一组命令的集合!一个事物的所有命令都会被序列化,在食物执行的过程中,会按照顺序执行!

一次性、顺序性、排他性!

redis的事务:

开启事务:Multi
命令入队:…
执行事务:exec
multi
set k1 v1
set k2 v2
set k3 v3
exec
1
2
3
4
5
#放弃事务
multi
set k1 v1
set k2 v2
set k3 v3
discard
1
2
3
4
5
6
#编译型异常(代码有问题,命令有错),事务中的所有命令都不会被执行!
multi
set k1 v1
set k2 v2
set k3 v3
getset k3 #错误语句
exec
#不会执行所有的命令

#运行时异常(1/0),如果事务队列中存在语法性错误!其他命令正常,错误命令报错!
multi
set k1 “vvvv”
incr k1
exec
#只有错误语句没有被执行!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
四、Redis的乐观锁
监控

悲观锁:

悲观,什么时候都出问题,无论做什么都会加锁
乐观锁:

很乐观,认为什么时候都不会出问题,不回上锁,更新数据的时候才判断一下,在此期间有没有修改过数据
获取version
更新的时候比较version
监视测试
set money 100
set out 0
watch money #监视money
multi #事务正常结束,数据期间没有发生变动,这个时候正常执行
decrby money 20
decrby out 20
exec
1
2
3
4
5
6
7
#再开一个客户端测试多线程修改值,watch当作redis的乐观锁操作
set money 100
set out 0
watch money #监视money
multi
decrby money 20
decrby out 20

#重新开一个客户端
set money 200

#回第一个客户端
exec #错误
unwatch #事务失败,先解锁
watch #再加锁
multi
decrby money 10
exec #成功
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
五、使用Jedis操作Redis
我们使用java操作Redis

什么是Jedis,是Redis官方推荐的Java连接工具,是java操作Redis的中间件

1、导入对应的依赖


redis.clients
jedis
3.2.0


com.alibaba
fastjson
1.2.62


1
2
3
4
5
6
7
8
9
10
11
12
2、编码测试
连接数据库
操作命令
断开连接
package com.xwy.test;
import redis.clients.jedis.Jedis;
/**

  • @author levi
  • @create 2020/7/25 12:57 下午
    */
    public class TestPing {
    public static void main(String[] args){
    Jedis jedis = new Jedis(“ip”,6379);
    System.out.println(jedis.ping());
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    3、常用API
    所有代码类似命令!

六、通过Jetis再次理解事务
事务

JSONObject jsonObject = new JSONObject();
jsonObject.put(“hello”,“world”);
jsonObject.put(“name”,“xwy”);
Transaction multi = jedis.multi(); //开启事务
String result = jsonObject.toJSONString();
try{
multi.set(“user1”,result);
multi.set(“user2”,result);
multi.exec();
}catch (Exception e){
multi.discard();
e.printStackTrace();//放弃事务;
}finally {
System.out.println(jedis.get(“user1”));
jedis.close();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
七、SpringBoot集成Redis
springboot2.x后,原来的jedis被替换成了lettuce

jedis:采用的直连,多个线程操作是不安全的,想要避免不安全,使用jetis pool连接池,更像BIO模式

lettuce:采用netty,实例可以在多个线程中进行共享,不存在线程不安全的情况,可以减少线程数据,更像NIO模式:

整合测试

导入依赖
配置连接
spring.redis.host=39.97.184.172
spring.redis.port=6379
1
2
测试
package com.xwy;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisTemplate;

@SpringBootTest
class SpringbootO2ApplicationTests {

@Autowired
private RedisTemplate redisTemplate;
@Test
void contextLoads() {

    //opsForValue 操作字符串 类似string
    //opsForList 操作List
    //ops。。。

// //获取redis连接对象
// RedisConnection connection = redisTemplate.getConnectionFactory().getConnection();
// connection.flushAll();
// connection.flushDb();

    redisTemplate.opsForValue().set("mykey","xwy");
    System.out.println(redisTemplate.opsForValue().get("mykey"));
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
八、自定义RedisTemplate
首先测试:
在这里插入图片描述

关于对象的保存:

需要讲对象序列化!

在这里插入图片描述

可以成功获取值!

不同的方式的配置类:(写好的固定模版,企业中拿去直接使用!!!)

在这里插入图片描述
在这里插入图片描述

在真实的开发中,一般都自己封装RedisUtil

由于代码太多,先留个坑

九、RedisConfig配置文件详解
#1、配置文件 unit单位对大小写不敏感!

2、bind ip #绑定的IP

3、protected-mode #保护模式

#通用

4、daemonize yes #以守护进程方式运行,默认是no 需要改为yes

5、pidfile /var/run/redis_6379.pid # 如果后台运行,需要制定pid文件

6、loglevel notice #日志
logfile “” #输出的日志文件位置名

7、databse 16 # 默认是16个数据库

快照

#持久化,在规定的时间内,执行了多少次操作,则会持久化到文件.rdb.aof
#redis是内存数据库,如果没有持久化,数据断电即失

8、#如果900s内,如果至少有一个key进行了修改,就需要持久化操作
save 900 1

9、stop-writes-on-bgsave-error yes # 持久化出错还要不要继续执行

10、rdbcompression yes # 是否压缩rdb文件,需要小号一些cpu资源

11、rdbchecksum yes #保存rdb文件的时候,是否要进行错误检查校验

12、dir ./ #rdb 文件保存的目录

#安全

13、密码

#限制

14、maxclients 1000 #设置能连接redis的最大客户端数量

15、maxmemory #设置redis配置的最大内存容量

16、maxmemory-policy noeviction #内存达到上限之后的处理策略
#移除过期的key
#报错
#。。。。

#APPEND ONLY模式 aof配置

17、appendonly no #默认是不开启aof模式 默认是rdb方式持久化,在大部分情况下,rdb完全够用

18、appendfilename “appendonly.aof“ #持久化文件的名字

19 #appendfsync always #每次修改都会sync 消耗性能
#appendfsync everysec #每秒执行一次,可能会丢失这一秒的数据
#appendfsync no #不执行sync
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
十、Redis持久化
Redis是一个内存数据库,不提供持久化那么数据断电即失!

1、RDB(Redis DataBase)
触发机制

save的规则满足的情况下,出发rdb规则

执行flushall,也会触发

推出redis,也会产生一个rdb文件

备份自动生成一个dump.rdb

如果恢复rdb文件

1、只需要将rdb文件放在redis启动目录下,redis启动自动检查dump.rdb回复其中的数据

2、查看需要存在的位置

config get dir
1
优点:

适合大规模的数据恢复
对数据完整性的要求并不高,
缺点

需要一定的时间间隔进行进程操作,如果redis意外宕机,这个最后一次修改的数据就没有了。
fork进程的时候,会占用一定的内容空间。
2、AOF(Append Only File)
将所有命令都记录下来,history,回复的时候就把这个文件全部执行一遍!

AOF保存的文件时appendonly.aof!!

默认是不开启的,需要手动配置!!appendonly on改为yes!!!重启redis就可以开启!!

如果aof文件有错误,redis启动不起来!我们需要修复!

redis给我们提供了一个工具,叫redis-check-aof!!!

redis-check-aof --fix appendonly.aof
1
优点和缺点

优点

每一次修改都同步,文件完整性更好
每秒同步一次可能会丢失一秒数据
从不同步效率最高
缺点

相对于数据文件来说,aof远远大于rdb,修复的速度比rdb慢
运行效率比rdb慢,所有redis默认的持久化策略是rdb!
十一、Redis订阅发布
通信 队列 发送者 订阅者

Redis发布订阅(pub/sub)是一种消息通信模式。微信、微博、关注系统

Redis可以订阅任意数量的频道。

角色

消息发送者、频道、接受者

测试

subscribe kuangshenshuo #建立频道

#去另一个终端!
publish kuangshenshuo “hello kuangshen” #发送消息
1
2
3
4
使用场景:

实时消息系统
实时聊天(频道作为聊天室,将信息回显给所有人)
订阅、关注系统
稍微复杂的场景使用消息中间件MQ做

十二、Redis主从复制
数据复制是单向的,只能从主节点到从节点!!

主从复制,读写分离!80%的情况下都是独操作!减缓服务器压力,架构中常用!一主二从!

作用

数据冗余
故障恢复
负载均衡
高可用(集群)
一般来说,Redis运用于工程,只使用一台是万万不可的!!!

结构上,单台redis服务器会发生单点故障,并且一台服务器要处理所有的负载,压力较大
容量上,单台redis内存容量有限,一般来说,单台redis最大使用内存不要超过20G。
在这里插入图片描述
环境配置

127.0.0.1:6379> info replication #查看当前库的信息

Replication

role:master # 角色
connected_slaves:0 #没有从机
master_replid:c35253ec819f702ff5d100cd6b88bebd5f897a15
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
127.0.0.1:6379>
1
2
3
4
5
6
7
8
9
10
11
12
13
#在两个从机中配置!!
slaveof 127.0.0.0.1 6379
1
2
真实的配置应该是在配置文件中配置,这里使用的是命令,是暂时的!!

细节

主机可以写,从机只能读不能写!!主机中的所有信息和数据都会被从机自动保存!!

主机断开连接,从机依旧连接到主机,但是没有写操作了,如果住机会来了,从机仍然能获得主机写的信息!!

如果是使用命令行配置的,从机重启会变成主机,重新变为主机,重新变为从机后,立马会从主机中获取值!

复制原理

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jB2Q3rCU-1595755773619)(/Users/levi/Library/Application Support/typora-user-images/截屏2020-07-26 上午12.30.55.png)]

如果没有老大了,能不能选择一个老大出来呢?

slaveof no one #如果主机断开可以篡位,是自己变为主机!
1
其他节点手动变为我的从节点!手动!主机回来之后,只能重新配置,光杆司令!

哨兵模式
哨兵模式(自动选举老大的模式)

哨兵是一个独立的进程!

测试

#1 配置
#进入redis.conf所在的文件夹
vim sentinel.conf
#写入
sentinel monitor myredis 127.0.0.1 6379 1 #被监控的名称 主机 端口号 1
#后面的数字1 代表主机挂了,slave投票看让谁接替成为主机,票数最多的,成为主机!
1
2
3
4
5
6
#2 启动
#bin
redis-sentinel kconfig/sentinel.conf
1
2
3
如果主机master宕机,就会从从机中随机选一个作为主机!!主机回来后,自动现任主机的从机!

优缺点

优点:

哨兵集群,基于主从复制模式,所有主从配置的优点都有
主从可以切换,故障可以转移,可用性就会更好
哨兵模式是主从模式爹升级,手冻到自动,更加健壮
缺点:

Redis不好在线扩容,集群容量达到上限,在线扩容十分麻烦
实现哨兵模式的配置其实是很麻烦的,有很多选择
哨兵模式的全部配置

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XhSsmwBD-1595755773622)(/Users/levi/Library/Application Support/typora-user-images/截屏2020-07-26 下午4.17.30.png)]

在这里插入图片描述
在这里插入图片描述

十三、Redis缓存穿透和雪崩
缓存穿透
概念

用户想要查询一个数据,但是缓存内没有,数据库也没有,于是查询失败,但是用户很多的情况下,缓存都没有命中,于是都去请求数据库,这就给数据库造成很大压力,出现缓存穿透!!

解决方案

布隆过滤器
在这里插入图片描述

缓存过滤器
在这里插入图片描述

问题

如果空值能够被缓存起来,就意味着缓存需要更多的空间,因为当中很多空值的键
即使对空值设置了过期时间,但是还是会存在缓存层和存储层数据会有一段时间窗口的不一致,这对于需要保持数据一致性的业务会有影响
缓存击穿
火力全部被压在一个地方!

微博服务器宕机!

概述

在这里插入图片描述

解决方案

设置热点数据永不过期
从缓存层面看,没有设置过期时间,所以不会出现热点key过期后产生的问题

加互斥锁
分布式锁,保证每一个key同时只有一个线程去查询后端服务,其他线程没有获得分布式锁的权限,因此只需要等待即可,这种发式将高并发的压力转移到了分布式锁,对分布式锁的考验很大!

缓存雪崩
概念

在这里插入图片描述

解决方案

Redis高可用
redis可能挂掉,那么多增加几台redis,一台挂掉其他可以继续工作,搭建集群,异地多活

限流降级
缓存失效,通过加锁或者队列空值数据库写缓存的线程数量

数据预热
正式部署前,先把可能的数据先预先访问一遍,这样部分可能大量访问的数据就会加载到缓存中,在即将发生大并发访问前手动出发缓存不同的key,设置不同的过期时间,让缓存失效的时间尽量均匀。

原文链接:https://blog.csdn.net/weixin_42098332/article/details/107581121?utm_medium=distribute.pc_feed.none-task-blog-personrec_tag-11.nonecase&depth_1-utm_source=distribute.pc_feed.none-task-blog-personrec_tag-11.nonecase&request_id=5f1ff71b9cc79f6252ce48b1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值