【Redis】redis事务和锁、持久化、RDB、AOF、主从复制、集群、缓存穿透、缓存击穿、缓存雪崩、分布式锁和ACL机制

【Redis】redis事务和锁、持久化、RDB、AOF、主从复制、集群、缓存穿透、缓存击穿、缓存雪崩、分布式锁和ACL机制,第1张

【Redis】redis事务和锁、持久化、RDB、AOF、主从复制、集群、缓存穿透、缓存击穿、缓存雪崩、分布式锁和ACL机制

文章目录

Redis事务和锁机制

Multi、exec、discard事务的冲突问题

悲观锁乐观锁WATCH key [key...] 乐观锁 Redis事务三特性

单独的隔离 *** 作没有隔离级别的概念不保证原子性 Redis持久化

两种持久化方式RDBforkRDB的备份AOF备份

AOF启动/修复/恢复 AOF同步频率设置

appendfsync alwaysappendfsync everysecappendfsync no Rewrite压缩AOF持久化流程

AOF优势AOF劣势 Redis主从复制

配置从库不配置主库一台从服务器可以再跟一台从服务器slaveof no one:主服务器挂掉,从服务器成为master哨兵模式 Redis集群

删除持久化数据制作6个实例

配置基本信息redis cluster配置修改启动6个redis服务 将6个节点合成一个集群redis cluster如何分配这6个节点在集群中插入数据查询集群中的值故障恢复 Redis应用过程中的问题

缓存穿透

描述原因解决方案 缓存击穿

现象可能原因解决方案 缓存雪崩

现象问题解决方案 分布式锁

设置锁的过期时间

expire users 10 UUID防止误删 ACL

acl listacl catacl whoamiaclsetuser

Redis事务和锁机制

​ Redis事务是一个单独的隔离 *** 作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求打断。

​ Redis事务的主要作用就是串联多个命令防止别的命令插队。

Multi、exec、discard

​ 从输入Multi命令开始,输入的命令都会依次进入命令队列中,但不会执行,直到输入exec后,redis会将之前的命令队列中的命令依次执行。

​ 组队的过程中可以通过discard来放弃组队。

127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> set k1 v1 
QUEUED
127.0.0.1:6379(TX)> set k2 v2
QUEUED
127.0.0.1:6379(TX)> exec
1)OK
2)OK
127.0.0.1:6379> 
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> set a1 b1
QUEUED
127.0.0.1:6379(TX)> set a2 b2
QUEUED
127.0.0.1:6379(TX)> discard
OK
127.0.0.1:6379> 

错误示范:

​ 在组队过程中出现了错误:

127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> set b1 v1
QUEUED
127.0.0.1:6379(TX)> set b2 b2
QUEUED
127.0.0.1:6379(TX)> set b3
(error) ERR wrong number of arguments for 'set' command
127.0.0.1:6379(TX)> exec
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379> 

​ 在执行过程中出现了错误:

127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> set c1 v1 
QUEUED
127.0.0.1:6379(TX)> incr c1
QUEUED
127.0.0.1:6379(TX)> set c2 v2
QUEUED
127.0.0.1:6379(TX)> exec
1) OK
2) (error) ERR value is not an integer or out of range
3) OK
127.0.0.1:6379> 
事务的冲突问题 悲观锁

先上锁,后 *** 作, *** 作完解锁。

1000 ——> if 1000>800 then -800 ——>剩200——>if 200 > 500 then -500 ——>200

上锁 解锁 /上锁 不 *** 作

乐观锁

加上数据的版本号(v1.0),2个请求可以同时进行,当一个请求结束后,会更改当前的版本号(v1.1),另一个请求改数据之前检查数据的版本号 (check-and-set v1.0!=v1.1)

WATCH key [key…] 乐观锁

在执行multi之前,先执行watch key1 [key2],可以监视一个(或多个)key,如果在事务执行之前这个(或这些)key被其他命令所改动,那么事务将被打断。

主机1:

127.0.0.1:6379> watch balance
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> incrby balance 10
QUEUED
127.0.0.1:6379(TX)> exec
1) (integer) 10
127.0.0.1:6379> 

主机2:

127.0.0.1:6379> watch balance
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> incrby balance 20
QUEUED
127.0.0.1:6379(TX)> exec
(nil)
127.0.0.1:6379> 
Redis事务三特性 单独的隔离 *** 作

