赞
踩
- redis确保了再内存紧张的情况下,仍然能够保持高效的性能。选择合适的淘汰策略很重要。它
- 取决于你的应用场景和你希望如何权衡存储和性能。使用redis的时候,建议经常去监控内存的
- 使用情况,并根据需要去调整淘汰策略。
-
- redis中的淘汰策略:内存在使用率达到maxmemory上限时的一种内存释放行为。redis里面提
- 供了很多种内存淘汰算法。主要分为四类:
- 1.random算法:随机移除某个key
- 2.ttl算法:在设置过期期间的key中,去把更早过期时间的key有限的移除。
- 3.lru算法:移除最近很少使用的key,是一种比较常见的内存淘汰算法。在redis里面,会维护
- 一个大小为16的候选池(数据根据时间进行排序,然后每次随机取出5个key放到候选池里面,当
- 满了以后,访问时间间隔最大的key就会从候选池中取出来淘汰掉)
- 缺点:假如说一个key的访问频率很低,但是最近一次偶然被访问到,LRU就会认为这是一个热key,
- 从而不会被淘汰掉。
- 4.lfu算法:为了修补lru算法的漏洞,在redis4里面增加了一个LFU算法。相比较LRU来说,LFU
- 增加了访问频率这个维度,来统计数据的热点情况。LFU的主要设计是使用了两个双向链表组成了一
- 个二维双向链表一个链表用来保存访问频率。另一个链表用来保存频率相同的所有元素。当添加元素
- 的时候访问次数默认是1,于是找到相同访问频次的节点,然后添加到相同频率节点对应的双向链表
- 的头部。当这个key被访问的时候,就会增加对应key的访问频次。并且把当前访问节点移动到下一个
- 访问频次的节点。
- 在这个方案中,
redis持久化AOF和RDB区别,分别解决什么场景?
- 为了解决发生宕机后数据持久化的问题,redis提供了两种持久化策略:
- RDB:在指定的时间间隔内,把内存的数据集快照写入磁盘(也就是保留某个时间点的数据)
- hash结构:Hash结构的底层数据结构是使用一张全局的Hash表,来保存所有的键值对。这张hash表有多个
- 哈希桶组成,哈希桶的安全元素保存了key和value的指针。(其中key指向的实际的键,value
- 指向的实际的值)
-
- hash冲突:所谓的hash冲突不同的key计算出结果落到同一个哈希桶里面。Redis为了解决哈希冲突问题,采用
- 了**链式寻址法**(采用了链表的方式来保存同一个哈希桶中的多个元素。这个部分的实现和java中
- 的HashMap是一样的)。
-
- 如果出现了大量的key的冲突导致链表过长的情况会导致数据检索效率变慢。redis是如何解决的?
- 解决方案:为了保持高效性,redis会对hash表做rehash的操作,也就是通过增加哈希桶来减少
- 冲突。为了rehash更高效redis还默认使用了两个全局哈希表,一个是用来当前使用称为主hash表,
- 一个用来扩容称为备用hash表。
- 决定redis请求效率的因素主要有三个方面的原因。分别是网络、cpu、内存。
- 在网络层面reids采用了多路复用的设计,提升了整个并发的处理连接数。不过这个阶段Server端的
- 所有IO操作,都是由同一个主线程来处理,这时候IO的瓶颈就会影响到redis端的整体处理性能。所
- 以从redis6.0开始,在多路复用层面增加了多线程的处理来优化IO的处理能力。不过,具体的数据操作
- 仍然是由主线程来处理的。所以我们可以认为redis认为数据IO的处理依然是单线程。从CPU层面来说,
- redis只需要采用单线程就可以了,原因有两个:
- 1.如果采用多线程对于redis中数据操作都需要通过同步的方式来保证数据安全性。这反而会影响redis
- 的性能。
- 2.在Linux系统上,redis通过piplining可以处理100万个请求每秒。而应用程序的计算复杂度主要是
- O(N)或者O(log(N)),不会消耗太多的CPU和内存。
- 最后redis本身的数据结构也做了很多优化。比如通过压缩表来合理的利用内存空间,他通过跳跃表的设计
- 去降低时间复杂度。同时还提供了Hash、String、Set、Zset、List等。不同时间复杂度的数据类型使得
- 我们在不同的开发场景中去选择不同的类型去降低时间复杂度同时适应更多的场景选择。
- 延时队列的场景:它通常用于在未来的某个时间执行某个任务的场景。比如:订单超时的处理
- 、定时任务等
-
- 在redis里面可以使用Zset这个有序集合来实现延时队列,具体的实现方式:
问题:但是消费端需要不断的向redis去发起轮询所以它会存在两个问题
- 问题解析:在企业级的开发中错误使用redis有可能会出现大key的问题,主要考查对于redis性能
- 优化和存储策略的了解
最明显的几个问题:
- 1.内存占用
- 大key占用大量的内存资源导致redis实例的内存压力增加
- 2.网络传输延迟
- 大key的读写操作可能会增加网络传输的延迟影响性能
- 3.持久化备份
- 大key的持久化备份需要更多的磁盘空间和时间
- 提出应对处理Redis大key的策略,能够解释每种策略的优劣和适用场景
- 框架思想:了解redis中数据结构和特性从而能够在实际的开发中去选择合适的存储方案并进行性能优化
- 和资源管理
-
- 解决方案:
- 1.把大key分割成多个小key来存储
- 比如:把一个大的Hash结构分割为小的Hash的结构。每个小的Hash结构代表一部分数据,这样可以减少单个
- key的大小去降低内存的压力。
- 2.搭建redis cluster集群,把key分配到不同的hash slot槽所在的分片上
- 这样可以降低单个redis节点的存储压力
- 3.如果已经存在了大key,可以做数据的拆分和迁移
- 按照业务需求和规则将大key拆分成多个小的key并分布到不同的redis的实例上,然后在迁移完成之后清理
- 到不需要使用的大Key。
- 4.考虑是使用压缩算法进行压缩,去减少存储的空间的占用
- 在存储数据之前对数据进行压缩在读取的时候进行解压缩,以节省存储空间和减少网络传输的数据量
- 5.从业务层面进行分析,了解大key产生的原因,并根据需求和访问模式进行相应优化
- 比如使用更加合适的数据结构优化业务逻辑和设计方案等等。
- 问题解析:在redis中key的过期清理是通过使用定期删除和惰性删除两种机制来实现的。
- 定期删除:redis会隔一段时间执行一次定期删除操作。
- 在每次执行删除的时候,redis会随机抽取一部分的key,并检查它们是否已经过期。如果
- 发现有过期的key就直接删除,并且释放对应的内存空间。这种机制保证了redis能够定期
- 清理掉过期的key,但并不保证所有过期的key都会被立即清理掉。
- 惰性删除:当一个key被访问的时候redis会检测key是否过期则删除并释放相应的内存空间。
-
- 问题解答:当redis中key过期的时候,虽然这个key在逻辑上已经过期了,redis并不会立即
- 释放对应的内存空间。由于redis采用了定期删除和惰性删除来清理key,这两种机制意味着redis
- 中的key的过期清理并不是实时的。所以即使key过期了redis也不会立即清理它们。只有在执行
- 定期删除或者访问的时候才会进行清理操作。因此一些过期的key可能会在一段时间内仍然存在redis
- 中,直到触发了相应的清理机制,会删除或者释放内存。
- 在redis里面有3种过期策略:
- 定时过期:是指每个设置过期时间的key都需要创建一个定时器,到过期时间就会立即对key进行清理
- 这个策略可以立即清除过期的数据,对内存很友好,但是会占用大量的cpu资源从而影响到缓存的响应
- 时间和吞吐量。
-
- 惰性过期:是指被动访问某个key的时候,才会判断可以是否已过期,过期则清除。这策略可以最大化
- 的节约CPU的资源,但是对内存非常不友好。在极端情况下,可能会出现大量过期的key没有被再次访
- 问,从而不会被清除导致占用大量内存。
-
- 这两种方案都有点极端所以在redis里面采用了另外一种折中的方案:
- 定期过期:折中方案会周期性轮询redis库中的时效性数据,采用随机抽取的策略,利用过期数据占比
- 的方式控制删除频率。这种方式可以调整定时扫描的时间间隔和每次扫描的耗时来实现在不同情况下使
- 得CPU和内存资源达到一个最优平衡的效果。而在redis里面同时使用了惰性过期和定期过期这两种策
- 略。
- 1.当redis使用内存达到一个maxmemory的参数配置阀值的时候,redis就会根据配置的内存的
- 淘汰策略把访问不高的key从内存里面移除掉。maxmemory的默认值是服务器的最大内存。
- 2.redis默认提供了八种缓存淘汰策略。这八种缓存淘汰策略总的来说归类成五种:
- 第一种,采用LRU策略,就是把不经常使用的key直接淘汰掉
- 第二种,采用的是LFU的策略,它在LRU的算法上做了一些优化,增加了数据的访问频次。从而去
- 确保淘汰的数据是非热点的。
- 第三种,是随机策略,也就是说它随机删除一些key。
- 第四种,ttl策略,它是从设置到过期时间的key里面,挑选出过期时间最近的一些key,进行优先
- 淘汰。
- 第五种,直接报错,当内存不够的时候,直接抛出一个异常。这是默认的一个处理策略。
- 这些策略我们可以直接在redis.conf这个文件里面去手动配置和修改,我们可以根据缓存类型和
- 缓存使用的场景去选择合适的淘汰策略。
- 3.在使用缓存的时候建议增加这些缓存的过期时间,我们知道缓存大概得一个生命周期,从而去更好
- 的利用缓存。
问题解析: redisServer本身是一个线程安全的K-V数据库。也就是在redis Server上执行的指令不需要任何 同步机制,不会存在线程安全问题。虽然在redis6.0里面增加多线程的模型,但是这部分增加的线程 只是用来处理网络IO事件,对指令的执行是由主线程来执行(所以不会存在多个线程同时执行指令操作 的情况)。 至于为什么redis没有采用多线程来执行命令,我认为有几个方面的原因: 1.redis Server本身可能出现的性能瓶颈点,无非就是网络IO,CPU,内存。但是CPU并不是redis的 瓶颈点,所以没有必要去使用多线程来执行指令。 2.如果采用多线程意味着对于redis的所有指令操作都 必须要考虑线程安全问题,也就是说需要加锁来解决。这种方式带来的性能影响反而更大。 3.在redis的客户端虽然redis server中的指令执行是原子的,但是有如果有多个redis客户端同时 执行多个指令的时候,就无法保证多个操作原子性。假设两个redis client同时获取redis server 里面的key1同时进行修改和写入。因为多线程环境下的原子性无法被保障,以及多进程情况下共享资源 的访问竞争问题。使得对于redis server的数据操作是不安全的。 但是对于客户端层面的线程安全问题,解决方法有很多: 比如尽可能的使用redis里面的原子指令或者对多个客户端的资源访问加锁,或者通过lua脚本来实现多 个指令的操作等等。
- redis中的keys命令用于返回匹配指定规则的所有键。类似于数据库里面like模糊查询匹配功能。
- 主要考查对redis性能和可靠性的了解以及对redis的使用最佳实践的熟悉程度。
-
- 问题解答:
- 使用keys命令可能会存在几个潜在的问题:
- 1.性能问题:keys命令需要遍历整个redis的键空间,如果redis中的key数据非常大,遍历过程非常
- 耗时从而影响性能。
- 2.阻塞问题:keys命令是一个阻塞命令,它会阻塞所有其他客户端对数据库的访问,直到keys命令结束。
- 因此执行keys命令失败会导致redis服务器可能会暂时停止响应其他请求,导致服务不可用或响应变慢。
-
- 在生产环境下禁止使用keys命令特别是在数据量较大的集群环境中,一旦因为keys命令阻塞了redis的操作
- 就有可能使得集群判断redis出现故障从而出现故障恢复,引发数据混乱和雪崩等问题。
r
- redis作为一个高性能缓存中间件, 除了拥有高性能特点之外。相比较其他缓存而言还支持
- 多种数据结构。比如说String、List、set、zset、hash都是redis中常见的数据结构。然
- 而redis中的这些数据结构的底层实现和我们传统意义上理解的List、set的实现是不一样的。
- redis针对不同类型的数据结构进行了优化,会根据不同的数据采用不同数据结构来进行存储。
-
- 一般来说,涉及到数据结构底层的优化大多数是指着时间复杂度的优化。比如ConcurrentHashMap中, 链表转红黑树的设计其实就是O(n)的时间复杂度向O(logn)的时间复杂度进行一个优化。在redis的不同数据结构中每一种结构的底层实现也是有所不同的。比如String类型,底层会根据存储
- 字节长度大小来选择embstr或者raw的编码方式。再比如List类型中采用了ziplist+quicklsit
- 来实现。其中ziplist表示压缩列表(压缩列表:就是按照数据实际大小来分配存储空间,比如说一个int类型占4个字节,但是它的值是1的情况下意味着只需要一个字节就可以存储这样既可以去节省内存的使用又可以保存内存的连续性,避免内存碎片的问题)
-
- 另外再数据结构中,还有一种常见的空间换时间的设计方式。比如说:zset里面使用了ziplist跳跃表,由于链表的时间复杂是O(n),于是通过在链表上增加多层稀疏索引,使得链表的数据查找变成了一个类似于二叉的形式,使得数据查找的时间复杂度可以降低到O(logn)的这样一个级别。
-
- 最后在redis中还有一个比较经典的空间换时间的设计就是早期的LRU算法,通过hash表和双向链表的结合。解决了链表时间复杂度的问题,如果想去定位链表中的元素可以去hash表中找到key对应的对象地址,然后基于该对象地址去访问链表即可。时间复杂度就会从O(n)变成O(1)的一个常量复杂度。
-
- 除此之外redis中还有很多好的优化的一个思想,数据结构的使用技巧非常多,可以从一些优秀开源的组件中去学习和借鉴这些优秀设计方案。
- redis-cluster集群模式使用了hash槽(hash slot)来实现数据的分片,hash slot默认长度是16384。应用程序去存储一个key的时候会通过key进行CRC16计算
- 在取模以后路由到对应的hashslot所在的节点。
-
- 一般情况下对于一个中间件某个特定阀值的设计,都是通过相关的计算和测试得到
- 一个相对比较合适的值。对于redis中的Hash slot为什么是16384这个问题我认
- 为有以下几个考虑因素:
- 1.对于网络通信开销平衡, redis集群中每个节点会发送心跳信息,而心跳包中携
- 带节点的完整配置。它能够以幂等性的方式来实现配置的更新。 如果采用16384个
- 插槽,而每个插槽信息就会用的位数是1。因此每个节点需要维护的配置信息占用的
- 空间大小就是16384/节点数量/8 KB。假设3个节点的集群,那么每个节点维护的配
- 置信息,占用的空间的大小是2KB。其次,CRC16算法产生的hash值有16位,如果
- 按照2^16次方计算,得到一个65536这个槽,那就会导致每个节点维护的配置信息。每个节点维护的配置信息占8kb,8kb数据的心跳包看起来不大,但是这个心跳每一
- 秒都需要把当前节点的信息同步集群中的其他节点。相比于16384这个hash slot
- 整体增加了4倍。这样会对网络带宽带来了极大的浪费,并且这个浪费并没有带来更
- 好的效果。
-
- 2.集群规模的限制redis cluster不太可能扩展到1000个主节点,太多的节点可
- 能会导致网络拥堵等问题。因此在这样一个条件限制下,采用16384这个插槽范围比
- 较合适。
-
- 3.16384个插槽可以确保每个master节点都有足够的插槽,可以确保每个master
- 节点都有足够的插槽,同时也可以保证插槽的数目过多或者过少。
-
- 从而保证了redis Cluster的集群的稳定性和高性能。16384这个槽的数量是经过
- 考虑和实践得出的。既可以满足redis集群的性能要求又可以保证管理复杂度和通
- 信的开销的可控性。
- 但是数据是存储在内存中的这就意味着如果服务宕机了,数据有可能会丢失。为了解决
- 这个问题, redis提供了两种持久化策略:
- RDB持久化是指在指定的时间间隔内,把内存中的数据集快照写入磁盘。(也就是只保留
- 某个时间点的数据) 它的实际操作过程是fork一个子进程。先把数据集写入到一个临时
- 文件,写入成功以后再替换之前的文件,用二进制进行压缩存储。
-
- AOF而AOF持久化会记录服务器接收的所有写操作命令并且把命令追加到一个文件里面,
- 持久化到磁盘上。在服务器启动的时候通过重新执行这些命令来还原数据。
-
- 考查:
- 1.对redis持久化机制的理解程度
- 2.对不同持久化策略在实际应用中的选择和优化
- 更有效的去保证数据的安全性和一致性
-
- RDB的优点:恢复大数据集的速度比AOF快,对CPU和内存的影响比较小。它更加适用于
- 需要做冷备份,对数据的恢复要求不高的场景。因为它是间隔一顿时间进行持续化d,如果在
- 这个时间段内redis发生宕机。那么这些数据就会被丢失,
-
- AOF的优点:更加稳定,数据的完整性更好。因为它记录了每一个写操作,但是AOF的文件
- 越来越大,可能会影响到redis的性能。 因此AOF更加适用于对数据安全性要求比较高的场
- 景。比如购物车、订单等关键业务。
-
- 同时在实际应用中,也可以同时开启RDB和AOF进行持久化,以便结合两者的优点。
- 具体采用哪种持久化策略需要根据业务需求和系统环境进行权衡。
-
- 如何优化AOF持久化的几种策略:
- 每秒同步一次
- 每修改一次数据就同步一次
- 或者不同步
-
- 我们可以根据业务的性能和数据安全性需求进行选择
- redis里面的Master-Slave集群是不具备故障恢复能力的。也就是master节点挂了以后
- 需要从集群中的其他Slave节点去选举一个新的Master继续提供服务。因此在redis里面
- 引入了Sentine哨兵机制。通过哨兵来监控集群的一个状态,实现master选举。哨兵是一种
- 单独的进程,所以为了保证哨兵的可靠性,会对哨兵做集群部署。
-
- 假设哨兵节点有3个那这个时候分别去监听redis里面的3个主从节点,一旦redis主从集群的
- 某个节点出现故障,而故障节点被其中一个sentine哨兵节点检测到,但是另外两个节点还没
- 有检测到,那3个哨兵节点如何在意见上达成一致的。同时哨兵节点怎么去判断哪一个是slave
- 节点应该成为Master呢?
-
- 当redis集群中的Master节点出现故障哨兵节点检测到以后,会从redis集群其他slave节点中
- 去选举一个作为新的Master。具体的判断依据有两个部分:
- 第一部分:筛选
- 第二部分:综合评估
- 在刷选阶段,会过滤掉一些不健康的节点, 比如下线或者断线的节点或者没有回复Sentinel哨兵
- 响应的slave节点。 同时还会评估实例过往的网络连接情况,如果在一定时间内slave和master
- 经常性断链而且超过一定的阈值也不会考虑。
-
- 经过筛选之后剩下的都是一些健康节点了,然后对健康节点进行一个综合评估了。具体有三个
- 维度按照顺序去判断:
- 1.根据slave优先级来判断,通过slave-priority配置项,可以给不同的从库设置不同的
- 优先级,优先级高的优先成为master。
- 2.选择数据量偏移量差距最小的,其实就是比较slave和原master复制进度差距,避免丢失
- 过多的数据的问题。
- 3.slave runID,在优先级和复制进度都相同的情况下,runID越小说明创建时间越早,优
- 先选为master
- 按照以上步骤就可以选择一个新的master节点,另外哨兵出现集群的情况下,其中一个哨
- 兵节点认为redis集群出现故障,另外两节点还没有感知的情况下在进行master选举之前
- sentinel需要通过共识算法来达成一致,这里用到了Raft协议。
-
- redis主从复制是指redis集群里面Master节点和slave节点的数据同步的一种机制,就是
- 把一台redis服务器数据复制到其他redis服务器里面。其中负责数据来源的节点称为master
- 被动接收数据同步的节点称为slave。
- 在redis里面提供了全量复制和增量复制两种模式,全量复制一般都是发生在slave
- 节点初始化的阶段。需要把master上的所有的数据全部都copy一份,它的工作原理:
- 1.slave服务器连接master,并发送sync命令,master收到命令后会生成数据快照;
- 2.把数据快照发送给slave节点,slave节点收到数据以后丢弃旧的数据并重新载入新的数据,
- 然后对外提供服务。(在主从复制的过程中,redis并没有采用数据的强一致性,因此会存在
- 一个数据同步的延迟,导致数据的一个不一致的问题)
-
- 增量复制就是说master收到数据变更之后,就是说master收到数据变更之后会把变更的数据
- 同步给所有的slave节点,它的原理:
- master和slave都会维护一个复制偏移量叫offset,用来表示master向slave传递字节
- 数量,每一次进行增量数据的传递master和slave维护的offset都会增加对应的字节
- 数。redis只需要根据offset就可以实现增量的数据的同步。
-
-
- 回答:redis的主从分布包括全量复制和增量复制,全量复制发生在初始化阶段从节点会主
- 动向主节点发起一个同步请求,那么主节点收到请求以后会生成一份当前数据的快照发送从
- 节点,从节点收到数据进行加载之后完成全量复制。
- 增量复制是发生在每一次master节点发生数据变更的一个场景里面,会把变化的增量数据同步
- 给从节点,增量复制是通过维护offset这样一个复制偏移量来实现的。
-
- 首先redis本身是一个基于key-value结构的内存数据库。而redis的一个设计者,
- 为了避免redis故障导致数据丢失的问题,提供了RDB和AOF两种持久化的一个机制。
- RDB是通过快照的方式来实现持久化,也就是就会根据快照的一个触发条件。把内存
- 里面的数据快照写入到磁盘里,以二进制的压缩文件的方式进行存储。RDB快照的触
- 发方式有很多:
- 1.执行bgsave命令触发异步快照,执行save命令触发同步快照,同步快照会阻塞
- 客户端的执行指令;
- 2.根据redis.conf文件里面的配置,自动触发bgsave;
- 3.主从复制的时候触发;
- AOF的持久化,它是一种近乎实时的方式,把redis server执行的事务命令进行追加
- 存储。客户在执行一个数据变更的操作,redis就会把这样一个命令追加到aof的缓冲
- 区里面,然后再把缓冲区的数据写入到磁盘的aof文件里面。最终什么时候真正把数据
- 持久化到磁盘的aof文件里面,是根据磁盘的刷盘策略来决定的。
- 另外aof这种指令追加的一个方式会造成aof文件过大带来明显的io性能问题。所以redis
- 是针对这样的一个情况,提供了aof重写机制。当aof文件大小达到某一个阈值的时候
- 就会将相同的指令进行压缩。
-
- 优缺点:
- 1.RDB是每隔一段时间触发持久化,因此数据安全性低,aof可以做到实时持久化,数据安
- 全性较高。
- 2.RDB文件默采用压缩的方式持久化,AOF存储的是执行指令,所以RDB在RDB在数据恢复
- 的时候性能比AOF要好。
- 所谓的优缺点是当前方案更适合当前应用场景而已。
√
- AOF是redis里面提供了一种数据持久化的一个方式,采用了指令追加一个方式
- 去近乎实时的去实现数据指令的一个持久化。 因为通过AOF这种方式会把每一个
- 数据更改的一个操作指令追加并且存储到AOF文件里面。所以很容易导致aof文件
- 过大造成io性能的一个问题。redis为了解决这个问题设计出一个aof重写的机制。
- 也就是把aof文件里面的相同的指令进行压缩,只保留最新的一个数据操作的指令。
- 简单来说,就是如果AOF文件里面存储了某个key的多次并更记录,但实际上正在
- 数据恢复的时候只需要执行最新的数据操作指令就可以了。历史数据就没有必要存
- 在这样一个文件里面去占空间。AOF文件的重写具分为几个步骤:
-
- 1.首先,根据当前的redis内存里面的数据,重新构建一个新的aof文件。
- 2.然后,读取当前reids里面的数据写入到新的AOF文件里面
- 3.最后,重写完成以后,用新的AOF文件覆盖现有的AOF文件
-
- 另外因为AOF文件在重写的过程中,需要去读取当前内存里面所有的键值的一个数据,
- 再去生成对应的一个新的指令去进行保存。而这个过程很明显会比较耗时,所以对业
- 务会产生影响。于是redis把重写这样一个过程放在后台的一个子进程中去完成,这样
- 子进程再做重写的时候主进程依然可以处理客户端的一个请求。为了避免子进程在
- 重写的过程中,主进程的数据发生变化导致AOF文件里面的数据和redis内存中
- 数据不一致的一个问题。redis还做一层优化,子进程再做重写的这个过程中,主进程
- 的数据变更需要追加到aof的重写缓冲区里面,等到AOF文件重写完成以后,再把AOF
- 重写缓冲区里面的数据追加到新的AOF文件里面。 这样就可以保证新的AOF文件里面
- 的数据和redis内存数据是一致的。
-
- 注意:数据持久化和重写这样的过程中如何去避免对客户端产生影响,还需要保证数据
- 的数据一致性
- redis集群有几种实现方式,一个是主从集群,一个是redis cluster就是在redis集群里面
- 包括一个master节点和多个slave节点。master节点负责数据的读写,slave节点负责数据的
- 读取。master节点收到数据变更会同步到slave节点上。通过这样一个架构可以去实现redis的
- 读写分离,提升数据的查询效率。但是redis主从集群不提供容错和恢复的功能,一旦master节
- 点挂了,不会自动选取新的Master导致后续的客户端所有的写请求直接失败。
- 所以redis提供了哨兵机制,专门用来监听redis主从集群提供故障的,的自动恢复能力。哨兵
- 会监控redis主从节点的一个状态。当master节点出现故障的时候,会自动从剩下的slave节点
- 里面去选举出一个新的master。哨兵模式下虽然解决了master选举的一个问题,但是在线扩
- 容的问题还没有解决。
- 于是就有了第三种集群方式:redis cluster,它实现了redis的分布式存储,
- 也就每个节点存储不同的数据实现数据的分片功能。在redis cluster里面引用了slot槽
- 来实现数据分片。(slot的取值范围是0-16383)每个节点会分配一个slot区间,当存取key
- 的时候
- redis会根据key去计算slot值,然后找到对应的节点进行数据读写。在高可用方面,redis
- cluster引入了主从分布的一个模式。一个master节点对应一个或者多个slave节点。
- 当master节点出现故障的时候会自动从slave节点去选举出一个新的master继续提供服
- 务。redis cluster虽然解决了在线扩容以及故障转移的能力但也有缺点。
- 缺点:
- 1.客户端的实现会更加复杂
- 2.slave节点只是一个冷备节点不提供分担读操作的压力
- 3.对于redis里面的批量操作指令会有限制
- 因此主从模式和cluster模式各有优缺点,根据场景需求来进行选择
-
- 回答:
- redis集群有两种:1.主从复制 2.redis cluster
- 1.redis哨兵集群是基于主从复制来实现的,所以可以实现读写分离,分担redis读操作
- 的压力;而redis cluster集群里面的slave节点只是实现冷备的一个机制,只有在
- master宕机之后才会工作。
- 2.redis哨兵集群无法在线扩容所以并发压力受限于单个服务器资源的一个配置。reids
- cluter提供了基于slot槽的一个数据分片的一个机制,可以实现在线扩容提升读写性能。
- 3.从集群的架构来说redis哨兵集群是一主多从,而redis cluster是一个多主多从的
- 一个机制。
-
-
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。