启动and连接

启动 用的是配置文件启动

redis-server .../redis.conf

redis-cli -p 6379

[root@LJT redis]# redis-server redis.conf
[root@LJT redis]# redis-cli -p 6379
127.0.0.1:6379> exit
[root@LJT redis]# pwd
/www/server/redis 用的是宝塔,默认在www用户下

关机

SHUTDOWN

JRedis

<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.2.0</version>
</dependency>

宝塔

我用的aliyun的www 宝塔的 redis 位置

cd /www/server/redis

Redis.conf

单位
配置文件对大小写不敏感
# 1k => 1000 bytes
# 1kb => 1024 bytes
# 1m => 1000000 bytes
# 1mb => 1024*1024 bytes
# 1g => 1000000000 bytes
# 1gb => 1024*1024*1024 bytes …………
包含
# include /path/to/local.conf
# include /path/to/other.conf …………
bind 127.0.0.1 绑定的ip protected-mode yes 保护模式 port 6379 端口 ################################# GENERAL ##################################### daemonize yes 守护进程方式运行,默认no pidfile /www/server/redis/redis.pid 如果以后台方式运行,要指定pid # Specify the server verbosity level.
# This can be one of:
# debug (a lot of information, useful for development/testing)
# verbose (many rarely useful info, but not a mess like the debug level)
# notice (moderately verbose, what you want in production probably)默认,生产环境
# warning (only very important / critical messages are logged)
loglevel notice
logfile "/www/server/redis/redis.log" 位置 # dbid is a number between 0 and 'databases'-1
databases 16 默认16个数据库 持久化,redis是内存数据库,断电即失
save 900 1 如果900s内至少有一个key修改,进行持久化操作
save 300 10
save 60 10000 stop-writes-on-bgsave-error yes 持久化出错,是否继续工作 rdbcompression yes 是否压缩 rdb 文件,要消耗一定的cpu资源 rdbchecksum yes 保存 rdb 文件 是否要校验 dbfilename dump.rdb rdb 文件保存目录 ################################# REPLICATION ################################# ################################# SECURITY #################################
# requirepass foobared 设置密码 ################################### CLIENTS ####################################
# maxclients 10000 最大的连接数 ############################## MEMORY MANAGEMENT################################
# maxmemory <bytes> 最大的容量 # maxmemory-policy noeviction 内存满了怎么处理 ############################## APPEND ONLY MODE ###############################
aof的配置 appendonly no 默认不开启,默认rdb够用了 appendfilename "appendonly.aof" 持久化的文件的名字 # appendfsync always 每次都要 sync
appendfsync everysec 每秒执行一次 sync 可能会丢失一秒的数据
# appendfsync no 不执行,操作系统自己同步数据

RDB

Redis DataBase redis 的持久化

保存的是dump.rdb

持久化,redis是内存数据库,断电即失
save 900 1 如果900s内至少有一个key修改,进行持久化操作
save 300 10
save 60 10000 stop-writes-on-bgsave-error yes 持久化出错,是否继续工作 rdbcompression yes 是否压缩 rdb 文件,要消耗一定的cpu资源 rdbchecksum yes 保存 rdb 文件 是否要校验 dbfilename dump.rdb rdb 文件保存目录
  1. save规则满足了 就自动的执行了
  2. 执行flushall
  3. 退出redis

这个时候是会有 dump.rdb。

怎么恢复RDB文件

只要放到redis的启动目录就可以了,redis会自动检查。

优点:

  1. 适合大规模的数据恢复
  2. 对数据的完整性要求不高

缺点:

  1. 需要一定的时间间隔
  2. fork的时候会占用一定的内存空间

AOF(Append Only File)

将我们的所有的操作记录下来。

以日志的形式来记录每个写操作,将Redis执行过的所有指令记录下来(读操作不记录) , 只许追加文件但不可以改写文件, redis启动之初会读取该文件重新构建数据,换言之, redis重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复。