事务中的所有命令都会序列化、按顺序地执行。事务在执行过程中,不会被其他客户端发送来的命令请求所打断。 没有隔离级别的概念

队列的命令没有提交之前都不会实际被执行,因为事务提交前任何执行都不会被实际执行。 不保证原子性

事务中如果有一条命令执行失败,其后的命令仍然会被执行,没有回滚。 Redis持久化 两种持久化方式

    RDBAOF
RDB

​ 含义:在指定的时间间隔内将内存中的数据集快照写入磁盘

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

​ 优势:

    适合大规模的数据恢复对数据完整性和一致性要求不高更适合使用节省磁盘空间恢复速度快

​ 缺点:

    fork的时候,在内存中的数据被克隆了一份,大致2倍的膨胀需要考虑虽然Redis在fork时使用了写时拷贝技术,但是如果数据庞大时还是比较消耗性能。在备份周期内一定间隔时间做一次备份,如果Redis意外down掉的话,就会丢失最后一次快照后的所有修改。
fork

fork的作用是复制一个与当前进程一样的进程。新进程的所有数据(变量、环境变量、程序计数器等)数值都和原进程一致,但是是一个全新的进程,并作为原进程的子进程。

在Linux程序中,fork()会产生一个和父进程完全相同的子进程,但子进程在此后多会exec系统调用,处于效率考虑,Linux中引入了“写时复制技术”

一般情况父进程和子进程会公用同一段物理内存,只有进程空间的各段的内容要发生变化时,才会将父进程的内容复制一份给子进程。

RDB的备份
# Unless specified otherwise, by default Redis will save the DB:
#   * After 3600 seconds (an hour) if at least 1 key changed
#   * After 300 seconds (5 minutes) if at least 100 keys changed
#   * After 60 seconds if at least 10000 keys changed
#
# You can set these explicitly by uncommenting the three following lines.
#
# save 3600 1
# save 300 100
save 20 3
#20秒内有三次数据写入就会触发持久化 *** 作,保存到当前路径下,名称为dump.rdb
AOF备份

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

如果AOF和rdb同时开启,则默认启动AOF

AOF启动/修复/恢复

正常恢复:

​ 修改redis里面的这一处内容:appendonly由no改为yes:

appendonly yes

# The name of the append only file (default: "appendonly.aof")

appendfilename "appendonly.aof"

​ 恢复:重启redis然后重新加载

异常恢复:

    修改默认的appendonly no,改为yes如果遇到AOF文件损坏,通过redis-check-aof --fix appendonly.aof进行恢复备份被写坏的AOF文件恢复:重启redis,然后重新加载
AOF同步频率设置 appendfsync always

始终同步,每次redis的写入都会立刻记入日志;性能较差但数据完整性比较好

appendfsync everysec

每秒同步,每秒记入日志一次,如果宕机,本秒的数据可能丢失。

appendfsync no

redis不主动进行同步,把同步时机交给 *** 作系统

Rewrite压缩

含义:

​ AOF采用文件追加方式,文件会越来越大,为避免出现这种情况,新增了重写机制,当AOF文件的大小超过所设定的阈值时,redis就会启动AOF文件的内容压缩,只保留可以恢复数据的最小指令集,可以使用命令bgrewriteaof

原理:

​ AOF文件持续增长而过大时,会fork处一条新进程来将文件重写(也是先写临时文件最后再rename),redis4.0版本后的重写,实质上就是把rdb的快照,以二进制的形式附在新的aof头部,作为已有的历史数据,替换掉原来的流水账 *** 作。

触发条件:

​ redis会记录上次重写时的AOF大小,默认配置是当AOF文件大小时上次rewrite后大小的一倍且文件大于64M时触发。

​ 重写虽然可以节约大量磁盘空间,减少恢复时间,但是每次重写还是有负担,因此redis要满足一定条件才会重写。

​ auto-aof-rewrite-percentage:设置重写的基准值,文件达到100%时开始重写(文件是原来重写后文件的2倍时触发)

​ auto-aof-rewrite-min-size:设置重写的基准值,最小文件64MB。达到这个值开始重写。

例如:文件达到70MB开始重写,降到50MB,下次什么时候开始重写?100MB系统载入时或者上次重写完毕时,redis会记录此时AOF大小,设为base_size,如果redis的AOF当前大小>=base_size + base_size*100%(默认)且当前大小>=64mb(默认)的情况下,redis会对AOF进行重写。

