02-Redis基础

一、Redis数据操作

1. 数据库操作
# 选择数据库,一共有16个库,i 的范围 0 ~ 15,默认为 0 号库
select i
# 查询数据库容量
dbsize
# 清除当前库
flushdb
# 清除所有库
flushall
2. 数据操作
1)Redis-Key
# 查询数据库中所有key
keys *
# 设置key
set key value
# 判断key是否存在,存在返回1,不存在返回0
exists key
# 移除当前库中的key到指定的库中,如下面的命令将key移动到库1中
move key 1
# 设置key的过期时间i,单位秒,返回-1表示没有过期时间,-2表示key不存在(可能已经过期)
expire key i
# 设置key的同时设置过期时间
set key value ex i
# 查询key的剩余有效原因
ttl key
# 查看key的类型
type key
2)String(字符串)
# 设置值
set key value
# 获取值
get key
# 给key追加字符串,若不存在,则新增一个
append key append_value
# 获取字符串长度
strlen key

######################################################################
#------------步长操作------------
# key自增/自减1
incr/decr key
# 设置增量i,即在 key的值 + i,当 i < 0时即为减量
incrby key i
# 设置减量i, 即key_value - i,当 
decrby key i

######################################################################
#---------字符串范围--------------
# 截取字符串[begin, end],0为第一个字符,-1表示最后一个字符
# 当end的值大于字符串的长度时,截取到末尾结束
# getrange key 0 -1 等价于 get key
getrange key begin end

#替换指定位置开始的字符串
#get key abcdef
#setrange key 1 xx  axxdef
setrange key index value

######################################################################
# setex(set with expire) 设置过期时间
# setnx(set if not exist)	不存在就设置(在分布式锁中会常常使用)
# 设置过期时间,等价于前面说的:set key value ex i
setex key i value
# 若key存在,则创建失败
setnx key value

######################################################################
mset		# 同时设置多个值【k1 v1 k2 v2......】
mget		# 同时获取多个值【mget k1 k2...】
msetnx		# 原子性操作,多个(key,value)中,若有一个已经存在,则该操作会失败,即使其它key不存在

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

# key的巧用:object:{id}:{filed}
127.0.0.1:6379> mset user:1:name zhangsan user:1:age 20
OK
127.0.0.1:6379> mget user:1:name user:1:age
1) "zhangsan"
2) "20"


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"


value除了是字符串,还可以是数字:

  • 计数器
  • 统计数量
3)List(列表)

redis中,可以把List当栈、队列、阻塞队列等使用

所有的List命令以L开头

######################################################################
127.0.0.1:6379> lpush list one		# 将一个或多个值放到列表头部(左边)
(integer) 1
127.0.0.1:6379> lpush list two
(integer) 2
127.0.0.1:6379> lpush list three
(integer) 3
127.0.0.1:6379> lrange list 0 -1
1) "three"
2) "two"
3) "one"
127.0.0.1:6379> lrange list 0 1		# 获取指定区间的值(从0开始)
1) "three"
2) "two"
127.0.0.1:6379> rpush list right
(integer) 4
127.0.0.1:6379> lrange list 0 -1	# 将一个或多个值插入到列表尾部(右边)
1) "three"
2) "two"
3) "one"
4) "right"

######################################################################
lpop
rpop

127.0.0.1:6379> lrange list 0 -1
1) "three"
2) "two"
3) "one"
4) "right"
127.0.0.1:6379> lpop list 
"three"
127.0.0.1:6379> lrange list 0 -1	# 移除列表第一个(头部、左边)值
1) "two"
2) "one"
3) "right"
127.0.0.1:6379> rpop list			# 移除错后一个(尾部、右边)值
"right"
127.0.0.1:6379> lrange list 0 -1
1) "two"
2) "one"

#移除key中的cnt个element元素
# cnt > 0	从头到尾删除cnt个element元素
# cnt < 0	从尾到头删除|cnt|个element元素
# cnt = =	删除全部值为element元素
lrem key cnt element	

######################################################################
lindex		# 根据下标获取值
	
127.0.0.1:6379> lindex list 1
"one"
127.0.0.1:6379> lindex list 0
"two"

######################################################################
llen

127.0.0.1:6379> lrange list 0 -1
1) "two"
2) "one"
127.0.0.1:6379> llen list		# 返回列表长度
(integer) 2

# 截取[begin,end]范围的值,并将其赋值给key
ltrim key begin end

