Redis初见(其二)

Redis主从关系

当有多个客户端请求Redis时,Redis可能会过载

可以建立Redis集群,并确定主从关系

应用程序                
                                        写入

                                    主-Master 6379端口

                        复制                        复制
        
        读取
                    Slaver  6380端口                      Slaver  6381端口

Monster以写为主,Slaver以读为主,读写分离,提高效率

如果某个Slaver不能正常工作,可切换另一个slaver

只有能有一个Monster

搭建一主二从

新建3个redis服务

创建另外目录将redis.conf到 /hspredis

mkdir /hspredis

cd /hspredis

cp /etc/redis.conf /hspredis/

修改对应三个conf文件

include /hspredis/redis.conf
pidfile /var/run/redis_6379.pid
port 6379
dbfilename dump6379.rdb

include /hspredis/redis.conf
pidfile /var/run/redis_6380.pid
port 6380
dbfilename dump6380.rdb

include /hspredis/redis.conf
pidfile /var/run/redis_6381.pid
port 6381
dbfilename dump6381.rdb

即可有3个redis服务

再Xshell分别开启这三个redis服务

现在三个服务都是Monster,通过指令更改6380 6381为6379的仆人

redis-cli -p 6380              指定端口进入对应redis

slaverof 127.0.0.1 6379

6379写入数据,从6380和6381都可以读到

info replication     查看主从关系

注意事项

仆redis每次重启都会默认变为Monster,重新设置为Slaver后能同步主redis的数据

主redis关掉后,仆redis不会变Monster,等主Redis再启动再变为其仆redis

薪火相传
主Redis            仆Redis1            仆Redis2
  A                    B                C

B是A仆Redis,C也可以是B的仆Redis,可以减少A的服务器压力

反客为主

slaveof no one                 让仆redis变为Monster

哨兵模式

反客为主自动版,能够后台监控主机是否故障,如果故障,将票数最多从库转为主库(上面的B),如果原主机再启动一样成为新主机从机

先到redis们所在文件修改sentinel.conf

cd /hspredis/
vi sentinel.conf

sentinel monitor redis_master 127.0.0.1 6379 1   //进行监控
                                    
                    监控名(自取)              几个哨兵

redis-sentinel /hspredis/sentinel.conf   即可开启监控

Redis集群

redis容量不够,并发操作太多时候需要多个redis

无中心化集群

                            A从机  node1
                            A主机  node2


                B主机    node3                C主机
                B从机    ...                  C从机

各个Redis仍然采用主从结构,各个Redis服务连通的,都可以作为请求入口,都可以请求转发,即使某个redis服务故障,集群仍可继续运行,每个redis服务为一个节点node

得先删除rdb和aof文件

首先打开集群模式

例如6379.conf文件

cluster-enabled yes                                打开集群模式

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

cluster-node-timeout 15000                     失联多久切换主从模式

其他6380 6381 6382...类似

cp redis6379.conf redis6380.conf

将6个节点合成一个集群

cd /opt/redis-6.2.6/src/                先到此目录

rdis-cli --cluster create  --cluster-replicas 1 192.168.198.135:6379 192....:6380 ...6381

合成集群

--cluster-replicas 1:表示为每个集群每个主节点创建个从节点

主从关系认定

cluster nodes     查看主从关系

每个replicates后面对应的端口即为他的主机

集群方式登录

redis-cli -c -p 6379

-c:自动重定向,设置key时使用

注意事项:

一个集群至少3个主节点

一共有16383个插槽slot(用于放置Key),平均分给3个主机,每次设置key会计算插槽值放到对应主机

A负责 0-5460号插槽

B 5461-10922

C 10923-16383

当插入多个key时,可能他们的slot不同故可以

mset k2{name} v2         k3{name} v3         k4{name} v4  可放在同一slot下

查找key对应插槽值

cluster keyslot key

cluster countkeysinslot slot                查找该插槽下有多少key

cluster getkeysinslot  slot count           查找该插槽count个key

 Redis集群故障恢复

主节点下线,从节点会自动上升为主节点;原主机恢复变为从机

即使连接的不是主机,集群也会自动切换主机储存。主机写,从机读

缓存穿透

key对应的数据在数据源(redis和mysql)不存在,反复针对此key的请求都拿不到则会压垮数据源,应用服务器压力变大,Redis命中率降低,一直查数据库

解决:

1对空值缓存

2.设置可访问名单(白名单)

3.布隆过滤器

4.进行实时监控

缓存击穿

key对应数据存在,但在redis过期,若有大量请求发来,会从后端DB加载数据到缓存,这时候的大量并发请求可能会压垮后端DB,Redis正常,但数据库瘫痪了

解决:

1.预先设置热门数据

2.实时调整key过期时间

3.使用锁

缓存雪崩

key对应数据存在,但在redis过期,此时大量并发请求传来,会从后端DB加载数据,可能会把后端DB压垮,与缓存击穿区别是缓存雪崩针对很多key缓存,而缓存击穿只是某一个key

解决:
1.构建多级缓存架构

2.使用锁或队列

3.设置国企标志更新缓存

4.将缓存失败时间分散开

分布式锁

分布式项目分布在各个机器上,单纯的Java Api不能提供分布式锁的能力,需要一种跨JVM的互斥机制控制共享资源访问,这就是分布式锁要解决的问题

                          请求    请求   请求    
    
                               分布式锁

                    子模块1                子模块2

主流方案:

基础数据库实现

基于缓存实现(redis等)                        性能最高

基础Zookeeper                                   可能性最高

基本实现分布式锁(基于Redis)

setnx key value                                key是锁的键vlaue是锁的值

del key                                              释放锁

expire key seconds                            给锁设置过期时间防止死锁

ttl key                                                查看某个锁(过期时间)

set key value nx ex seconds              设置锁并过期时间

通过SpringBoot+Redis实现分布式锁

    index1                index2                index3

                        
                        Redis通过setnx()加锁

在Controller内

@GetMapping("/lock")
public void lock(){

  Boolean lock  redisTemplate.opsForValue().
    setIfAbsent("lock","ok",3,TimeUnit.SECONDS);   //设置锁 过期时间3秒
    
    redisTemplate.delete("lock");               //释放锁
 
}

UUID防误删锁

可能第一个业务未完成,锁就释放了,其他请求又拿到锁,第一个请求可能造成混乱把第二个请求的锁给释放了

解决:给锁设置uuid

lock(){

    String uuid = UUID.randoUUID().toString();            //获取UUID

    Boolean lock  redisTemplate.opsForValue().
    setIfAbsent("lock",uuid,3,TimeUnit.SECONDS);        //然后赋给锁值

    if(uuid.equals(redisTemplate.opsForValue().get("lock"))){    //判断是不是自己的锁

            redisTemplate.delete("lock");
                
     }
    
}

Lua脚本可保障删除的原子性

ACL

Redis访问控制列表

该功能限制可以执行的命令和可以访问的键

常用指令

acl list                                    展现用户权限列表

acl cat 命令                           添加权限

acl who am i                         查看当前用户

acl setuser                             命令创建和编辑用户ACL

IO多线程

Redis加入多线程处理网络数据的读写和协议解析,执行命令依然是单线程

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值