redis学习

什么是NoSQL

not only sql :不仅仅是sql
Map<String,Object>,使用键值对来控制。这个就是典型的Redis的一种。

NoSQL的特点

  1. 方便扩展(K,V之间没有关系,很好扩展)。像Java为什么做接口,就是为了解耦。
  2. 大数据量高性能(Redis 1秒写8万次,读取11万条SQL缓存记录级,是一种细粒度的缓存,性能会比较高!)
  3. 数据类型是多样型的!(不需要事先设计数据库!随取随用!如果是数据量十分大的表,很多人就无法设计了!)
  4. 传统RDBMS和NoSQL
传统的RDBMS
- 结构化组织
- SQL
- 数据和关系都存在单独的表中
- 操作操作,数据定义语言
- 严格的一致性
- 基础的事务
Nosq1
- 不仅仅是数据
- 没有固定的查询语言
- 键值对存储,列存储(像大数据的HBase),文档存储,图形数据库(社交关系)
- 最终一致性,
- CAP定理和BASE(异地多活) 初级架构师 (只要学不死 就往死里学)
- 高性能,高可用,高可扩
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210113094929154.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzQ2MTUzOTY0,size_16,color_FFFFFF,t_70)
## Redis入门
1. Redis: Remote Dictionary Server,远程字典服务,是一个开源的使用ANSI C语言编写,支持网络,可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API(什么意思,也可以通过python等来调用)
2. redis会周期性的把更新的数据写入磁盘或者修改操作写入追加的记录文件,并且在此基础上实现了master-slave(-)同步。
3. 免费和开源!是当下最热门的NoSQL技术之一!也被人们称为结构化数据库。
## Redis能干嘛?
1.内存存储、持久化,内存中是断电即失、所以说持久化很重要(rdb、aof)
2.效率高,可以用于高速缓存
3.发布订阅系统
4.地图信息分析
5.定时器、计时器(浏览量!incr decre就可以,不需要从数据库中取数据)
**特性:**
1、多样的数据类型
2、持久化
3、集群
4、事务
**学习中需要用到的东西
1.官网:redis.io
2、中文网:redis.cn**
## Windows安装
redis-benchmark.exe测试性能
​ redis-check-aof.exe测试持久化
​ redis-cli.exe客户端
​ redis-server.exe服务端