Aof保存的是appendonly.aof文件

############################## APPEND ONLY MODE ###############################
aof的配置 appendonly no 默认不开启,默认rdb够用了,这里改为yes就是开启了,重启redis就生效了 appendfilename "appendonly.aof" 持久化的文件的名字 # appendfsync always 每次都要 sync
appendfsync everysec 每秒执行一次 sync 可能会丢失一秒的数据
# appendfsync no 不执行,操作系统自己同步数据

vim 这个 appendonly.aof 文件,就可以看到自己的所有的操作

以日志级别记录我们的所有的写操作。

redis -check-aof

这个是会检查你的 appendonly.aof 。

redis -check-aof  --fix appendonly.aof

可以用

ps -ef|grep redis

看自己的reids是否开启了。

按照默认的配置,如果aof的文件大于64m,太大了,redis 会 fork 一个新的进程将我们的文件进行重写。

aof 默认的就是文件的无限追加。

优点

  1. 每一次的修改都同步,文件的完整性会更好
  2. 每秒同步一个,可能会丢失最后一秒的数据
  3. 从不同步,效率最高

缺点

  1. 相对于数据文件来说,aof 远大于 rdb,会很慢,运行效率也更低

扩展:

RDB 持久化可以在指定的时间间隔内生成数据集的时间点快照(point-in-time snapshot)。

AOF 持久化记录服务器执行的所有写操作命令,并在服务器启动时,通过重新执行这些命令来还原数据集。

AOF 文件中的命令全部以 Redis 协议的格式来保存,新命令会被追加到文件的末尾。

Redis 还可以在后台对 AOF 文件进行重写(rewrite),使得 AOF 文件的体积不会超出保存数据集状态所需的实际大小。

Redis 还可以同时使用 AOF 持久化和 RDB 持久化。

在这种情况下, 当 Redis 重启时, 它会优先使用 AOF 文件来还原数据集, 因为 AOF 文件保存的数据集通常比 RDB 文件所保存的数据集更完整。你甚至可以关闭持久化功能,让数据只在服务器运行时存在。

发布和订阅

通信 队列 发送者 ======== 订阅者

redis也是一种消息通信模式

redis可以订阅任意数量的频道

操作例子:

127.0.0.1:6379> SUBSCRIBE zwtjava
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "zwtjava"
3) (integer) 1
1) "message"
2) "zwtjava"
3) "hello zwt"
1) "message"
2) "zwtjava"
3) "hello redis"
127.0.0.1:6379> PUBLISH zwtjava "hello zwt"
(integer) 1
127.0.0.1:6379> PUBLISH zwtjava "hello redis"
(integer) 1
127.0.0.1:6379>

主从复制

概念

主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器。

前者称为主节点(Master/Leader),后者称为从节点(Slave/Follower), 数据的复制是单向的!只能由主节点复制到从节点(主节点以写为主、从节点以读为主)。

默认情况下,每台Redis服务器都是主节点,一个主节点可以有0个或者多个从节点,但每个从节点只能由一个主节点。

作用

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

  2. 故障恢复:当主节点故障时,从节点可以暂时替代主节点提供服务,是一种服务冗余的方式

  3. 负载均衡:在主从复制的基础上,配合读写分离,由主节点进行写操作,从节点进行读操作,分担服务器的负载;尤其是在多读少写的场景下,通过多个从节点分担负载,提高并发量。

  4. 高可用基石:主从复制还是哨兵和集群能够实施的基础。

为什么使用集群?

  1. 单台服务器难以负载大量的请求
  2. 单台服务器故障率高,系统崩坏概率大
  3. 单台服务器内存容量有限

查看当前库的信息:

[root@LJT redis]# redis-server redis.conf
[root@LJT redis]# redis-cli -p 6379
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:0
master_failover_state:no-failover
master_replid:cf011df27ae3fb7062185a64f1a1b6f660d61b10
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

一主二从

配置伪集群:

复制配置文件