重写过程:

    bgrewriteaof重发重写,判断是否当前有bgsave或bgrewriteaof在运行,如果有,则等待该命令结束后再继续执行。主进程fork处子进程执行重写 *** 作,保障主进程不会阻塞。子进程遍历redis内存中数据到临时文件,客户端的写请求同时写入aof_buf缓冲区和aof_rewrite_buf重写缓冲区保证原AOF文件完整以及新AOF文件生成期间的新的数据修改动作不会丢失。子进程写完新的AOF文件后,向主进程发信号,父进程更新统计信息。主进程把aof_rewrite_bud中的数据写入到新的AOF文件。使用新的AOF文件覆盖旧的AOF文件,完成AOF重写。
AOF持久化流程
    客户端的请求写命令会被append追加到AOF缓冲区内;AOF缓冲区根据AOF持久化策略[always,everysec,no]将 *** 作sync同步到磁盘的AOF文件中;AOF文件大小超过重写策略或手动重写时,会对AOF文件rewrite重写,压缩AOF文件容量;redis服务重启时,会重新load加载AOF文件中的写 *** 作达到数据恢复的目的;
AOF优势

备份机制更稳健,丢失数据概率更低。可读的日志文本,通过 *** 作AOF文件,可以处理误 *** 作。 AOF劣势

比起RDB占用更多的磁盘空间。恢复备份速度慢。每次读写都同步的话,有一定的性能压力。存在个别bug,造成恢复不便。 Redis主从复制

master以写为主,slave以读为主。

步骤:

    创建/myredis文件夹复制redis.conf配置文件到文件夹中配置一主两从,创建三个配置文件

    redis6379.confredis6380.confredis6381.conf 在三个配置文件中写入内容

inlcude /myredis/redis.conf
pidfile /var/run/redis_6381.pid
port 6381
dbfilename dump6381.rdb

开启daemonize yes

pid 文件名字 pidfile

指定端口port

log 文件名字

dump.rdb 名字 dbfilename

appendonly关掉

[root@redis redis-6.2.6]# cd /myredis/
[root@redis myredis]# ls
redis6379.conf  redis6380.conf  redis6381.conf  redis.conf
[root@redis myredis]# vi redis6381.conf
[root@redis myredis]# vi redis6380.conf
[root@redis myredis]# vi redis6379.conf
[root@redis myredis]# vi redis.conf 

​ 5.开启redis服务

[root@redis myredis]# redis-server redis6379.conf
[root@redis myredis]# redis-server redis6380.conf
[root@redis myredis]# redis-server redis6381.conf
[root@redis myredis]# ps -ef | grep redis
root        3339       1  0 09:39 ?        00:00:16 redis-server 127.0.0.1:6379
root        3344    2684  0 09:39 pts/2    00:00:00 redis-cli
root        5820       1  0 13:32 ?        00:00:00 redis-server 127.0.0.1:6380
root        5827       1  0 13:32 ?        00:00:00 redis-server 127.0.0.1:6381
root        5900    2282  0 13:40 pts/0    00:00:00 grep --color=auto redis

查看主机的运行情况

[root@redis myredis]# redis-cli -p 6379
[root@redis myredis]# redis-cli -p 6380
[root@redis myredis]# redis-cli -p 6381
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:0
master_failover_state:no-failover
master_replid:be58cc035a1e95eebeb94d9b76384562990f5c94
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:6380>  info replication
# Replication
role:master
connected_slaves:0
master_failover_state:no-failover
master_replid:6888455763bc86cb654ad3bd39ba3905cf5d0246
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:6381>  info replication
# Replication
role:master
connected_slaves:0
master_failover_state:no-failover
master_replid:434224fc6ec4808b5f3560b4ed7d93ff28750496
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

​ 6.在从机上配置

配置从库不配置主库
 slaveof 
 #成为某个实例的从服务器

在6380和6381上执行:slaveof 127.0.0.1 6379

127.0.0.1:6380> slaveof 127.0.0.1 6379
OK
127.0.0.1:6381> slaveof 127.0.0.1 6379
OK
一台从服务器可以再跟一台从服务器

6381服务器上 *** 作:

127.0.0.1:6381> slaveof 127.0.0.1 6380
OK
127.0.0.1:6381>  info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6380
master_link_status:up
master_last_io_seconds_ago:3
master_sync_in_progress:0
slave_read_repl_offset:3346
slave_repl_offset:3346
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:fbad1029d5d306892f44473c85fbb43b87cdb5ad
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:3346
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:3346
127.0.0.1:6381> 