# 移除列表最后一个元素,并放到新列表中
rpoplpush	# 6.2.0被弃用
# 可以使用lmove source destination right left来代替使用

127.0.0.1:6379> lrange list 0 -1
1) "-1"
2) "0"
3) "hello2"
4) "hello1"
5) "hello"
127.0.0.1:6379> rpoplpush list mylist	# 移除列表最后一个元素,并放到新列表中
"hello"	
127.0.0.1:6379> lrange list 0 -1	# 原列表中无被移除的元素
1) "-1"
2) "0"
3) "hello2"
4) "hello1"
127.0.0.1:6379> lrange mylist 0 -1	# 新列表中存在新值
1) "hello"

######################################################################
lset key index value	# 更新指定下标的值,若不存在指定下标,这报错

# element插入到指定的pivot的前/后面
linsert key before/after pivot element
4)Set(集合)

无序无重复集合

# 往Set集合中添加成员
sadd key member[...member]

# 查看指定key的成员
smembers key
# 等价于只有一个key的sinter交集操作
sinter key

# 判断集合key中是否存在成员member
sismember key member
# 判断集合key中的多个成员member是否存在
smismember key member [...member]

# 查询集合成员个数
scard key

# 移除key中指定的成员mem
srem key mem

# 随机选择cnt个成员,默认一个
srandmember key 【cnt】

# 随机删除成员
spop key

# 将指定的成员mem移动到另外的SET集合key2中
smove key1 key2 mem


# 数学集合
127.0.0.1:6379> sadd key1 a b c
(integer) 3
127.0.0.1:6379> sadd key2 c d e
(integer) 3
127.0.0.1:6379> sdiff key1 key2		# 差集(key1 - key2)
1) "b"
2) "a"
127.0.0.1:6379> sinter key1 key2	# 交集
1) "c"
127.0.0.1:6379> sunion key1 key2	# 并集
1) "b"
2) "a"
3) "c"
4) "d"
5) "e"


5)Hash(哈希)

即Map集合,<key, map>

本质与String没区别,唯一的差异是vlaue从一个String变成了 key value 的map对象

Hash更适合存储对象信息,key就是对象名,field就是对象属性,value就是属性对应的值。

###################################################################################
# 设置一个或多个hash,其中key是mykey,value是一个map对象<field, value>
hset mykey field value [...field value]
# 获取key中指定的字段值
hget key field
# 获取key中指定的多个字段值
hmget key field [...field]
# 获取key中所有字段
hgetall key
# 删除key中指定字段field
hdel key field [...field]

127.0.0.1:6379> hset mykey f1 v1 f2 czm f3 v3 f4 ob		# 设置hash
(integer) 4
127.0.0.1:6379> hget mykey f2		# 获取hash中指定field的value
"czm"
127.0.0.1:6379> hmget mykey f2 f4	# 获取hash中指定的多个field的value
1) "czm"
2) "ob"
127.0.0.1:6379> hgetall mykey		# 获取指定hash的所有field和value
1) "f1"
2) "v1"
3) "f2"
4) "czm"
5) "f3"
6) "v3"
7) "f4"
8) "ob"
127.0.0.1:6379> hdel mykey f3		# 删除一个指定field
(integer) 1
127.0.0.1:6379> hgetall mykey
1) "f1"
2) "v1"
3) "f2"
4) "czm"
5) "f4"
6) "ob"
127.0.0.1:6379> hdel mykey f2 f4	# 删除多个指定field
(integer) 2
127.0.0.1:6379> hgetall mykey
1) "f1"
2) "v1"


###################################################################################
# 获取hash长度
hlen key
# 获取hash中指定field的长度
hstrlen key field
# 判断hash中的指定字段是否存在
hexists key field

# 只获取所有的字段
hkeys key
#只获取所有的字段值
hvals key

###################################################################################
# 为key中的字段值加上增量increment,increment < 0时表示减量
hincrby key field increment
# 为key中的字段值减上减量incr,incr > 0 时表示增量

# 当key中存在指定的key时,不操作,不存在则新增
hsetnx key field value
6)ZSet/SortedSet(有序集合)

在Set的基础上新增了一个score,并根据器进行排序,默认升序