[root@LJT redis]# cp redis.conf redis79.conf
[root@LJT redis]# cp redis.conf redis80.conf
[root@LJT redis]# cp redis.conf redis81.conf [root@LJT redis]# ll
total 436
-rw-rw-r-- 1 redis redis 28118 Jun 1 22:03 00-RELEASENOTES
-rw-rw-r-- 1 redis redis 51 Jun 1 22:03 BUGS
-rw-rw-r-- 1 redis redis 5026 Jun 1 22:03 CONDUCT
-rw-rw-r-- 1 redis redis 3384 Jun 1 22:03 CONTRIBUTING
-rw-rw-r-- 1 redis redis 1487 Jun 1 22:03 COPYING
drwxrwxr-x 7 redis redis 4096 Jul 12 10:40 deps
-rw-r--r-- 1 root root 104 Jul 21 16:30 dump.rdb
-rw-rw-r-- 1 redis redis 11 Jun 1 22:03 INSTALL
-rw-rw-r-- 1 redis redis 151 Jun 1 22:03 Makefile
-rw-rw-r-- 1 redis redis 6888 Jun 1 22:03 MANIFESTO
-rw-rw-r-- 1 redis redis 21567 Jun 1 22:03 README.md -rw-r--r-- 1 root root 61859 Jul 21 16:32 redis79.conf
-rw-r--r-- 1 root root 61859 Jul 21 16:32 redis80.conf
-rw-r--r-- 1 root root 61859 Jul 21 16:32 redis81.conf
-rw-rw-r-- 1 redis redis 61859 Jul 21 10:50 redis.conf -rw-r--r-- 1 redis redis 15057 Jul 21 16:30 redis.log
-rwxrwxr-x 1 redis redis 275 Jun 1 22:03 runtest
-rwxrwxr-x 1 redis redis 279 Jun 1 22:03 runtest-cluster
-rwxrwxr-x 1 redis redis 1046 Jun 1 22:03 runtest-moduleapi
-rwxrwxr-x 1 redis redis 281 Jun 1 22:03 runtest-sentinel
-rw-rw-r-- 1 redis redis 13768 Jun 1 22:03 sentinel.conf
drwxrwxr-x 3 redis redis 12288 Jul 12 17:32 src
-rw-r--r-- 1 root root 5 Jul 12 10:42 start.pl
drwxrwxr-x 11 redis redis 4096 Jun 1 22:03 tests
-rw-rw-r-- 1 redis redis 3055 Jun 1 22:03 TLS.md
drwxrwxr-x 9 redis redis 4096 Jun 1 22:03 utils
-rw-r--r-- 1 root root 5 Jul 12 10:45 version_check.pl
-rw-r--r-- 1 root root 6 Jul 12 10:42 version.pl
[root@LJT redis]#

修改对应的配置文件

-rw-r--r--  1 root  root  61859 Jul 21 16:32 redis80.conf

port 6380

daemonize yes		开启服务

logfile "/www/server/redis/redis80.log"

dbfilename dump80.rdb

大概就是这样几个地方

连接三台主机,都是master,默认都是master,我们一般只用配置从机就可以。

主(79)从(80,81)

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

SLAVEOF 127.0.0.1 6379

通过这个命令配置主从关系

127.0.0.1:6380> SLAVEOF 127.0.0.1 6379
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:5
master_sync_in_progress:0
slave_repl_offset:0
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:4c97ee0b19fef1a3f8e4f2f97ec15b20c01d61b1
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:0
127.0.0.1:6380>

这是用的命令实现的,不是永久的,永久的需要再配置文件里面实现,

配置中实现这个即可。

# replicaof <masterip> <masterport>

# masterauth <master-password>

细节了解:

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

127.0.0.1:6379> set k1 v1
OK
127.0.0.1:6379> get k1
"v1"
127.0.0.1:6379> 127.0.0.1:6380> get k1
"v1"
127.0.0.1:6380>
127.0.0.1:6380> set k2 v2
(error) READONLY You can't write against a read only replica.

