目录
1、主从复制(读写分离)
1.1、什么是主从复制
1.2、主从复制的作用
1.3、环境搭建
首先在把redis下的redis.conf配置文件copy一份到一个新的文件夹,这里我创建一个myredis文件夹
复制端口6379
复制端口6380
复制端口6381
启动各个端口的redis
查看redis进程
分别打开三个窗口连接三个服务器
1.4、一主二仆
这里把6379当作主服务器,把6380、6381当作为从服务器,那么6380、6381就要通过命令去绑定主服务器,在6380、6381服务器分别输入以下命令,将6379服务器当作主服务器。
1.5、注意事项
1、当其中的一个从服务器 shutdown 挂掉了,从服务器再次启动还会不会重新连接到主服务器中?
不会,会自动变成主服务器。
2、如果把挂掉的从服务器重新连到主服务器后,主服务器的数据还会不会复制过来?
会。
3、当主服务器挂掉后,从服务器不会做任何事情,查看从服务器 info replication服务器情况,还认主服务器只是状态挂掉了,再次重启主服务器,又回到主服务位置。
1.6、反客为主
将主服务器挂掉
把从服务器上位为主服务器
1.7、哨兵模式(sentinel)
是一种容灾方案。以上主服务器挂了,虽然从服务器变成了主服务器,但是有一个问题,是手动变成服务器
哨兵:实则是一个在特殊模式下的Redis服务器,里面存储的是自己本身的信息,主服务器的信息,从服务器的信息。
用一个或者多个哨兵来监视主服务器(也就是进行写操作的服务器)是否在正常执行任务,一旦哨兵发现主服务器不可用时,就找到一个合适的从服务器成为主服务器。
恢复到6379位主服务器,6380、6381位从服务器的状态
在当前myredis目录下创建 sentinel.conf 文件,名字不要写错,配置如下
mymaster为监控对象起的服务器名字 ,1 只要有一个哨兵认为master宕机就可以切换,同时会选举1个哨兵进行迁移的数据
启动哨兵模式
把主服务器6379服务器 shutdown , 查看哨并是否会自动把从服务器变成主服务器
此时哨兵会检测到主服务器宕机,会再选择一个从服务器上位主服务器
2、Redis集群
2.1、什么是集群
2.2、什么是redis集群
-
Redis-Cluster的概念 Redis-Cluster采用无中心结构,集群中的每个节点都是平等的关系,都是对等的,每个节点都保存各自的数据和整个集群的状态。每个节点都和其他所有节点连接,而且这些连接保持活跃,这样就保证了我们只需要连接集群中的任意一个节点,就可以获取到其他节点的数据。
-
数据分散存储 Redis 集群并没有使用传统的一致性哈希来分配数据,而是采用另外一种叫做 哈希槽(hash slot) 的方式来分配的。redis cluster 默认分配了 16384 个slot,当我们set一个key 时,会用CRC16算法来取模得到所属的slot,然后将这个key 分到哈希槽区间的节点上,具体算法就是:CRC16(key) % 16384。
-
Redis 是在内存中保存数据的,而我们的电脑一般内存都不大, 这也就意味着 Redis 不适合存储大数据,适合存储大数据的是 Hadoop 生态系统的 Hbase 或 者是 MogoDB。Redis 更适合处理高并发,一台设备的存储能力是很有限的,但是多台设备 协同合作,就可以让内存增大很多倍,这就需要用到集群。
-
Redis 集群搭建的方式有多种,例如使用客户端分片、Twitter开发的Twemproxy、豌豆荚开发的Codis 等,但从 redis 3.0 之后版本支持 redis-cluster 集群,它是 Redis 官方提出的解决方案, Redis-Cluster 采用无中心结构,每个节点保存数据和整个集群状态,每个节点都和其他所 有节点连接。
2.3、Redis集群中的哈希槽
Redis集群中引入了哈希槽的概念,Redis集群有16384个哈希槽,进行set操作时,每个key会通过CRC16校验后再对16384取模来决定放置在哪个槽,搭建Redis集群时会先给集群中每个master节点分配一部分哈希槽。 比如当前集群有3个master节点,
master1节点包含0~5500号哈希槽, master2节点包含5501~11000号哈希槽, master3节点包含11001~16384号哈希槽,
当我们执行“set key value”时,假如 CRC16(key) % 16384 = 777,那么这个key就会被分配到master1节点上,如下图
2.4、Redis集群中节点的通信
既然Redis集群中的数据是通过哈希槽的方式分开存储的,那么集群中每个节点都需要知道其他所有节点的状态信息,包括当前集群状态、集群中各节点负责的哈希槽、集群中各节点的master-slave状态、集群中各节点的存活状态等。Redis集群中,节点之间通过建立TCP连接,使用gossip协议来传播集群的信息。如下图:
2.5、如何判断某个节点挂掉
首先要说的是,每一个节点都存有这个集群所有主节点以及从节点的信息。它们之间通过互相的ping-pong判断是否节点可以连接上。如果有一半以上的节点去ping一个节点的时候没有回应,集群就认为这个节点宕机了,然后去连接它的备用节点。
3、缓存穿透
3.1、缓存穿透概述
缓存穿透是指缓存和数据库中都没有的数据,这样每次请求都会去查库,不会查缓存,如果同一时间有大量(高并发)请求进来的话,就会给数据库造成巨大的查询压力,甚至击垮数据库。
3.2、解决方案
1、对空值缓存:如果一个查询返回的数据为空,不管数据是否存在,我们仍然把这个空值作缓存,设置空值的过期时间很短。
2、设置访问的白名单:使用bitmaps类型定义一个可以访问的名单,名单id作为bitmaps偏移的量,每次访问和bitmaps有id进行对比,如果不存在就拦截,不允许访问
3、布隆过滤器:布隆过滤器底层使用bit数组存储数据,该数组中的元素默认值是0。布隆过滤器第一次初始化的时候,会把数据库中所有已存在的key,经过一些列的hash算法(比如:三次hash算法)计算,每个key都会计算出多个位置,然后把这些位置上的元素值设置成1。 之后,有用户key请求过来的时候,再用相同的hash算法计算位置。
-
如果多个位置中的元素值都是1,则说明该key在数据库中已存在。这时允许继续往后面操作。
-
如果有1个以上的位置上的元素值是0,则说明该key在数据库中不存在。这时可以拒绝该请求,而直接返回。
其实,布隆过滤器最致命的问题是:如果数据库中的数据更新了,需要同步更新布隆过滤器。但它跟数据库是两个数据源,就可能存在数据不一致的情况。
比如:数据库中新增了一个用户,该用户数据需要实时同步到布隆过滤。但由于网络异常,同步失败了。
这时刚好该用户请求过来了,由于布隆过滤器没有该key的数据,所以直接拒绝了该请求。但这个是正常的用户,也被拦截了。
很显然,如果出现了这种正常用户被拦截了情况,有些业务是无法容忍的。所以,布隆过滤器要看实际业务场景再决定是否使用,它帮我们解决了缓存穿透问题,但同时了带来了新的问题。
4、缓存击穿
4.1、缓存击穿概述
有时候,我们在访问热点数据时。比如:我们在某个商城购买某个热门商品。 为了保证访问速度,通常情况下,商城系统会把商品信息放到缓存中。但如果某个时刻,该商品到了过期时间失效了。 此时,如果有大量的用户请求同一个商品,但该商品在缓存中失效了,一下子这些用户请求都直接到了数据库,可能会造成瞬间数据库压力过大,而直接挂掉。
4.2、解决方案
1、设置热点数据永不过期。(也是一种解决方式,但是实际过程中不推荐)
2、加锁的方式:锁的对象就是key,这样,当大量查询同一个key的请求并发进来时,只能有一个请求获取到锁,然后获取到锁的线程查询数据库,然后将结果放入到缓存中,然后释放锁,此时,其他处于锁等待的请求即可继续执行,由于此时缓存中已经有了数据,所以直接从缓存中获取到数据返回,并不会查询数据库。也就是加锁让一个人去查询数据并把数据存储到缓存中,其他人再查询的时候就直接从缓存中获取了。
5、缓存雪崩
5.1、缓存雪崩概述
缓存雪崩是指当缓存中有大量的key在同一时刻过期,或者Redis直接宕机了,导致大量的查询请求全部到达数据库,造成数据库查询压力骤增,甚至直接挂掉。
5.2、解决方案
-
给不同的key的TTL添加随机值,避免大量的key同时到期
-
利用Redis集群提高服务的可用性,避免Redis服务宕机后的数据丢失和请求直达数据库
-
给缓存业务添加降级限流策略
-
给业务添加多级缓存