redis和jedis分布式相关中间件

Redis一篇文章搞定!

2020-03-08  本文已影响0人  千淘萬漉

1、Redis的的用途和场景

高性能与高并发
各种业务场景如何利用Redis秀操作,可以参考《Redis数据说明》

2、使用不当的后果

3、redis为啥高性能

4、redis的数据类型

string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。

5、redis的过期策略

两种策略组合,保证过期的key一定能删掉。

LRU内存淘汰策略,进行过期key(最近最少使用)的内存释放。可以用LinkedHashMap自己手写一个.

6.redis如何支持高并发

单机redis的并发在几万(高性能的主机可以支撑到10w+),一般会采用主从架构+读写分离,一般是一主多从,主负责写并将数据同步复制到其他的slave节点上去,从节点负责读,所有的读请求都要走从节点,这样可以支撑起一个水平扩展的读高并发架构。

7、redis replication主从复制的核心原理

当启动一个salve节点时,它首先会发送一个psync的命令给master节点,如果是第一次连接,就会触发全量同步,master会异步的生成一份rdb快照文件(无磁盘化复制,内存中创建不会落盘),同时还会将这段时间从客户端收到的所有写命令缓存在内存中。rdb生辰后,发送给slave节点,slave写入磁盘再加载到内存中,然后master会讲内存中缓存的写命令也同步给slave,slave也会去同步这部分增量数据。

master和slave都会维护一个offset,不仅仅用于全量复制,让master和slave都知道相互之间一个数据一致性情况。

8、断点续传

全量主从复制支持断点续传,master节点在内存中维护了backlog,记录了一个同步的偏移量,如果断线重连以后,会从backlog中记录的偏移量位置开始进行同步,如果没有找到offset就会触发全量同步。

9、redis的高可用机制

redis的高可用是通过哨兵机制来保障的。类似zk,可以实现集群监控、消息通知、故障转移和配置中心的作用。哨兵本身也是分布式的:

a.社区版本推出的原生高可用解决方案

Redis哨兵架构

故障转移的工作流程就是,当Master宕机的时候,Sentinel会选举出新的Master,并根据Sentinel中client-reconfig-script脚本配置的内容,去动态修改VIP(虚拟IP),将VIP(虚拟IP)指向新的Master。我们的客户端就连向指定的VIP即可!

缺陷:
(1)主从切换的过程中会丢数据
(2)Redis只能单点写,不能水平扩容

b.开源Proxy+Replication+Sentinel

前端使用Twemproxy+KeepAlived做代理,将其后端的多台Redis实例分片进行统一管理与分配

HA proxy+KeepLive

每一个分片节点的Slave都是Master的副本且只读;Sentinel持续不断的监控每个分片节点的Master,当Master出现故障且不可用状态时,Sentinel会通知/启动自动故障转移等动作;Sentinel 可以在发生故障转移动作后触发相应脚本(通过 client-reconfig-script 参数配置 ),脚本获取到最新的Master来修改Twemproxy配置。

缺陷:
(1)部署结构超级复杂
(2)可扩展性差,进行扩缩容需要手动干预
(3)运维不方便

10、redis哨兵的选举算法

判断master失败的两种状态:

如果一个master被认为odown,且majority哨兵都允许了准备切换,选举一个slave为一个master。

source: 史上最全 Redis 高可用解决方案总结

11、redis挂掉以后的数据恢复(持久化机制)

redis持久化主要功能就是为了保证灾难恢复,数据恢复。可以归类于高可用。关于持久化的AOF和RDB,二者区别介绍如下:

12、RDB中save和Bgsave的区别?

Redis提供了2个命令来创建RDB文件,一个是SAVE,另一个是BGSAVE。

BGSAVE命令可以在不阻塞服务器进程的情况下执行,所以推荐使用BGSAVE命令。

13、RDB和AOF如何选择?

可以综合使用,用AOF来保证数据不丢失,作为恢复数据的第一选择;用RDB来做冷备,在AOF或者磁盘损坏不可用的情况下,还有RDB作为快速恢复的手段。

source: 阿里二面:熟悉Redis?讲讲你理解的Redis的持久化机制(RDB、AOF)

14、Redis的架构选择

15、Redis Cluster

客户端与Redis节点直连,不需要中间Proxy层,直接连接任意一个Master节点;根据公式HASH_SLOT=CRC16(key) mod 16384,计算出映射到哪个分片上,然后Redis会去相应的节点进行操作

Redis cluster架构

具有如下优点:
(1)无需Sentinel哨兵监控,如果Master挂了,Redis Cluster内部自动将Slave切换Master
(2)可以进行水平扩容
(3)支持自动化迁移,当出现某个Slave宕机了,那么就只有Master了,这时候的高可用性就无法很好的保证了,万一Master也宕机了,咋办呢? 针对这种情况,如果说其他Master有多余的Slave ,集群自动把多余的Slave迁移到没有Slave的Master 中。

缺点:
(1)批量操作是个坑(mget)
(2)资源隔离性较差,容易出现相互影响的情况。

source: 那些年用过的Redis集群架构(含面试解析)

16、Redis cluster的高可用性

整个流程跟哨兵相比,非常类似,所以说,redis cluster功能强大,直接集成了replication和sentinal的功能。不过在通信协议上整个采用了gossip协议,跟集中式的哨兵协议不同,不是将集群元数据(节点信息,故障,等等)集中存储在某个节点上,而是互相之间不断通信,保持整个集群所有节点的数据是完整的。其他在判断节点是否当季、节点过滤和选举上的思路都是少数服从多少的思路,基本一致。