测试:主机断开,从机依旧连接,但是没有写操作。

​ 主机回来,恢复。

​ 从机断了,主机的写操作ok,从机回来,不可以拿到掉线的值。

复制原理

通过测试管观察原理:

Slave启动成功连接到master后会发送一个sync命令

Master接到命令,启动后台的存盘进程,同时收集所有接收到的用于修改数据集命令,在后台进程执行完毕之后, master将传送整个数据文件到slave ,并完成一次完全同步。

全量复制:而slave服务在接收到数据库文件数据后,将其存盘并加载到内存中。

增量复制: Master继续将新的所有收集到的修改命令依次传给slave ,完成同步
但是只要是重新连接master , 一次完全同步(全量复制)将被自动执行。

宕机后的手动配置主机

主节点断开,info replication

127.0.0.1:6380> SLAVEOF no one
OK
127.0.0.1:6380> info replication
# Replication
role:master
connected_slaves:0
master_failover_state:no-failover
master_replid:7fc61819c4dd84b2476cc55cf827ab854177bdbf
master_replid2:4c97ee0b19fef1a3f8e4f2f97ec15b20c01d61b1
master_repl_offset:3538
second_repl_offset:3539
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:3538
127.0.0.1:6380>

如果这个时候主机ok了,回来了,需要再配置。

哨兵模式

自动版的“选老大“。

主从切换技术的方法是:

当主服务器宕机后,需要手动把一台从服务器切换为主服务器,这就需要人工干预,费事费力,还会造成一段时间内服务不可用。

这不是一种推荐的方式,更多时候,我们优先考虑哨兵模式

Redis从2.8开始正式提供 了Sentinel (哨兵)架构来解决这个问题。

谋朝篡位的自动版,能够后台监控主机是否故障,如果故障了根据投票数自动将从库转换为主库

哨兵模式是一种特殊的模式,首先Redis提供了哨兵的命令,哨兵是一个独立的进程,作为进程,它会独立运行。

其原理是哨兵通过发送命令,等待Redis服务器响应,从而监控运行的多个Redis实例。

然而一个哨兵进程对Redis服务器进行监控,可能会出现问题,为此,我们可以使用多个哨兵进行监控。

各个哨兵之间还会进行监控,这样就形成了多哨兵模式

假设主服务器宕机,哨兵1先检测到这个结果,系统并不会马上进行failover过程,仅仅是哨兵1主观的认为主服务器不可用,这个现象成为主观下线

当后面的哨兵也检测到主服务器不可用,并且数量达到一定值时,那么哨兵之间就会进行一次投票 ,投票的结果由一个哨兵发起,进行failover[故障转移]操作。

切换成功后,就会通过发布订阅模式,让各个哨兵把自己监控的从服务器实现切换主机,这个过程称为客观下线

测试:

目前是一主二从。

配置哨兵文件

sentinel monitor mymaster 127.0.0.1 6379 1

后面的这个数字1 ,代表主机挂了,slave投票看让谁接替成为主机,票数最多的就会成为主机!

启动哨兵