```java
默认端口是6379
命令ping,返回PONG,说明是空的
他的存储方式是KV键值对,
	set name kuangshen,返回ok。
	get name,返回kuangshen。

在这里插入图片描述

Linux安装

1.下载安装
2.解压redis的安装包
3.进入解压后的文件,可以看到我们redis的配置文件
​ redis.conf – redis配置文件
4.基本命令环境安装
  1)安装C的环境
  yum install gcc-c++
  2)查看C当前版本
  gcc -v
  3) 会把所有的环境都给你配置好,需要点时间,等待他make完毕,make完毕后 make install再次确认下
  make || make install
5. 默认的安装路径
/usr/local/bin
6. redis默认不是后台启动的,vim这个.conf文件
改了之后这样就默认后台启动了,这样就配置完成了,如果不设置就会如后台所示
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210113100708163.png)
7. 启动redis服务,指定启动的conf文件
redis-server kconfig/redis.conf 
8. 使用redis-cli 进行连接测试
redis-cli -p 6379
9.当你get不存在的值得时候会返回空:(nil)
keys *  查看所有的key
10.查看redis的进程是否开启
ps -ef|grep redis
11.如何关闭redis服务呢?
1)shutdown  关闭redis
2)然后到未连接状态,直接exit退出即可
3)然后可以再次查看进程是否存在
12 测试性能
redis-benchmark是一个压力测试工具!
官方自带的性能测试工具!
redis-benchmark命令参数!
# 测试:100个并发连接  100000请求
redis-benchmark -h localhost -p 6379 -c 100 -n 100000
注意:该命令是在 redis 的目录下执行的,而不是 redis 客户端的内部指令。

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

Redis基础知识
redis默认有16个数据库,不信的话可以vim配置文件
redis.windows.conf >> databases 16
默认使用的是第0个数据库
select 3:切换到第三个数据库
DBSIZE:查看数据库的大小
flushdb:清空当前数据库的所有key
flushall:清空整个 Redis 服务器的数据(删除所有数据库的所有 key)
exists:查看当前key是否存在
EXISTS name
返回1存在 返回0不存在
move:移除当前的key字段
move name 1
不过一般我们不会这么用的
expire:设置key的过期时间,单位是秒
expire name 10:设置10秒后name-key自动失效
ttl:查看当前key的剩余时间
ttl name:查看name-key还有多久自动过期
已经过期了返回-2
type:查看当前key类型
type name ,返回string

Redis是单线程的!

明白Redis是很快的,官方表示,**Redis是基于内存操作,CPU不是Redis性能瓶颈,Redis的瓶颈是根据机器的内存和网络带宽,**既然可以使用单线程来实现,就使用单线程了!所以就是用了单线程了。
Redis是C语言写的,官方提供的数据为100000+的QPS,完全不比同样是使用key-vale的Memecache差!

Redis为什么单线程还这么快?

1、误区1:高性能的服务器一定是多线程的?
​ 答:不一定
2、误区2:多线程(CPU上下文会切换!)一定比单线程效率高!
​ 多线程有弊端,跟CPU调度有关。CPU会上下文切换,也会耗费资源。
CPU速度 > 内存 > 硬盘
核心:redis是将所有的数据全部放在内存中的,所以说使用单线程去操作效率就是最高的。因为多线程CPU会上下文切换,这是一个耗时的操作!!!对于内存系统来说,如果没有上下文切换,效率就是最高的。多次读写都是在一个CPU上的,在内存情况下,这个就是最佳的方案。​CPU切换一般在1500~2500纳秒之间。

redis官网介绍

Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件MQ。 它支持多种类型的数据结构,如 字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets) 与范围查询, bitmaps, hyperloglogs 和 地理空间(geospatial) 索引半径查询。 Redis 内置了 复制(replication),LUA脚本(Lua scripting), LRU驱动事件(LRU eviction),事务(transactions) 和不同级别的 磁盘持久化(persistence), 并通过 Redis哨兵(Sentinel)和自动 分区(Cluster)提供高可用性(high availability)。
80%只会用string类型

String(字符串类型)
90%的java程序员使用redis只会使用1个String类型!
#######################################################################
127.0.0.1:6379> set key1 v1  
OK
127.0.0.1:6379> get key1 
"v1"
127.0.0.1:6379> keys * 
1) "key1"
127.0.0.1:6379> exists key1
(integer) 1
127.0.0.1:6379> append key1 "hello"  # 追加字符串 
(integer) 7
127.0.0.1:6379> append name "zhangsan"  # 追加字符串 如果key不存在,就相当于setkey
(integer) 8
127.0.0.1:6379> keys *
1) "name"
2) "key1"
127.0.0.1:6379> get key1
"v1hello"
127.0.0.1:6379> strlen key1    # 获取字符串长度
(integer) 7
127.0.0.1:6379> append key1 ",kuangshen"
(integer) 17
127.0.0.1:6379> strlen key1
(integer) 17
127.0.0.1:6379> get key1
"v1hello,kuangshen"
#######################################################################
127.0.0.1:6379> set views 0  # 设置初始浏览量为0
OK
127.0.0.1:6379> get views
"0"
127.0.0.1:6379> incr views   #  自增1
(integer) 1
127.0.0.1:6379> incr views   
(integer) 2
127.0.0.1:6379> get views 
"2"
127.0.0.1:6379> decr views    #	 自减1
(integer) 1
127.0.0.1:6379> decr views
(integer) 0
127.0.0.1:6379> decr views
(integer) -1
127.0.0.1:6379> INCRBY views 10   #【步长-增量】
(integer) 9
127.0.0.1:6379> DECRBY views 10   #【步长-增量】
(integer) -1
#######################################################################
字符串范围 range 
【getrange】
127.0.0.1:6379> set key1 "hello,kuangshen"
OK
127.0.0.1:6379> get key1
"hello,kuangshen" 
127.0.0.1:6379> GETRANGE key1 0 3   # 截取字符串 [0,3]
"hell"
127.0.0.1:6379> GETRANGE key1 0 -1	#  读取全部的字符串 和 get key是一样的
"hello,kuangshen"
【setrange】  
127.0.0.1:6379> set key2 abcdefg
OK
127.0.0.1:6379> get key2
"abcdefg"
127.0.0.1:6379> setrange key2 1 xx  # 替换指定位置开始的字符串!
(integer) 7
127.0.0.1:6379> get key2
"axxdefg"
#######################################################################
【setex】:(set with expire)# 设置过期时间
【setnx】:(set if not exist)# 不存在再设置(在分布式锁中会常常使用!)

127.0.0.1:6379> setex key3 30 "hello"  # 设置key3的值伟hello,30秒后过期
OK
127.0.0.1:6379> get key3
"hello"
127.0.0.1:6379> ttl key3
(integer) 23
127.0.0.1:6379> SETNX mykey "redis"  # 如果mykey不存在,创建mykey
(integer) 1
127.0.0.1:6379> keys *   # 此时key3没有因为已经过期
1) "mykey"
2) "key"
3) "key1"
4) "key2"
127.0.0.1:6379> ttl key3     # -2表示已经过期
(integer) -2
127.0.0.1:6379> setnx mykey "MongoDB"    #  如果mykey存在,创建失败!
(integer) 0
127.0.0.1:6379> get mykey
"redis"




#######################################################################
127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3  # 同时设置多个值
OK
127.0.0.1:6379> keys *    
1) "k2"
2) "k3"
3) "k1" 
127.0.0.1:6379> mget k1 k2 k3   #  同时获取多个值
1) "v1"
2) "v2"
3) "v3"
127.0.0.1:6379> msetnx k1 v1 k4 v4   # msetnx 是一个原子性的操作 要么一起成功/一起失败!
(integer) 0
127.0.0.1:6379> get v4
(nil)

# 对象
set user:1{name:zhangsan,age:3}  # 设置一个user:1 对象,对象值为 json字符来保存一个对象!

# 这里的key是一个巧妙的设计: user:{id}:{filed},如此设计在Redis中是完全OK的!
127.0.0.1:6379> mset user:1:name zhangsan user:1:age 2
OK
127.0.0.1:6379> mget user:1:name user:1:age
1) "zhangsan"
2) "2"

# 这个作用是什么呢?比如微信阅读量
127.0.0.1:6379> set article:10000:views 0  # 设置文章编号为10000的对象的初始浏览量,为0

###############################################################################
getset  # 先get然后再set

127.0.0.1:6379> getset db redis   #  如果不存在值  则返回 nil
(nil)
127.0.0.1:6379> get db
"redis"
127.0.0.1:6379> getset db mongodb   #  如果存在值  获取原来的值,并设置新的值 用于更新一般
"redis"
127.0.0.1:6379> get db
"mongodb"

RDB(Redis DataBase)

主从复制中,RDB是备用的。在从机上面,不占用主机内存。而AOF基本不用,
在指定的时间间隔内将内存中的数据集快照写入磁盘,也就是行话讲的Snapshot快照,它恢复时是将快照文件直接读到内存里。

Redis会单独创建(fork)一个子进程来进行持久化,会先将数据写入到一个临时文件中,待持久化过程都结束了,再用这个临时文件替换上次持久化好的文件。整个过程中,主进程是不进行任何IO操作的。这就确保了极高的性能。如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。RDB的缺点是最后一次持久化后的数据可能丢失。

我们默认的就是RDB,一般情况下不需要修改这个配置。

有时候在生产环境我们会将dump.rdb进行备份
rdb保存的文件是dump.rdb 都是在我们的配置文件中快照中配置的
在这里插入图片描述

触发机制

1、save的规则满足的情况下,会自动触发rdb规则

2、执行flushall命令,也会触发我们的rdb规则!
3、退出redis,也会产生rdb文件!

备份就自动生成一个dump.rdb文件

如何恢复rdb文件!

1、只需要将rdb文件放在我们redis启动目录就可以,redis启动的时候会自动检查dump.rdb恢复其中的数据!
2、查看需要存在的位置
node1:6379> CONFIG GET dir

  1. “dir”
  2. “/export/server/redis-3.2.8-bin/datas” # 如果在这个目录下存在dump.rdb文件,启动就会自动恢复其中的数据
    优点:
    1.大规模的数据恢复
    2.对数据的完整性要不高!
    缺点:
    1.需要一定的时间间隔进程操作!(当然你也可以自己去修改配置)。如果redis意外宕机了,这个最后一次修改数据就没有的了!
    2.fork进程的时候,会占用一定的内存空间!!

AOF(Append Only File)

将我们的所有命令都记录下来,history,恢复的时候就把这个文件全部在执行一遍!追加文件
以日志的形式来记录每个写操作,将Redis执行过的所有指令记录下来(读操作不记录),只许追加文件但不可以改写文件,redis启动之初会读取该文件重新构建数据,换言之,redis重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作(万一是大数据就很慢)

Aof保存的是appendonly.aof文件

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

一般的话,我们只要每秒保存即可

# appendfsync always
appendfsync everysec
# appendfsync no

是否要用append重写,默认no即可

# If you have latency problems turn this to "yes". Otherwise leave it as
# "no" that is the safest pick from the point of view of durability.
# 如果有延迟问题,请将此选项转换为“yes”。否则就让它保持原样 “no”从耐久性的角度来看,这是最安全的选择。
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100 # 重写的基准是100 增幅100%就重新覆盖一次
auto-aof-rewrite-min-size 64mb  # 最小值是64MB 

默认是不开启的,我们要把他改成yes来开启。我们只需要将appendoly 改为yes就开启了aof!
重启服务,shutdown 再登录就可以生效了。
然后我们set k1 v1 ,并且get k1 v1以下,输入cat appendonly.aof看看
redis-check-aof:aof文件修复工具,我们来测试下
如果这个aof文件有错误,这时候redis是启动不起来的,我们

需要修复这个aof文件

redis 给我们提供了一个工具 redis-check-aof --fix

1.shutdown exit,退出redis
2.删除datas/dump.rdb文件,因为里面有保存数据
3.vim appendonly.aof,肆意修改,并保存
4.尝试启动redis,登录cli的时候报错:
Could not connect to Redis at node1:6379: Connection refused
5.执行修复工具:redis-check-aof ../datas/appendonly.aof
6.需要你确认,输入y,修复成功。Successfully truncated AOF
7.再次执行,如果aof文件正常,就会发现数据都恢复了

重写规则说明

aof默认就是文件的无限追加,文件会越来越大!
在这里插入图片描述
​ 如果这个aof文件大于64M,太大了。fork一个新的进程来将文件进行重写!。,
优点和缺点!

appendonly no  #默认是不开启aof模式的,默认是使用rdb方式持久化的,在大部分所有的情况下,rdb完全够用!
appendfilename "appendonly.aof"  # 持久化的文件的名字

# appendfsync always  # 每次修改都会 sync 消耗性能
appendfsync everysec  # 每秒执行一次 sync,可能会丢失这一秒的数据
# appendfsync no      # 不执行 sync 操作系统自己同步数据,速度最快,但一般也不用。


优点:

1.每一次修复都同步,文件的完整会更好。
2.每秒同步一次,可能会丢失一秒的数据。
3.从不同步,效率最高的。
缺点:
1.相对于数据文件来说,aof远远大于rdb,修复的速度也比rdb慢!
Aof运行效率也要比rdb慢,所以我们redis默认的配置就是rdb持久化!
1、RDB持久化方式能够在指定的时间间隔内对你的数据进行快照存储
2、AOF持久化方式记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据,AOF命令以Redis协议追加保存每次写的操作到文件未尾,Redis还能对AOF文件进行后台重写,使得AOF文件的体积不至于过大。
3、只做缓存,如果你只希望你的数据在服务器运行的时候存在,你也可以不使用任何持久化
4、同时开启两种持久化方式
在这种情况下,当redis重启的时候会优先载入AOF文件来恢复原始的数据,因为在通常情况下AOF文件保存的数据集要比RDB文件保存的数据集要完整。
RDB的数据不实时,同时使用两者时服务器重启也只会找AOF文件,那要不要只使用AOF呢?作者建议不要,因为RDB更适合用于备份数据库(AOF在不断变化不好备份),快速重启,而且不会有AOF可能潜在的Bug,留着作为一个万一的手段。
5.性能建议
因为RDB文件只用作后备用途,建议只在Slave上持久化RDB文件,而且只要15分钟备份一次就够了,只保留 save9001这条规则。
如果EnableAOF,好处是在最恶劣情况下也只会丢失不超过两秒数据,启动脚本较简单只load自己的AOF文件就可以了,代价一是带来了持续的IO,二是AOF rewrite的最后将rewrite过程中产生的新数据写到新文件造成的阻塞几乎是不可避免的。只要硬盘许可,应该尽量减少AOF rewrite的频率,AOF重写的基础大小默认值64M太小了,可以设到5G以上,默认超过原大小100%大小重写可以改到适当的数值。
如果不Enable AOF,仅靠Master-Slave Repllcation 实现高可用性也可以,能省掉一大笔IO,也减少了rewrite时带来的系统波动。代价是如果Master/Slave同时倒掉(断电),会丢失十几分钟的数据,启动脚本也要比较两个Master/Slave中的RDB文件,载入较新的那个,微博就是这种架构。

Redis发布订阅

Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息。微信、微博、关注系统!
Redis客户端可以订阅任意数量的频道。

Redis主从复制

1主人 – 2仆从

概念
主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器。前者称为主节点(master/leader),后者称为从节点(slave/follower);数据的复制是单向的,只能由主节点到从节点。Master以写为主,Slave以读为主。

默认情况下,每台Redis服务器都是主节点(因为你还没有配置主从);

且一个主节点可以有多个从节点(或没有从节点),但一个从节点只能有一个主节点。

主从复制的作用主要包括

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

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

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

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

一般来说,要将Redis运用于工程项目中,只使用一台Redis是万万不能的(可能宕机,1主2从),原因如下:

1、从结构上,单个Redis服务器会发生单点故障,并且一台服务器需要处理所有的请求负载,压力较大

2、从容量上,单个Redis服务器内存容量有限,就算一台Redis服务器内存容量为256G,也不能将所有内存用作Redis存储内存

一般来说,单台Redis最大使用内存不应该超过20G。
主从复制,读写分离!80%的情况下都是在进行读操作!减缓服务器压力。架构中经常使用,最低1主2从。

只要在公司中,主从复制就是必须要用的,因为真实项目中不可能单机使用Redis!

环境配置(单机多集群)

只配置从库,不用配置主库。

node1:6379> info replication  # 查看当前库的信息
# Replication
role:master 		# 角色 master
connected_slaves:0  # 没有从机
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_o

复制3个配置文件,然后修改对应的信息

1、端口

2、pid名字

3、log文件名字

4、dump.rdg名字

# 步骤:
# 在一台虚拟机上,克隆3个窗口,复制3份conf文件

[root@node1 redis-3.2.8-bin]# cd /export/server/redis-3.2.8-bin
[root@node1 redis-3.2.8-bin]# cp redis.conf redis79.conf 
[root@node1 redis-3.2.8-bin]# cp redis.conf redis80.conf   
[root@node1 redis-3.2.8-bin]# cp redis.conf redis81.conf  

命令:vim redis79.conf
port 6379 # 84行  端口这里不用改 本身这个文件就是79端口  
daemonize yes # 128行 后台运行 要yes
pidfile /var/run/redis_6379.pid # 150行 这里pid file 也没问题
logfile "/export/server/redis-3.2.8-bin/logs/redis6379.log" # 163行 logfile加上后缀6379
dbfilename dump6379.rdb # 236行 dump.rdb改成 dump6379.rdb 否则会重名

# 至此第一个就保存好了。
# 第二个文件对应的改成6380和6381

修改完毕之后,在三个窗口分别启动我们3个redis服务器,可以通过进程查看。(注意我们是一台虚拟机的3个窗口上)

# 窗口1 
[root@node1 redis-3.2.8-bin]# redis-server redis79.conf 
[root@node1 redis-3.2.8-bin]# redis-cli -h node1 -p 6379

# 窗口2 
[root@node1 redis-3.2.8-bin]# redis-server redis80.conf 
[root@node1 redis-3.2.8-bin]# redis-cli -h node1 -p 6380

# 窗口3 
[root@node1 redis-3.2.8-bin]# redis-server redis81.conf 
[root@node1 redis-3.2.8-bin]# redis-cli -h node1 -p 6381

一主二从

默认情况下,每台redis服务器都是主节点。(因为你还没有配置主从)。

一般情况下,我们只配置从机就可以了。

认老大,一主(用79),二从(用80和81)

#  在从机中查看信息
node1:6380> SLAVEOF node1 6379 # SLAVEOF host 6379  找谁当自己的老大
OK
node1:6380> info replication 
# Replication
role:slave  # 当前角色的从机
master_host:node1  # 可以看到主机的信息
master_port:6379
master_link_status:up
master_last_io_seconds_ago:0
master_sync_in_progress:0
slave_repl_offset:15
slave_priority:100
slave_read_only:1
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

#  在主机中查看信息
node1:6379> info replication
# Replication
role:master
connected_slaves:2  # 多了从机的配置
slave0:ip=192.168.88.161,port=6380,state=online,offset=253,lag=1  
slave1:ip=192.168.88.161,port=6381,state=online,offset=253,lag=1
master_repl_offset:267
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:266

主机可以写;从机不能写只能读。

主机中的所有信息和数据,都会自动被从机保存。

缓存击穿和缓存雪崩

缓存击穿和缓存雪崩

redis散列

在这里插入图片描述

redis的有序集合

在这里插入图片描述

缓存击穿

黑客故意去请求缓存中不存在的数据,导致所有的请求都在数据库上面,导致数据库连接异常
解决方法:
1.采用互斥锁,当缓存中无数据或者失效,先去获取锁,然后再去请求数据库,没得到锁,休眠一段时间再去重试
2.采用异步更新策略,无论key是否取到值,都直接返回。value值中维护一个缓存失效时间,缓存如果过期,异步起一个线程去读数据库,更新缓存。需要做缓存预热(项目启动前,先加载缓存)操作。
3. 提供一个能迅速判断请求是否有效的拦截机制,比如,利用布隆过滤器,内部维护一系列合法有效的key。迅速判断出,请求所携带的Key是否合法有效。如果不合法,则直接返回。

缓存雪崩

即缓存同一时间大面积的失效,这个时候又来了一波请求,结果请求都怼到数据库上,从而导致数据库连接异常。
解决方案:

  1. 给缓存的失效时间,加上一个随机值,避免集体失效。
  2. 使用互斥锁,但是该方案吞吐量明显下降了。
  3. 双缓存。我们有两个缓存,缓存A和缓存B。缓存A的失效时间为20分钟,缓存B不设失效时间。自己做缓存预热操作。然后细分以下几个小点:
    I 从缓存A读数据库,有则直接返回
    II A没有数据,直接从B读数据,直接返回,并且异步启动一个更新线程。
    III 更新线程同时更新缓存A和缓存B。

redis和数据库双写一致性问题

最终一致性和强一致性
有强一致性要求的数据,不能放缓存。我们所做的一切,只能保证最终一致性。
首先,采取正确更新策略,先更新数据库,再删缓存。其次,因为可能存在删除缓存失败的问题,提供一个补偿措施即可,例如利用消息队列。

如何解决redis的并发竞争key问题

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值