解决redis高并发问题的几种思路

解决redis高并发问题的几种思路

1:布隆过滤器

首先,布隆过滤器能解决绝大部分恶意攻击的请求,比如我们数据库中的id通常都设为自增的,是有一定范围大小的,如果有黑客恶意用数据库中没有的id一直访问我们的数据库,这就会给数据库造成很大的压力,为了解决这个bug,去我们可以使用布隆过滤器来过滤大部分恶意请求。

在这里插入图片描述

1.1 实现原理

布隆过滤器(Bloom Filter)是1970年由布隆提出的。它实际上是一个很长的二进制向量和一系列随机映射函数。布隆过滤器可以用于检索一个元素是否在一个集合中。它的优点是空间效率和查询时间都比一般的算法要好的多,缺点是有一定的误识别率和删除困难。

布隆过滤器的原理是,当一个元素被加入集合时,通过K个Hash函数将这个元素映射成一个位数组中的K个点,把它们置为1。检索时,我们只要看看这些点是不是都是1就(大约)知道集合中有没有它了:如果这些点有任何一个0,则被检元素一定不在;如果都是1,则被检元素很可能在。这就是布隆过滤器的基本思想。

在这里插入图片描述

注:这是最初的布隆过滤器,里面还没存储值,所以都是0

在这里插入图片描述

布隆过滤器会将数据通过多个不同的hash函数将数据生成多个hash值,并映射到槽中,把0变为1,说明有数据。

缺点:

​ 1:布隆过滤器的缺点也很明显,首先是删除数据非常困难,误算率会随着数据的增加逐步加大。

​ 2:它不能准确的判断这个槽中的数据,随着数据的增加,槽中的1也会越来越多,如果我们要查找数据,如果槽中的点有0,就说明没有数据映射到这个bit位上,数据不存在,如果其他的数据也把这个槽中的点置为1,那这个点说明数据存在的,造成了误判,随着数据的增加,被置为1的点会越来越多,即使有一个数据没有被存储过,但万一hash函数返回的三个bit位都被置成了1,那么程序还是会判断这个值是存在的。

总结:尽管有有一定的缺点,但能防止绝大部分数据的判断,也是很推荐使用布隆过滤器的。

能更好的解决缓存穿透。

2:全量同步和增量同步

在这里插入图片描述

Canal是一个基于MySQL二进制日志的高性能数据同步系统

全量同步:就是在上线的时候把查询的所有数据都存到redis中,设置永不失效。

增量同步:在MySql中的binlog日志记录着程序所有的增删改语句,cannal对binlog进行实时监控,如果binlog有更改,就会触发canal同步系统,redis中的内容进行同步更新。

解决问题:缓存雪崩,缓存击穿

3:主从原理

主节点:master 用来写

从节点:slave 用来读

主节点只能有一个,从节点可以有多个

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yUHtosBq-1596442557298)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1596163357043.png)]

使用场景:当QPS(每秒查询率)达到一定高度时,一台服务器不够用时,需要搭建多台服务器时,就用到了主从复制。

原理:首先让用户访问从服务器,从服务器和主服务器建立了连接,主服务器发送数据副本,做到实时更新,这样就有额外的从服务器处理读请求,通过将读请求分发到不同的从服务器上进行处理,以达到分担压力,性能增强。用户请求的写功能,从服务器会将这个请求交给主服务器去做。

4:实现高可用

高可用(HA)是分布式系统架构设计中必须考虑的因素之一,它是通过架构设计减少系统不能提供服务的
时间。保证高可用通常遵循下面几点:

  1. 单点是系统高可用的大敌,应该尽量在系统设计的过程中避免单点。
  2. 通过架构设计而保证系统高可用的,其核心准则是:冗余。
  3. 实现自动故障转移

我们现在已经给Redis实现了主从复制,可将主节点数据同步给从节点,从节点此时有两个作用:

  1. 从节点扩展主节点的读能力,分担主节点读压力。
  2. 一旦主节点宕机,从节点作为主节点的备份可以随时顶上来。(高可用)

5:哨兵机制(Sentinel)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ysUkjjcF-1596442557300)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1596163717659.png)]

应用场景:当主节点宕机,从节点晋升为主节点,同时修改应用方的主节点地址,还需要命令所有从节点去复制新的主节点,这个过程都是由Sentinel来进行实时监控的。

5.1 哨兵有三个定时监控任务完成对各节点的发现和监控

任务1,每个哨兵节点每10秒会向主节点和从节点发送info命令获取最新拓扑结构图,哨兵配置时只要配置对主节点的监控即可(sentinel monitor mymaster 192.168.1.3 26379 2),通过向主节点发送info,获取从节点的信息,并当有新的从节点加入时可以马上感知到;

任务2,每个哨兵节点每隔2秒会向redis数据节点的指定频道上发送该哨兵节点对于主节点的判断以及当前哨兵节点的信息,同时每个哨兵节点也会订阅该频道,来了解其它哨兵节点的信息及对主节点的判断,其实就是通过消息publish和subscribe来完成的;

任务3,每隔1秒每个哨兵会向主节点、从节点及其余哨兵节点发送一次ping命令做一次心跳检测,这个也是哨兵用来判断节点是否正常的重要依据

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ShaZhRmV-1596442557301)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1596164088815.png)]