[root@LJT redis]# redis-sentinel sentinel79.conf
20183:X 21 Jul 2021 22:41:55.113 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
20183:X 21 Jul 2021 22:41:55.113 # Redis version=6.2.4, bits=64, commit=00000000, modified=0, pid=20183, just started
20183:X 21 Jul 2021 22:41:55.113 # Configuration loaded
20183:X 21 Jul 2021 22:41:55.114 * monotonic clock: POSIX clock_gettime
_._
_.-``__ ''-._
_.-`` `. `_. ''-._ Redis 6.2.4 (00000000/0) 64 bit
.-`` .-```. ```\/ _.,_ ''-._
( ' , .-` | `, ) Running in sentinel mode
|`-._`-...-` __...-.``-._|'` _.-'| Port: 26379
| `-._ `._ / _.-' | PID: 20183
`-._ `-._ `-./ _.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' | https://redis.io
`-._ `-._`-.__.-'_.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' |
`-._ `-._`-.__.-'_.-' _.-'
`-._ `-.__.-' _.-'
`-._ _.-'
`-.__.-' 20183:X 21 Jul 2021 22:41:55.120 # Sentinel ID is 236bea779a3b0737574dc5022c37d17d825b0ccb
20183:X 21 Jul 2021 22:41:55.120 # +monitor master mymaster 127.0.0.1 6379
quorum 1 #有一票 #它的俩个从节点
20183:X 21 Jul 2021 22:41:55.120 * +slave slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6379
20183:X 21 Jul 2021 22:41:55.125 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6379 #关闭主节点后的日志 failover selected 20183:X 21 Jul 2021 22:42:49.558 # +sdown master mymaster 127.0.0.1 6379
20183:X 21 Jul 2021 22:42:49.558 # +odown master mymaster 127.0.0.1 6379 #quorum 1/1
20183:X 21 Jul 2021 22:42:49.558 # +new-epoch 1 20183:X 21 Jul 2021 22:42:49.558 # +try-failover master mymaster 127.0.0.1 6379
20183:X 21 Jul 2021 22:42:49.565 # +vote-for-leader 236bea779a3b0737574dc5022c37d17d825b0ccb 1
20183:X 21 Jul 2021 22:42:49.565 # +elected-leader master mymaster 127.0.0.1 6379
20183:X 21 Jul 2021 22:42:49.565 # +failover-state-select-slave master mymaster 127.0.0.1 6379 20183:X 21 Jul 2021 22:42:49.637 # +selected-slave slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6379
20183:X 21 Jul 2021 22:42:49.637 * +failover-state-send-slaveof-noone slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6379
20183:X 21 Jul 2021 22:42:49.720 * +failover-state-wait-promotion slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6379
20183:X 21 Jul 2021 22:42:50.053 # +promoted-slave slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6379
20183:X 21 Jul 2021 22:42:50.053 # +failover-state-reconf-slaves master mymaster 127.0.0.1 6379
20183:X 21 Jul 2021 22:42:50.113 * +slave-reconf-sent slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6379
20183:X 21 Jul 2021 22:42:51.102 * +slave-reconf-inprog slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6379
20183:X 21 Jul 2021 22:42:51.102 * +slave-reconf-done slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6379
20183:X 21 Jul 2021 22:42:51.157 # +failover-end master mymaster 127.0.0.1 6379
20183:X 21 Jul 2021 22:42:51.157 # +switch-master mymaster 127.0.0.1 6379 127.0.0.1 6380
20183:X 21 Jul 2021 22:42:51.158 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6380
20183:X 21 Jul 2021 22:42:51.158 * +slave slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6380
20183:X 21 Jul 2021 22:43:21.239 # +sdown slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6380 #再测试,果然 master 是 6380 127.0.0.1:6380> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=127.0.0.1,port=6381,state=online,offset=9076,lag=0
master_failover_state:no-failover
master_replid:6d563979b4c421fde3bc7a8996b88d2f02f060ee
master_replid2:1645d3e978dea3fea45f2f5219077322693e61a3
master_repl_offset:9076
second_repl_offset:1585
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:9076
127.0.0.1:6380> #6379再次上线 20183:X 21 Jul 2021 22:42:51.157 # +switch-master mymaster 127.0.0.1 6379 127.0.0.1 6380
20183:X 21 Jul 2021 22:42:51.158 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6380
20183:X 21 Jul 2021 22:42:51.158 * +slave slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6380
20183:X 21 Jul 2021 22:43:21.239 # +sdown slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6380
20183:X 21 Jul 2021 22:47:03.632 # -sdown slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6380
20183:X 21 Jul 2021 22:47:13.578 * +convert-to-slave slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6380 #发现现在没有用,还是6380统治天下

**

优点:**

1、哨兵集群,基于主从复制模式,所有的主从配置优点,它全有

2、主从可以切换,故障可以转移,系统的可用性就会更好

3、哨兵模式就是主从模式的升级,手动到自动,更加健壮!

缺点:

1、Redis 不好啊在线扩容的,集群容量- -旦到达上限,在线扩容就十分麻烦!

2、实现哨兵模式的配置其实是很麻烦的,里面有很多选择!

Redis 缓存 穿透 和 雪崩(面试高频,工作常用)

Redis缓存的使用,极大的提升了应用程序的性能和效率,特别是数据查询方面。

但同时,它也带来了一些问题。

其中,最要害的问题,就是数据的一致性问题,从严格意义上讲,这个问题无解。

如果对数据的一致性要求很高,那么就不能使用缓存。

另外的一些典型问题就是,缓存穿透、缓存雪崩和缓存击穿。

缓存穿透

缓存穿透的概念很简单,用户想要查询一个数据发现redis内存数据库没有,

也就是缓存没有命中,于是向持久层数据库查询。

发现也没有,于是本次查询失败。当用户很多的时候,缓存都没有命中,于是都去请求了持久层数据库。

这会给持久层数据库造成很大的压力,这时候就相当于出现了缓存穿透。

解决方案

布隆过滤器

是一种数据结构,对所有可能查询的参数以hash形式存储,在控制层先进行校验,不符合则丢弃,从而避免了对底层存储系统的查询压力。

缓存空对象

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

但是这种方法会存在两个问题:

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

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

缓存雪崩

缓存雪崩,是指在某一一个时间段,缓存集中过期失效。

产生雪崩的原因之一,比如在写本文的时候,马上就要到双十二零点,很快就会迎来-波抢购,这波商品时间比较集中的放入了缓存,假设缓存-个小时。那么到了凌晨一点钟的时候 ,这批商品的缓存就都过期了。而对这批商品的访问查询,都落到了数据库上,对于数据库而言,就会产生周期性的压力波峰。于是所有的请求都会达到存储层,存储层的调用量会暴增,造成存储层也会挂掉的情况。

解决方案

redis高可用

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

限流降级

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

数据预热

数据加热的含义就是在正式部署之前,我先把可能的数据先预先访问一遍,这样部分可能大量访问的数据就会加载到缓存中。

在即将发生大并发访问前手动触发加载缓存不同的key ,设置不同的过期时间,让缓存失效的时间点尽量均匀。

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

例如:微博热搜

解决方案

设置热点不过期

加互斥锁

Redis-初见的更多相关文章

  1. 初见Redis

    Redis是什么,有什么特点和优势 Redis是一个开源用C语言编写的,基于内存,可以持久化,高性能的key-value数据库,并提供多种语言的API. 它也被称为数据结构服务器,因为值(value) ...

  2. MongoDB 初见指南

    技术若只如初见,那么还会踩坑么? 在系统引入 MongoDB 也有几年了,一开始是因为 MySQL 中有单表记录增长太快(每天几千万条吧)容易拖慢 MySQL 的主从复制.而这类数据增长迅速的流水表, ...

  3. 4、redis 分布式锁

    1. 前言 关于分布式锁的实现,目前常用的方案有以下三类: 数据库乐观锁: 基于分布式缓存实现的锁服务,典型代表有 Redis 和基于 Redis 的 RedLock: 基于分布式一致性算法实现的锁服 ...

  4. 【需要重新维护】Redis笔记20170811视频

    很多内容都是抄的,个人记录 1.windows下初见 安装 进入目录 修改配置文件(暂时使用默认,未配置环境变量) 目录下:redis-server.exe启动服务 新建命令提示符,目录下,redis ...

  5. 使用redis构建可靠分布式锁

    关于分布式锁的概念,具体实现方式,直接参阅下面两个帖子,这里就不多介绍了. 分布式锁的多种实现方式 分布式锁总结 对于分布式锁的几种实现方式的优劣,这里再列举下 1. 数据库实现方式 优点:易理解 缺 ...

  6. Ignite性能测试以及对redis的对比

    测试方法 为了对Ignite做一个基本了解,做了一个性能测试,测试方法也比较简单主要是针对client模式,因为这种方法和使用redis的方式特别像.测试方法很简单主要是下面几点: 不作参数优化,默认 ...

  7. mac osx 安装redis扩展

    1 php -v查看php版本 2 brew search php|grep redis 搜索对应的redis   ps:如果没有brew 就根据http://brew.sh安装 3 brew ins ...

  8. Redis/HBase/Tair比较

    KV系统对比表 对比维度 Redis Redis Cluster Medis Hbase Tair 访问模式    支持Value大小 理论上不超过1GB(建议不超过1MB) 理论上可配置(默认配置1 ...

  9. Redis数据库

    Redis是k-v型数据库的典范,设计思想及数据结构实现都值得学习. 1.数据类型 value支持五种数据类型:1.字符串(strings)2.字符串列表(lists)3.字符串集合(sets)4.有 ...

  10. redis 学习笔记(2)

    redis-cluster 简介 redis-cluster是一个分布式.容错的redis实现,redis-cluster通过将各个单独的redis实例通过特定的协议连接到一起实现了分布式.集群化的目 ...

随机推荐

  1. Android NDK 直播推流与引流

    本篇介绍一下直播技术中推流与引流的简单实现. 1.流媒体服务器测试 首先利用快直播 app (其他支持 RTMP 推流与引流的 app 亦可)和 ffplay.exe 对流媒体服务器进行测试. 快直播 ...

  2. .Net Core+分布式配置中心(AgileConfig)

    GitHub上AgileConfig非常详细,以下只是本人学习过程的整理 一.介绍 1.参考地址 https://github.com/dotnetcore/AgileConfig https://w ...

  3. 获取元素在页面中位置 getBoundingClientRect()

    DOM 原生方法getBoundingClientRect()获取元素相对视口位置 DOMRect 对象包含了一组用于描述边框的只读属性--left.top.right和bottom,单位为像素.除了 ...

  4. Lock(锁)

    Lock(锁) 从JDK 5.0开始,Java提供了更加强大的线程同步机制----通过显示定义同步锁对象来实现同步.同步锁使用Lock对象充当. java.util.concurrent.locks. ...

  5. Qt列表等控件实现平滑滚动&deepin启动器存在的问题

    Qt列表等控件实现平滑滚动 Qt自带的的列表控件是不能平滑滚动的,但如果滚动速度快的话很容易引起视线丢失,体验效果很差.本篇主要讲述如何在Qt中对列表控件加入平滑滚动.文中以QScrollArea控件 ...

  6. NOIP 模拟 $22\; \rm f$

    题解 \(by\;zj\varphi\) 对于一个数,如果它二进制下第 \(i\) 位为 \(1\),那么 \(\rm x\) 在这一位选 \(1\) 的贡献就是和它不同的最高为为 \(i\) 的数的 ...

  7. SpringBoot获取请求的参数

    说明 SpringBoot 为我们封装了许多,简便的获取请求参数的方法! 1.获取无注解获取请求参数 请求地址:http://192.168.0.115:8080/myproject/test/noA ...

  8. ASP.NET Core教程:ASP.NET Core使用AutoMapper

    一.前言 在实际的项目开发过程中,我们使用各种ORM框架可以使我们快捷的获取到数据,并且可以将获取到的数据绑定到对应的List<T>中,然后页面或者接口直接显示List<T>中 ...

  9. C# 插件编写

    //加载插件 private void LoadPlugins() { string path = Path.Combine(Path.GetDirectoryName(Assembly.GetExe ...

  10. C++ Opencv图像直方图

    Mat image = imread("D:/ju.jpg"); imshow("素材图", image); int bins = 256; //直条为256 ...