17、数据分区的选择

a.哈希取余分区

哈希取余分区思路非常简单:计算 key 的 hash 值,然后对节点数量进行取余,从而决定数据映射到哪个节点上。
该方案最大的问题是,当新增或删减节点时,节点数量发生变化,系统中所有的数据都需要重新计算映射关系,引发大规模数据迁移。

b.一致性哈希分区

一致性哈希算法将整个哈希值空间组织成一个虚拟的圆环,如下图所示,范围为 0-2^32-1。对于每个数据,根据 key 计算 hash 值,确定数据在环上的位置,然后从此位置沿环顺时针行走,找到的第一台服务器就是其应该映射到的服务器。

与哈希取余分区相比,一致性哈希分区将增减节点的影响限制在相邻节点。一致性哈希分区的主要问题在于,当节点数量较少时,增加或删减节点,对单个节点的影响可能很大,造成数据的严重不平衡;同时也需要保证节点能够均匀分布在哈希环,使得缓存数据能够均匀分布。

c.带虚拟节点的一致性哈希分区(哈希槽)

该方案在一致性哈希分区的基础上,引入了虚拟节点的概念。Redis 集群使用的便是该方案,其中的虚拟节点称为槽(slot)。槽是介于数据和实际节点之间的虚拟概念;每个实际节点包含一定数量的槽,每个槽包含哈希值在一定范围内的数据。引入槽以后,数据的映射关系由数据 hash->实际节点,变成了数据 hash->槽->实际节点。在使用了槽的一致性哈希分区中,槽是数据管理和迁移的基本单位。槽解耦了数据和实际节点之间的关系,增加或删除节点对系统的影响很小。槽的数量一般远小于 2^32,远大于实际节点的数量;在 Redis 集群中,槽的数量为 16384

数据映射

Redis 集群将数据映射到实际节点的过程:

source: 深入学习 Redis 集群搭建方案及实现原理

18、缓存雪崩

故障原因:redis挂了
事前:redis高可用,主从+哨兵,redis cluster,避免全盘崩溃
事中:本地cache缓存 + hystrix限流&降级,避免MySQL被打死
事后:redis持久化,快速恢复缓存数据

故障原因2:缓存时采用了相同的过期时间,导致缓存在某一时刻同时失效
将缓存失效时间分散开,比如我们可以在原有的失效时间基础上增加一个随机值,比如1-5分钟随机,这样每一个缓存的过期时间的重复率就会降低,就很难引发集体失效的事件。

19、缓存穿透

缓存穿透是指缓存和数据库中都没有的数据,而用户不断发起请求,如发起为id为“-1”的数据或id为特别大不存在的数据。这时的用户很可能是攻击者,攻击会导致数据库压力过大。解决办法有两个:

20、数据库与缓存一致性

Cache Aside Pattern,基本都采用如下的缓存模式:

更新操作中为啥是直接删除而不是更新?
更新缓存的代价是很高的,删除缓存,而不是更新缓存,就是一个lazy计算的思想,不要每次都重新做复杂的计算,不管它会不会用到,而是让它到需要被使用的时候再重新计算。

21、高并发情况下如何保证一致性

还是应用上面的缓存模式来看:数据发生了变更,先删除了缓存,然后要去修改数据库,此时还没修改
一个请求过来,去读缓存,发现缓存空了,去查询数据库,查到了修改前的旧数据,放到了缓存中,数据变更的程序完成了数据库的修改,此时就会出现缓存和数据库中数据不一致的情况!

数据库与缓存更新与读取操作进行异步串行化
更新数据的时候,根据数据的唯一标识,将操作路由之后,发送到一个jvm内部的队列中,读取数据的时候,如果发现数据不在缓存中,那么将重新读取数据+更新缓存的操作,根据唯一标识路由之后,也发送同一个jvm内部的队列中,一个队列对应一个工作线程,每个工作线程串行拿到对应的操作,然后一条一条的执行

这样的话,一个数据变更的操作,先执行,删除缓存,然后再去更新数据库,但是还没完成更新。此时如果一个读请求过来,读到了空的缓存,那么可以先将缓存更新的请求发送到队列中,此时会在队列中积压,然后同步等待缓存更新完成。

22、生产环境中的redis是怎么部署的?

redis-cluster模式,企业数据架构组维护,10台机器,5主+5从,每个主实例挂了一个从实例,5个节点对外提供读写服务,单节点qps峰值可能可以达到每秒2万,5台机器并发峰值为10万读写请求/s

机器是什么配置?(4c8g或者8c16g),但是分配给redis进程的是内存,一般线上生产环境,redis的内存尽量不要超过10g,超过10g可能会有问题。给分配了一半4g。

高可用策略:因为每个主实例都挂了一个从实例,所以是高可用的,任何一个主实例宕机,都会自动故障迁移,redis从实例会自动变成主实例继续提供读写服务.

往内存里写的是什么数据?每条数据的大小是多少?用户登陆,每条数据是2k。1000个用户2m,50万条数据是1g。仅仅不到总内存的1/4。

目前高峰期每秒就是3000左右的请求量。

上一篇下一篇

猜你喜欢

热点阅读