5.2:故障转移

由Sentinel节点定期监控发现主节点是否出现了故障,sentinel会向master发送心跳PING来确认master是否存活,如果master在“一定时间范围”内不回应PONG 或者是回复了一个错误消息,那么这个sentinel会主观地(单方面地)认为这个master已经不可用了,会要求其他sentinel确认该节点是否丢失,如果确认,则认为是客观下线,的确不可用了,开始进行故障转移

6:负载均衡和高可用

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ygIYRYHM-1596442557302)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1596165498852.png)]

流程:

1:用户发送请求,首先经过nginx进行反向代理和负载均衡之后,再发送给tomcat集群,做到每个tomcat可以平均分担负载。不会因为某台服务器负载高宕机而某台服务器闲置的情况。

2:在这中间要考虑高可用问题,所以,采用tomcat集群的方式,我们防止nginx挂掉,多部署一个或多个nginx,实现高可用

3:如果nginx挂掉怎么办,在经过nginx之前用Linux的LVS(Linux虚拟服务器)采用IP负载均衡技术和基于内容请求分发技术进行负载均衡

4:那如果LVS挂掉了怎么办,还有硬件级负载均衡(F5)

5:如果还担心硬件级别的服务器挂掉了,就建立多个机房,在不同地区,考虑到自然灾害,一个机房不可用了,另一个稍远一点的机房就可以工作了,可能会出现响应变慢,这是肯定的。比如一些世界500强,就实施两地三中心。

7:redsi-Cluster 集群

应用场景:当哨兵模式下的数据访问过大,大到一台服务器存放不下的情况时,主从模式或sentinel模式就不能满足需求了,这个时候就需要对服务器进行分片,将数据存储到多个redis的 实例中,cluster模式的出现就是为了解决单机Redis容量有限的问题,将Redis的数据根据一定的规则分配到多台机器。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7ciQU7Op-1596442557304)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1596173322255.png)]

cluster可以说是sentinel和主从模式的结合体,通过cluster可以实现主从和master重选功能,所以如果配置两个副本三个分片的话,就需要六个Redis实例。因为Redis的数据是根据一定规则分配到cluster的不同机器的,当数据量过大时,可以新增机器进行扩容

架构特点:

  1. 所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽。
  2. 节点的fail是通过集群中超过半数的master节点检测失效时才生效。
  3. 客户端与redis节点直连,不需要连接集群所有节点,只需要连接集群中任意可用节点即可。
  4. 集群把所有的物理节点映射到[0-16383]slot上,cluster 负责维护node<>slot<>key关系
7.1 哈希槽分配数据

需要注意的是,这种集群模式下集群中每个节点保存的数据并不是所有的数据,而只是一部分数据。那
么数据是如何合理的分配到不同的节点上的呢?
Redis 集群是采用一种叫做 哈希槽 (hash slot) 的方式来分配数据的。redis cluster 默认分配了
16384 个slot,当我们set一个key 时,会用 CRC16 算法来取模得到所属的 slot ,然后将这个key 分到
哈希槽区间的节点上,具体算法就是: CRC16(key) % 16384 = 0-16383 。

假设现在有3个节点已经组成了集群,分别是:A, B, C 三个节点,它们可以是一台机器上的三个端口,也可以是三台服务器。那么采用哈希槽的方式来存放16384个槽的话,

节点A覆盖0-5460
节点B覆盖5461-10922
节点C覆盖10923-16383
那么,现在要设置一个key ,比如叫 my_name :
按照redis cluster的哈希槽算法: CRC16(‘my_name’)%16384 = 2412 。 那么就会把这个key 的存储分
配到 节点A 上了。

当用户发送请求的时候,连接任意一个节点即可,哈希槽的计算,集群会自动进行计算和重定向到有该数据的节点上,然后返回用户数据

7.2 redis-Cluster的主从模式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cB4YothU-1596442557305)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1596174743053.png)]

为了保证集群的高可用,在每个redis节点上都建立一个从节点,从节点会实时复制主节点的数据,当主节点宕机的时候,从节点就会顶上去变成主节点。

8:redis的另一种集群方式:Codis

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nBh5xeyj-1596442557307)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1596174624018.png)]

简单来说,codis是作为一个中间件存在的,当客户端向codis发送指令时,codis负责将指令转发到后面的redis来执行,并将结果返回给客户端,一个codis实例可以连接多个redis实例,也可以启动多个codis实例来支撑,每个codis节点都是对等的,这样可以增加整体的QPS需求,还能起到容灾功能。

9:redis的持久化技术

Redis提供了将数据定期自动持久化至硬盘的能力,包括RDBAOF两种方案,两种方案分别有其长处和短板,可以配合起来同时运行,确保数据的稳定性

Redis为持久化提供了两种方式:

  1. RDB:在指定的时间间隔能对数据进行快照存储。
  2. AOF:每次对服务器写的操作都记录在一个日志文件中,当服务器重启的时候会重新执行这些命令来恢复原始的数据

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Octzs8NO-1596442557309)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1596175563353.png)]

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值