###################################################################################
127.0.0.1:6379> zadd salary 2500 xh		# 添加单个成员
(integer) 1
127.0.0.1:6379> zadd salary 2000 zs 500 ks		#添加对各成员
(integer) 2
127.0.0.1:6379> zrange salary 0 -1		# 查询所有成员
1) "ks"
2) "zs"
3) "xh"
127.0.0.1:6379> zrangebyscore salary -inf +inf	# 默认就是升序排序
1) "ks"
2) "zs"
3) "xh"
127.0.0.1:6379> zrevrange salary 0 -1		# zrevrange 从大到小排序
1) "xh"
2) "zs"
3) "ks"
127.0.0.1:6379> zrangebyscore salary -inf +inf withscores	# 查询所有成员,并带着score
1) "ks"
2) "500"
3) "zs"
4) "2000"
5) "xh"
6) "2500"

###################################################################################
# 移除集合中的成员
zrem key member
# 获取集合中的个数
zcard key
# 获取集合中指定范围[min, max]的成员个数
zcount key min max

二、Redis持久化

三、Redis发布订阅

Redis发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息。如微信、微博、各种关注系统!

redis客户端可以订阅任意数量的频道。

发布订阅消息图:

第一个:消息发送者

第二个:频道

第三个:消息订阅者

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Fp1KhW2F-1648989377753)(D:\Install\Typora\typora-user-images\image-20210611112300495.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RQTMdZLT-1648989377754)(D:\Install\Typora\typora-user-images\image-20210611112432368.png)]

命令

# 订阅给定的一个或多个频道的信息
subscribe channel [...channel]
# 将消息message发送到指定的频道channel
publish channel message
# 退订指定频道,若未指定,则退订所有频道
unsubscribe [channel ...]


# 订阅一个或多个符合给定模式的频道
psubscribe pattern [...pattern]
# 退订所有给定模式的频道
punsubscribe pattern


# 查看发布订阅系统状态
pubsub <subcommand>
# 列出当前活跃频道
pubsub channels

测试

订阅端:

127.0.0.1:6379> subscribe omaster		# 订阅消息一个频道 omaster
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "omaster"
3) (integer) 1
# 等待读取频道推送的消息
1) "message"		# 类型;消息
2) "omaster"		# 消息来源:哪个频道
3) "hello omaster"		# 消息的具体内容

1) "message"
2) "omaster"
3) "hello_redis"

发送端:

127.0.0.1:6379> publish omaster "hello omaster"		# 发布者发布消息到频道
(integer) 1
127.0.0.1:6379> publish omaster hello_redis		# 发布者发布消息到频道
(integer) 1

原理

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bj4DAY79-1648989377755)(D:\Install\Typora\typora-user-images\image-20210611134222969.png)]

使用场景

1、实时消息系统

2、实时聊天系统(频道当作聊天室,将信息发送给所有人)

3、订阅、关注等

稍复杂的系统使用消息队列中间件

四、Redis主从复制/哨兵模式

1. 主从复制(一主二从)

主从复制,读写分离,主机写,从机读,80%的情况下都是读操作,两从机,减缓主服务器压力。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cO0N5j9q-1648989377755)(D:\Install\Typora\typora-user-images\image-20210611144413707.png)]

环境配置

redis默认为主库,顾只需配置从库即可!

127.0.0.1:6379> info replication		# 查看当前库信息
# Replication
role:master		# 角色; masater
connected_slaves:0	# 从机数量
master_failover_state:no-failover
master_replid:65d7189800a0e326fe09a230d709e0c19efde02c
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

将配置文件辅助多份(想配几个从机就复制几份),修改相应配置:

1、端口

2、pid名称

3、log文件名

4、dump.rdb文件名

5、若是主机配置了密码,则还需配置主机密码:masterauth password ,pasword为主机的密码

==默认情况下,每台Redis服务器都是主节点;==一般情况下配置从机就行。

127.0.0.1:6380> slaveof 127.0.0.1 6379		# slaveof host port 设置主机ip和端口
OK
127.0.0.1:6380> info replication
# Replication
role:slave		# 当前角色:从机
master_host:127.0.0.1	# 主机相关信息
master_port:6379
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_repl_offset:14
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:eb4bc712d6f547a5cd353a7bc1d5d297199320ac
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:14
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:14


#主机中信息
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:1		# 从机数量
slave0:ip=127.0.0.1,port=6380,state=online,offset=14,lag=1	# 从机信息
master_failover_state:no-failover
master_replid:eb4bc712d6f547a5cd353a7bc1d5d297199320ac
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:14
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:14

127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=6380,state=online,offset=1602121,lag=1
slave1:ip=::1,port=6381,state=online,offset=1602121,lag=1
master_failover_state:no-failover
master_replid:eb4bc712d6f547a5cd353a7bc1d5d297199320ac
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:1602121
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:553546
repl_backlog_histlen:1048576