6380和6379查看:

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_read_repl_offset:3360
slave_repl_offset:3360
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:1
slave0:ip=127.0.0.1,port=6381,state=online,offset=3360,lag=1
master_failover_state:no-failover
master_replid:fbad1029d5d306892f44473c85fbb43b87cdb5ad
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:3360
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:3360
127.0.0.1:6380> 
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=127.0.0.1,port=6380,state=online,offset=3374,lag=0
master_failover_state:no-failover
master_replid:fbad1029d5d306892f44473c85fbb43b87cdb5ad
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:3374
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:3374
127.0.0.1:6379> 
slaveof no one:主服务器挂掉,从服务器成为master

6379 shutdown:

127.0.0.1:6379> shutdown
not connected> exit
[root@redis myredis]# 

6380 成为master节点:

127.0.0.1:6380> slaveof no one
OK
127.0.0.1:6380>  info replication
# Replication
role:master
connected_slaves:1
slave0:ip=127.0.0.1,port=6381,state=online,offset=3542,lag=0
master_failover_state:no-failover
master_replid:1583f3eaf1671a1d9c1e1253b1d3df99f1c911ba
master_replid2:fbad1029d5d306892f44473c85fbb43b87cdb5ad
master_repl_offset:3542
second_repl_offset:3543
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:3542
127.0.0.1:6380> 
哨兵模式

在/myredis目录下新建sentinel.conf文件

[root@redis myredis]# touch sentinel.conf
[root@redis myredis]# vi sentinel.conf 

其中mymaster为监控对象起的服务器名称,1为至少有多少个哨兵同意迁移的数量。

添加:

sentinel monitor mymaster 127.0.0.1 6379 1

启动:

[root@redis myredis]# redis-sentinel /myredis/sentinel.conf 
6721:X 21 Jan 2022 14:43:29.726 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
6721:X 21 Jan 2022 14:43:29.726 # Redis version=6.2.6, bits=64, commit=00000000, modified=0, pid=6721, just started
6721:X 21 Jan 2022 14:43:29.726 # Configuration loaded
6721:X 21 Jan 2022 14:43:29.727 * Increased maximum number of open files to 10032 (it was originally set to 1024).
6721:X 21 Jan 2022 14:43:29.727 * monotonic clock: POSIX clock_gettime
                _._                                                  
           _.-``__ ''-._                                             
      _.-``    `.  `_.  ''-._           Redis 6.2.6 (00000000/0) 64 bit
  .-`` .-```.  ```/    _.,_ ''-._                                  
 (    '      ,       .-`  | `,    )     Running in sentinel mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 26379
 |    `-._   `._    /     _.-'    |     PID: 6721
  `-._    `-._  `-./  _.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |           https://redis.io       
  `-._    `-._`-.__.-'_.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |                                  
  `-._    `-._`-.__.-'_.-'    _.-'                                   
      `-._    `-.__.-'    _.-'                                       
          `-._        _.-'                                           
              `-.__.-'                                               

6721:X 21 Jan 2022 14:43:29.727 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
6721:X 21 Jan 2022 14:43:29.729 # Sentinel ID is e8e3718fd7bae8fb0d51fb001fba3a3766856f6e
6721:X 21 Jan 2022 14:43:29.729 # +monitor master mymaster 127.0.0.1 6379 quorum 1
6721:X 21 Jan 2022 14:43:29.730 * +slave slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6379
6721:X 21 Jan 2022 14:43:29.732 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6379

优先级在redis.conf中默认:slave-priority 100,值越小优先级越高,编辑redis.conf文件:

# The replica priority is an integer number published by Redis in the INFO
# output. It is used by Redis Sentinel in order to select a replica to promote
# into a master if the master is no longer working correctly.
#
# A replica with a low priority number is considered better for promotion, so
# for instance if there are three replicas with priority 10, 100, 25 Sentinel
# will pick the one with priority 10, that is the lowest.
#
# However a special priority of 0 marks the replica as not able to perform the
# role of master, so a replica with priority of 0 will never be selected by
# Redis Sentinel for promotion.
#
# By default the priority is 100.
replica-priority 100
Redis集群 删除持久化数据
[root@redis myredis]# ll
total 124
-rw-r--r-- 1 root root     0 Jan 21 14:37 appendonly.aof
-rw-r--r-- 1 root root   176 Jan 21 14:52 dump6379.rdb
-rw-r--r-- 1 root root   175 Jan 21 14:38 dump6380.rdb
-rw-r--r-- 1 root root   176 Jan 21 14:52 dump6381.rdb
-rw-r--r-- 1 root root   176 Jan 21 14:45 dump.rdb
-rw-r--r-- 1 root root   240 Jan 21 14:49 redis6379.conf
-rw-r--r-- 1 root root   264 Jan 21 14:49 redis6380.conf
-rw-r--r-- 1 root root   281 Jan 21 14:52 redis6381.conf
-rw-r--r-- 1 root root 93716 Jan 21 11:18 redis.conf
-rw-r--r-- 1 root root   392 Jan 21 14:49 sentinel.conf
[root@redis myredis]# rm -f *.rdb
[root@redis myredis]# ll
total 108
-rw-r--r-- 1 root root     0 Jan 21 14:37 appendonly.aof
-rw-r--r-- 1 root root   240 Jan 21 14:49 redis6379.conf
-rw-r--r-- 1 root root   264 Jan 21 14:49 redis6380.conf
-rw-r--r-- 1 root root   281 Jan 21 14:52 redis6381.conf
-rw-r--r-- 1 root root 93716 Jan 21 11:18 redis.conf
-rw-r--r-- 1 root root   392 Jan 21 14:49 sentinel.conf
[root@redis myredis]# rm -f *.aof
[root@redis myredis]# ll
total 108
-rw-r--r-- 1 root root   240 Jan 21 14:49 redis6379.conf
-rw-r--r-- 1 root root   264 Jan 21 14:49 redis6380.conf
-rw-r--r-- 1 root root   281 Jan 21 14:52 redis6381.conf
-rw-r--r-- 1 root root 93716 Jan 21 11:18 redis.conf
-rw-r--r-- 1 root root   392 Jan 21 14:49 sentinel.conf
[root@redis myredis]# 
制作6个实例

分别为:6379 6380 6381 6389 6390 6391

配置基本信息

开启daemonize yes

pid 文件名字 pidfile

指定端口port

log 文件名字

dump.rdb 名字 dbfilename

appendonly关掉

redis cluster配置修改

cluster-enable yes 打开集群模式

cluster-config-file node-6379.conf 设定节点配置文件名

cluster-node-timeout 15000 设定节点失联时间,超过该时间(毫秒),集群自动进行主从切换

[root@redis myredis]# cat redis6379.conf 
include /myredis/redis.conf
pidfile "/var/run/redis_6379.pid"
port 6379
dbfilename "dump6379.rdb"
cluster-enabled yes
cluster-config-file node-6379.conf
cluster-node-timeout 15000
[root@redis myredis]# sed -i 's/6379/6380/g' redis6380.conf 
[root@redis myredis]# sed -i 's/6379/6381/g' redis6381.conf 
[root@redis myredis]# sed -i 's/6379/6389/g' redis6389.conf 
[root@redis myredis]# sed -i 's/6379/6390/g' redis6390.conf 
[root@redis myredis]# sed -i 's/6379/6391/g' redis6391.conf 
启动6个redis服务
[root@redis myredis]# redis-server redis6379.conf 
[root@redis myredis]# redis-server redis6380.conf 
[root@redis myredis]# redis-server redis6381.conf 
[root@redis myredis]# redis-server redis6389.conf 
[root@redis myredis]# redis-server redis6390.conf 
[root@redis myredis]# redis-server redis6391.conf 
[root@redis myredis]# ps -ef | grep redis
root        7472       1  0 15:40 ?        00:00:00 redis-server 127.0.0.1:6389 [cluster]
root        7478       1  0 15:40 ?        00:00:00 redis-server 127.0.0.1:6390 [cluster]
root        7484       1  0 15:40 ?        00:00:00 redis-server 127.0.0.1:6391 [cluster]
root        7542       1  0 15:43 ?        00:00:00 redis-server 127.0.0.1:6379 [cluster]
root        7548       1  0 15:43 ?        00:00:00 redis-server 127.0.0.1:6380 [cluster]
root        7555       1  0 15:43 ?        00:00:00 redis-server 127.0.0.1:6381 [cluster]
root        7561    6595  0 15:43 pts/3    00:00:00 grep --color=auto redis
[root@redis myredis]# 
将6个节点合成一个集群
[root@redis myredis]# redis-cli --cluster create --cluster-replicas 1 192.168.50.135:6379 192.168.50.135:6380 192.168.50.135:6381 192.168.50.135:6389 192.168.50.135:6390 192.168.50.135:6391
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 192.168.50.135:6390 to 192.168.50.135:6379
Adding replica 192.168.50.135:6391 to 192.168.50.135:6380
Adding replica 192.168.50.135:6389 to 192.168.50.135:6381
>>> Trying to optimize slaves allocation for anti-affinity
[WARNING] Some slaves are in the same host as their master
M: a5fa9e57422d450d1459ab286c9979a2ade59476 192.168.50.135:6379
   slots:[0-5460] (5461 slots) master
M: 59cf483c3f6b077f473167d4ee5a1d5e4ad7ce82 192.168.50.135:6380
   slots:[5461-10922] (5462 slots) master
M: 23f111115c58208228c78a56a68f6ef95972003a 192.168.50.135:6381
   slots:[10923-16383] (5461 slots) master
S: 6d9d5d4cd1dbf03ec0c03abb57ac69a6923f1887 192.168.50.135:6389
   replicates 23f111115c58208228c78a56a68f6ef95972003a
S: 091c56c9d0052be27fdccb61481be6a0b0d37f2f 192.168.50.135:6390
   replicates a5fa9e57422d450d1459ab286c9979a2ade59476
S: 897d6b562f57aa56328450bad55b4aed76ae8d97 192.168.50.135:6391
   replicates 59cf483c3f6b077f473167d4ee5a1d5e4ad7ce82
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join

>>> Performing Cluster Check (using node 192.168.50.135:6379)
M: a5fa9e57422d450d1459ab286c9979a2ade59476 192.168.50.135:6379
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
M: 23f111115c58208228c78a56a68f6ef95972003a 192.168.50.135:6381
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
S: 6d9d5d4cd1dbf03ec0c03abb57ac69a6923f1887 192.168.50.135:6389
   slots: (0 slots) slave
   replicates 23f111115c58208228c78a56a68f6ef95972003a
S: 091c56c9d0052be27fdccb61481be6a0b0d37f2f 192.168.50.135:6390
   slots: (0 slots) slave
   replicates a5fa9e57422d450d1459ab286c9979a2ade59476
M: 59cf483c3f6b077f473167d4ee5a1d5e4ad7ce82 192.168.50.135:6380
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
S: 897d6b562f57aa56328450bad55b4aed76ae8d97 192.168.50.135:6391
   slots: (0 slots) slave
   replicates 59cf483c3f6b077f473167d4ee5a1d5e4ad7ce82
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
[root@redis myredis]# redis-cli -c -p 6379
127.0.0.1:6379> cluster nodes
23f111115c58208228c78a56a68f6ef95972003a 192.168.50.135:6381@16381 master - 0 1642753887987 3 connected 10923-16383
6d9d5d4cd1dbf03ec0c03abb57ac69a6923f1887 192.168.50.135:6389@16389 slave 23f111115c58208228c78a56a68f6ef95972003a 0 1642753890028 3 connected
091c56c9d0052be27fdccb61481be6a0b0d37f2f 192.168.50.135:6390@16390 slave a5fa9e57422d450d1459ab286c9979a2ade59476 0 1642753889005 1 connected
59cf483c3f6b077f473167d4ee5a1d5e4ad7ce82 192.168.50.135:6380@16380 master - 0 1642753888000 2 connected 5461-10922
897d6b562f57aa56328450bad55b4aed76ae8d97 192.168.50.135:6391@16391 slave 59cf483c3f6b077f473167d4ee5a1d5e4ad7ce82 0 1642753886000 2 connected
a5fa9e57422d450d1459ab286c9979a2ade59476 192.168.50.135:6379@16379 myself,master - 0 1642753889000 1 connected 0-5460
127.0.0.1:6379> 
redis cluster如何分配这6个节点

一个集群至少有三个主节点。

选项 --cluster-replicas 1表示为集群中的每个主节点创建一个从节点。

在集群中插入数据
192.168.50.135:6379> set k4 v4
-> Redirected to slot [8455] located at 192.168.50.135:6380
OK
192.168.50.135:6380> set k5 v5
-> Redirected to slot [12582] located at 192.168.50.135:6381
OK
192.168.50.135:6381> set k6 v6 
-> Redirected to slot [325] located at 192.168.50.135:6379
OK
192.168.50.135:6379> 

使用mset插入数据:

192.168.50.135:6379> mset name{user} lucy age{user} 20
-> Redirected to slot [5474] located at 192.168.50.135:6380
OK
192.168.50.135:6380> 
#其中{user}表示这个组的名称,crc16会根据组名进行哈希,之后存储数据。
查询集群中的值

cluster keyslot k1 #返回k1的插槽值:

192.168.50.135:6380> cluster keyslot k1
(integer) 12706
192.168.50.135:6380> 

cluster countkeysinslot #统计插槽中的数量:

192.168.50.135:6379> cluster countkeysinslot 449
(integer) 1
192.168.50.135:6379> 

CLUSTER GETKEYSINSLOT #返回count个slot槽中的键。:

192.168.50.135:6379> cluster getkeysinslot 449 1
1) "k2"
192.168.50.135:6379> 
故障恢复

​ 如果某一段插槽的主从都挂掉,而cluster-require-full-coverage为yes,那么,整个集群都挂掉。

​ 如果某一段插槽的主从都挂掉,而cluster-require-full-coverage为no,那么,该插槽数据全都不能使用,也无法储存。

Redis应用过程中的问题 缓存穿透 描述

访问时应用服务器压力变大redis命中率降低一直查询数据库 原因

redis里面查询不到数据库 *** 作中出现很多非正常的url访问 解决方案

对空值缓存:如果一个查询返回的数据为空(不管是数据是否不存在),仍然把在这个空结果(null)进行缓存,设置空结果的过期时间会很短,最长不超过五分钟。

设置可访问的白名单(白名单):

使用bitmaps类型定义一个可以访问的名单,名单id作为bitmaps的偏移量,每次访问和bitmap里面的id进行比较,如果访问id不存在bitmaps里面,进行拦截,不允许访问。

采用布隆过滤器:(布隆过滤器(Bloom Filter)时1970年由布隆提出的。它实际上是一个很长的二进制向量(位图)和一系列随机映射函数(哈希函数)布隆过滤器可以用于检索一个元素是否在一个集合中。它的优点是空间效率和查询时间都远远超过一般的算法,缺点是有一定的误识别率和删除困难。)将所有可能存在的数据哈希到一个足够大的bitmaps中,一个一定不存在的数据会被这个bitmaps拦截掉,从而避免了对底层存储系统的查询压力。

进行实时监控:当发现redis的命中率开始急速降低,需要排查访对象和访问的数据,和运维人员配合,可以设置黑名单限制服务。

缓存击穿 现象

数据库访问压力瞬时增加redis里面没有出现大量key过期redis可以正常运行 可能原因

redis某个key过期了,大量访问使用这个key 解决方案

​ key可能会在某些时间点被超高并发的访问,是一种非常“热点”的数据。这个时候,需要考虑一个问题:缓存被“击穿”的问题。

**预先设置热门数据:**在redis高峰访问之前,把一些热门数据提前存入到redis里面,加大这些热门数据key的时长**实时调整:**现场监控那些数据热门,实时调整key的过期时长。**使用锁:**就是在缓存失效的时候(判断拿出来的值为空),不是立即去load db。先使用缓存工具的某些带成功 *** 作返回值的 *** 作(比如redis的SETNX)去set一个mutex key。当 *** 作返回成功时,再进行load db *** 作,并回设缓存,最后删除mutex key;当 *** 作返回失败,证明有线程在load db,当前线程睡眠一段时间再重试整个get缓存的方法。 缓存雪崩 现象

数据库压力变大,服务器崩溃 问题

在极少的时间段,查询大量key的集中过期情况 解决方案

**构建多级缓存架构:**nginx缓存+redis缓存+其他缓存(ehcache等)**使用锁或者队列:**用加锁或者队列的方式保证不会有大量的线程对数据库一次性进行读写,从而避免失效时大量的并发请求落到底层存储系统上。不适用高并发情况。**设置过期标志更新缓存:**记录缓存数据是否过期(设置提前量),如果过期会触发通知另外的线程在后台去更新实际key的缓存。**将缓存失效时间分散开:**在原有的失效时间基础上增加一个随机值,比如1-5分钟随机,这样每个缓存的过期时间的重复率就会降低,很难引发集体失效事件。 分布式锁

redis命令

EX second: 设置键的过期时间为second秒。SET key value EX second 效果等同于 SETEX key second value。

127.0.0.1:6379> setnx users 10
-> Redirected to slot [14124] located at 192.168.50.135:6381
(integer) 1
192.168.50.135:6381> del users
(integer) 1
192.168.50.135:6381> setnx users 20
(integer) 1
192.168.50.135:6381> del users 
(integer) 1
192.168.50.135:6381> 

**PX millisecond:**设置键的过期时间为millisecond毫秒。SET key value PX millisecond等同于 PSETEX key millisecond value。

**NX:**只在键不存在时,才对键进行设置 *** 作。SET key value NX 效果等同于SETNX key value。

**XX:**只在键已经存在时,才对键进行设置 *** 作。

设置锁的过期时间 expire users 10

使用setnx上锁,使用del释放锁

锁一直没有释放,设置key过期时间,自动释放

上锁之后突然出现异常,无法设置过期时间

上锁的时候同时设置过期时间

192.168.50.135:6381> setnx users 10
(integer) 1
192.168.50.135:6381> expire users 10
(integer) 1
192.168.50.135:6381> ttl users
(integer) 8
192.168.50.135:6381> ttl users
(integer) 1
192.168.50.135:6381> ttl users
(integer) 0
192.168.50.135:6381> ttl users
(integer) -2
192.168.50.135:6381> setnx users 20
(integer) 1
192.168.50.135:6381> 
192.168.50.135:6381> set users 10 nx ex 12
OK
192.168.50.135:6381> ttl users
(integer) 7
192.168.50.135:6381> ttl users
(integer) 3
192.168.50.135:6381> ttl users
(integer) -2
192.168.50.135:6381> setnx users 20
(integer) 1
UUID防止误删 ACL acl list

权限列表查看

192.168.50.135:6381> acl list
1) "user default on nopass ~* &* +@all"
192.168.50.135:6381> 
acl cat

查看添加权限指令类别

192.168.50.135:6381> acl cat
 1) "keyspace"
 2) "read"
 3) "write"
 4) "set"
 5) "sortedset"
 6) "list"
 7) "hash"
 8) "string"
 9) "bitmap"
10) "hyperloglog"
11) "geo"
12) "stream"
13) "pubsub"
14) "admin"
15) "fast"
16) "slow"
17) "blocking"
18) "dangerous"
19) "connection"
20) "transaction"
21) "scripting"
192.168.50.135:6381> 

具体部分查看:

192.168.50.135:6381> acl cat string
 1) "msetnx"
 2) "incrbyfloat"
 3) "get"
 4) "setnx"
 5) "getset"
 6) "psetex"
 7) "decrby"
 8) "setex"
 9) "set"
10) "strlen"
11) "getdel"
12) "decr"
13) "mset"
14) "incrby"
15) "stralgo"
16) "substr"
17) "mget"
18) "getrange"
19) "getex"
20) "incr"
21) "setrange"
22) "append"
192.168.50.135:6381> 
acl whoami

查看当前用户

192.168.50.135:6381> acl whoami
"default"
192.168.50.135:6381>
aclsetuser

创建和编辑用户ACL

192.168.50.135:6381> acl setuser lucy
OK
192.168.50.135:6381> acl list
1) "user default on nopass ~* &* +@all"
2) "user lucy off &* -@all"
192.168.50.135:6381>

设置用户名、密码、acl权限,并启用用户

acl setuser user2 on >password ~cached:* + get

192.168.50.135:6381> acl setuser tom on >password ~cached:* +get
OK
192.168.50.135:6381> acl list
1) "user default on nopass ~* &* +@all"
2) "user lucy off &* -@all"
3) "user mary off &* -@all"
4) "user tom on #5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8 ~cached:* &* -@all +get"
192.168.50.135:6381> 

切换用户,验证权限

192.168.50.135:6381> auth tom password
OK
192.168.50.135:6381> get k1
(error) NOPERM this user has no permissions to access one of the keys used as arguments
192.168.50.135:6381> set k1 v1
(error) NOPERM this user has no permissions to run the 'set' command or its subcommand
192.168.50.135:6381> get cached:111
-> Redirected to slot [9830] located at 192.168.50.135:6380
(nil)
192.168.50.135:6380> 

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5708798.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存