实际环境中,通过配置文件配置实现永久配置,使用命令配置是暂时的。

细节

主机可以写,也可以读,从机不能写,只能读。

设置为从机后,从机会自动将主机中所有数据复制过来,这是全量复制

之后,主机写入新的数据,从机会继续更新这些数据,这叫==增量复制

主机断开连接,如何操作?

可以使用slaveof no one将从机变为主机,其他从机连到该主机即可。

2. 哨兵模式

测试

1、配置哨兵配置文件sentinel.conf

#                监控名称  监控的主机 端口 主机宕机后是否投票产生主机
sentinel monitor myredis 127.0.0.1 6379 1

2、启动

redis-sentinel conf/sentinel.conf

[root@172-18-232-233 bin]# redis-sentinel conf/sentinel.conf 
11605:X 11 Jun 2021 17:31:47.766 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
11605:X 11 Jun 2021 17:31:47.766 # Redis version=6.2.4, bits=64, commit=00000000, modified=0, pid=11605, just started
11605:X 11 Jun 2021 17:31:47.766 # Configuration loaded
11605:X 11 Jun 2021 17:31:47.768 * monotonic clock: POSIX clock_gettime
                _._                                                  
           _.-``__ ''-._                                             
      _.-``    `.  `_.  ''-._           Redis 6.2.4 (00000000/0) 64 bit
  .-`` .-```.  ```\/    _.,_ ''-._                                  
 (    '      ,       .-`  | `,    )     Running in sentinel mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 26379
 |    `-._   `._    /     _.-'    |     PID: 11605
  `-._    `-._  `-./  _.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |           https://redis.io       
  `-._    `-._`-.__.-'_.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |                                  
  `-._    `-._`-.__.-'_.-'    _.-'                                   
      `-._    `-.__.-'    _.-'                                       
          `-._        _.-'                                           
              `-.__.-'                                               

11605:X 11 Jun 2021 17:31:47.769 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
11605:X 11 Jun 2021 17:31:47.787 # Sentinel ID is d0806228171b60b3bb19912699597aeb91e7ff49
11605:X 11 Jun 2021 17:31:47.787 # +monitor master myredis 127.0.0.1 6379 quorum 1
11605:X 11 Jun 2021 17:31:47.788 * +slave slave 127.0.0.1:6380 127.0.0.1 6380 @ myredis 127.0.0.1 6379
11605:X 11 Jun 2021 17:31:47.797 * +slave slave [::1]:6381 ::1 6381 @ myredis 127.0.0.1 6379

3、主机宕机后,哨兵投票从从机中选出一个主机

11605:X 11 Jun 2021 17:32:47.106 # +sdown master myredis 127.0.0.1 6379
11605:X 11 Jun 2021 17:32:47.106 # +odown master myredis 127.0.0.1 6379 #quorum 1/1
11605:X 11 Jun 2021 17:32:47.106 # +new-epoch 1
11605:X 11 Jun 2021 17:32:47.106 # +try-failover master myredis 127.0.0.1 6379
11605:X 11 Jun 2021 17:32:47.115 # +vote-for-leader d0806228171b60b3bb19912699597aeb91e7ff49 1
11605:X 11 Jun 2021 17:32:47.115 # +elected-leader master myredis 127.0.0.1 6379
11605:X 11 Jun 2021 17:32:47.115 # +failover-state-select-slave master myredis 127.0.0.1 6379
11605:X 11 Jun 2021 17:32:47.174 # +selected-slave slave 127.0.0.1:6380 127.0.0.1 6380 @ myredis 127.0.0.1 6379
11605:X 11 Jun 2021 17:32:47.174 * +failover-state-send-slaveof-noone slave 127.0.0.1:6380 127.0.0.1 6380 @ myredis 127.0.0.1 6379
11605:X 11 Jun 2021 17:32:47.240 * +failover-state-wait-promotion slave 127.0.0.1:6380 127.0.0.1 6380 @ myredis 127.0.0.1 6379
11605:X 11 Jun 2021 17:32:48.269 # +promoted-slave slave 127.0.0.1:6380 127.0.0.1 6380 @ myredis 127.0.0.1 6379
11605:X 11 Jun 2021 17:32:48.269 # +failover-state-reconf-slaves master myredis 127.0.0.1 6379
11605:X 11 Jun 2021 17:32:48.270 * +slave-reconf-sent slave [::1]:6381 ::1 6381 @ myredis 127.0.0.1 6379
11605:X 11 Jun 2021 17:32:48.286 * +slave-reconf-inprog slave [::1]:6381 ::1 6381 @ myredis 127.0.0.1 6379
11605:X 11 Jun 2021 17:32:49.323 * +slave-reconf-done slave [::1]:6381 ::1 6381 @ myredis 127.0.0.1 6379
11605:X 11 Jun 2021 17:32:49.413 # +failover-end master myredis 127.0.0.1 6379
11605:X 11 Jun 2021 17:32:49.413 # +switch-master myredis 127.0.0.1 6379 127.0.0.1 6380
11605:X 11 Jun 2021 17:32:49.414 * +slave slave [::1]:6381 ::1 6381 @ myredis 127.0.0.1 6380
11605:X 11 Jun 2021 17:32:49.414 * +slave slave 127.0.0.1:6379 127.0.0.1 6379 @ myredis 127.0.0.1 6380
11605:X 11 Jun 2021 17:32:50.002 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ myredis 127.0.0.1 6380
11605:X 11 Jun 2021 17:33:19.421 # +sdown slave 127.0.0.1:6379 127.0.0.1 6379 @ myredis 127.0.0.1 6380

主机恢复后,则自动为新主机的从机。

哨兵模式

优点:

1、哨兵集群,基于主从复制,拥有全部的主从配置

2、主从自动切换,故障可以转移、系统可用性强

3、哨兵模式是主从配置的升级,从手动到自动,健壮性好

缺点:

1、Redis不方便在线扩容,集群数量达到上限,扩容十分麻烦

2、哨兵模式的配置很复杂

哨兵模式配置文件

五、Redis缓存穿透、击穿、雪崩

参考文章:Redis缓存穿透、击穿、雪崩详解

1. 缓存穿透(查不到)

概念

​ 缓存穿透的概念很简单,用户想要查询一个数据,发现redis内存数据库没有,也就是缓存没有命中,于是向持久层数据库查询。发现也没有,于是本次查询失败。当用户很多的时候,缓存都没有命中,于是都去请求了持久层数据库。这会给持久层数据库造成很大的压力,这时候就相当于出现了缓存穿透。

解决方案

1、布隆过滤器

首先也是对所有可能查询的参数以hash形式存储,当用户想要查询的时候,使用布隆过滤器发现不在集合中,就直接丢弃,不再对持久层查询。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-usppl0gV-1648989377755)(D:\Install\Typora\typora-user-images\image-20210611205917042.png)]

2、缓存空对象

当存储层不命中后,即使返回的空对象也将其缓存起来,同时会设置一个过期时间,之后再访问这个数据将会从缓存中获取,保护了后端数据源;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2W1ZeeCP-1648989377756)(D:\Install\Typora\typora-user-images\image-20210611205930655.png)]

存在的两个问题:

1)如果空值能够被缓存起来,这就意味着缓存需要更多的空间存储更多的键,因为这当中可能会有很多的空值的键;

2)即使对空值设置了过期时间,还是会存在缓存层和存储层的数据会有一段时间窗口的不一致,这对于需要保持一致性的业务会有影响。

2. 缓存击穿(量太大,缓存过期)

概念

缓存击穿,是指一个key非常热点,在不停的扛着大并发,大并发集中对这一个点进行访问,当这个key在失效的瞬间,持续的大并发就穿破缓存,直接请求数据库,就像在一个屏障上凿开了一个洞。

解决方案

1、热点数据永不过期

比如我们可以将某个 key 的缓存时间设置为 25 小时,然后后台有个 JOB 每隔 24 小时就去批量刷新一下热点数据。就可以解决这个问题了。

2、使用互斥锁

容易影响吞吐量,大部分项目设置热点 key 永不过期就妥妥的了。

3. 缓存雪崩

概念

在某个时间段,大量缓存数据到期失效,导致大量请求到数据库,可以理解这个时间段内缓存宕机失效。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rgvNMLtG-1648989377756)(D:\Install\Typora\typora-user-images\image-20210611211303071.png)]

解决方案

1、 Redis高可用

这个思想的含义是,既然redis有可能挂掉,那我多增设几台redis,这样一台挂掉之后其他的还可以继续工作,其实就是搭建的集群。

多提供几台服务器,做好集群。(异地多活)

2、限流降级

这个解决方案的思想是,在缓存失效后,通过加锁或者队列来控制读数据库写缓存的线程数量。比如对某个key只允许一个线程查询数据和写缓存,其他线程等待。

3、数据预热

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

4、数据永不过期

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值