面试问Redis集群,被虐的不行了......(1)

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: 面试问Redis集群,被虐的不行了......

本文主要围绕如下几个方面介绍集群

  • 集群简介
  • 集群作用
  • 配置集群
  • 手动、自动故障转移
  • 故障转移原理



本文实现环境

  • centos 7.3
  • redis 4.0
  • redis工作目录 /usr/local/redis
  • 所有操作均在虚拟机模拟进行



Redis集群


本文主要围绕如下几个方面介绍集群

本文实现环境

一、集群简介

二、集群作用

三、集群存储结构

1. 存储结构

2. 通讯设计

四、配置集群

1. 修改配置文件

2. 构建6个节点的配置文件并全启动

3. 安装ruby

4. 启动集群

5. 集群设置与获取数据

五、故障转移

1. 集群从节点下线

2. 集群主节点下线

3. 新增主节点

4. 手动故障迁移

六、故障转移原理篇

1. 故障发现到确认

2. 故障恢复(从节点从此翻身奴隶把歌唱)

你们想要的ssh的背景!!!




一、集群简介

集群是为了解决主从复制中单机内存上限和并发问题,假如你现在的云服务内存为256GB,当达到这个内存时redis就没办法再提供服务,同时数据量能达到这个地步写数据量也会很大,容易造成缓冲区溢出,造成从节点无限的进行全量复制导致主从无法正常工作。



image.png



那么我们就需要把单机的主从改为多对多的方式并且所有的主节点都会连接在一起互相通信。这样的方式既可以分担单机内存,也可以分发请求,提高系统的可用性。


如图:当有大量请求写入时,不再会单一的向一个主节点发送指令,而会把指令进行分流到各个主节点,达到分担内存、避免大量请求的作用。


那么指令是如何进行分流存储的呢!我们就需要到集群存储结构中一探究竟。


image.png


二、集群作用

  • 分散单机的存储能力,同时也可以很方便的实现扩展。
  • 分流单机的访问请求
  • 提高系统的可用性

如何理解提高系统的可用性这句话,我们看下图,当master1宕机后对系统的影响不会那么大,仍然可以提供正常的服务。


这个时候就会有人问了,当master1宕机后集群这个时候怎么工作呀!这个问题会在下文的故障转移来给你解答。并且在原理篇会对这个问题进行详解


image.png


三、集群存储结构

1. 存储结构

单机的存储是当用户发起请求后直接把key存储到自己的内存即可。



image.png


集群的存储结构就没有那么简单了,首先当用户发起一个key指令后需要做的事情。


  • 通过CRC16(key)会计算出来一个值
  • 用这个值取模16384,会得到一个值,我们就先认为是28
  • 这个值28就是key保存的空间位置

那么现在问题来了,这个key到底应该存储在那个redis存储空间里边呢!


image.png


其实redis在集群启动后就已经把存储空间划分了16384份,每台主机保存一部分。


这里需要注意的是我给每个redis存储空间里边的编号就相当于一个小的存储空间(专业术语“哈希槽”),你可以理解为一栋楼里边的编号,一栋楼就是redis的整个存储空间,每个房子的编号就相当于一个存储空间,这个存储空间会有一定的区域来保存对应的key,并非上图取模后的位置。


箭头指向的28是指的28会存储在这个区域里,这个房子有可能会存储29、30、31等。


image.png


此时问题来了,如果新增、减少一台机器后怎么办呢!看图说话,能用图说明尽量不去用文字。


在新增一台机器后,会从其他三个存储空间中拿出一定的槽分配给新的机器。这里可以自己设置想给新的机器放多少个槽。


同样减少一台机器后会把去掉的槽在重新分配给其它现有的机器跟新增节点一样,可以指定节点接收槽。


所谓的增节点或去节点就是改变槽所存储的位置不同。


image.png


了解了集群的存储结构后,我们就需要在对另一个问题进行说明了,集群是如何设计内部通讯呢!来了一个值,获取一个key,去哪拿数据,跟着这个问题我们看下文。


2. 通讯设计

集群中的每个节点会在一定的时期给其它节点发送ping消息,其它节点返回pong作为响应。经过一段时间后所有节点都会知道集群全部节点的槽信息。


如下图有三个节点,那么就会把16384个哈希槽分成三份。


分别为0-5500、5501-11000、11001-16384


当用户发起了一个key的请求,集群是如何处理请求的呢!


下图的黑框代表这集群所有节点的槽信息,里边还有很多其它信息。


image.png


如图所示,用户发起请求key,redis接收后计算key的槽位置,在根据槽位置找出对应的节点


如果访问的槽就在节点本身,那么就会直接返回key对应数据。


否则会回复moved重定向错误, 并且给客户端返回正确的节点。


然后重发key指令


image.png


四、配置集群

1. 修改配置文件


image.png


只需要注意咔咔圈中的配置信息即可


  • cluster-enabled yes:开启集群模式
  • cluster-config-file nodes-6379.conf:集群配置文件
  • clustre-node-timeout 10000:节点超时时间,这里为了方便测试设置为10s


image.png


2. 构建6个节点的配置文件并全启动

咔咔给大家提供一个命令可以很方便的替换文件sed 's/6379/6380/g' 6379-redis.conf > 6380-redis.conf


按照这样的方式创建出来6个不同端口的配置文件


image.png


随便打开一个配置文件查看,检测是否替换成功


image.png


为了查看日志信息方便,全部使用前台启动。并且查看服务是否都正常启动,执行命令ps -ef | grep redis


可以看到启动后多了个cluster标识,代表着都是集群的一个节点。


image.png


所有节点启动完成,集群启动的指令需要基于ruby(咔咔使用redis版本为4.0)。接下来一起安装


3. 安装ruby

执行命令wget https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.1.tar.gz


解压:tar -xvzf ruby-2.7.1.tar.gz 根据自己下载的版本来解压


安装:./configure | make | make install这三个指令一气呵成。


查看ruby和gem版本:ruby -v


image.png


4. 启动集群

集群的执行命令在/usr/local/redis/src/redis-trib.rb


注意如果需要直接使用redis-trib.rb命令,需要ln到bin目录下,否则就必须使用./redis-trib.rb的方式。


如果按照步骤走,这里会出现一个错误


image.png


执行gem install redis很不幸的是在这里也会出现错误。


image.png


随后需要安装yum install zlib-devel和yum install openssl-devel


安装完成后,在/ruby-2.7.1/ext/openssl 和 /ruby-2.7.1/ext/zlib 分别执行ruby extconf.rb并且执行make | make install

然后在执行gem install redis就OK


image.png



这时在回头来执行./redis-trib.rb create --replicas 1 127.0.0.1:6379 127.0.0.1:6380 127.0.0.1:6381 127.0.0.1:6382 127.0.0.1:6383 127.0.0.1:6384


image.png


信息解读


image.png


创建集群,并且给6个节点分配哈希槽,后三个节点配置为前三个节点的从节点


显示每个节点的哈希槽信息和节点ID,最后一步需要输入yes


image.png


来到data目录下查看配置文件的变化。配置文件主要信息是每个主节点分的槽


image.png

image.png

查看主机点的运行日志


这里给的主要信息cluster status changed:ok 集群状态正常


image.png


5. 集群设置与获取数据

当直接设置数据会报错,并且把name这个key进行转化后的槽位置为5798 并且给出了ip地址和端口号。


image.png


需要使用命令redis-cli -c


在进行设置值的时候提示说重定向到5798的这个槽


image.png

接下来进行获取数据,会自动的切换节点。

image.png

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
1月前
|
缓存 NoSQL 关系型数据库
大厂面试高频:如何解决Redis缓存雪崩、缓存穿透、缓存并发等5大难题
本文详解缓存雪崩、缓存穿透、缓存并发及缓存预热等问题,提供高可用解决方案,帮助你在大厂面试和实际工作中应对这些常见并发场景。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:如何解决Redis缓存雪崩、缓存穿透、缓存并发等5大难题
|
16天前
|
存储 NoSQL Redis
redis主从集群与分片集群的区别
主从集群通过主节点处理写操作并向从节点广播读操作,从节点处理读操作并复制主节点数据,优点在于提高读取性能、数据冗余及故障转移。分片集群则将数据分散存储于多节点,根据规则路由请求,优势在于横向扩展能力强,提升读写性能与存储容量,增强系统可用性和容错性。主从适用于简单场景,分片适合大规模高性能需求。
27 5
|
29天前
|
存储 NoSQL 算法
阿里面试:亿级 redis 排行榜,如何设计?
本文由40岁老架构师尼恩撰写,针对近期读者在一线互联网企业面试中遇到的高频面试题进行系统化梳理,如使用ZSET排序统计、亿级用户排行榜设计等。文章详细介绍了Redis的四大统计(基数统计、二值统计、排序统计、聚合统计)原理和应用场景,重点讲解了Redis有序集合(Sorted Set)的使用方法和命令,以及如何设计社交点赞系统和游戏玩家排行榜。此外,还探讨了超高并发下Redis热key分治原理、亿级用户排行榜的范围分片设计、Redis Cluster集群持久化方式等内容。文章最后提供了大量面试真题和解决方案,帮助读者提升技术实力,顺利通过面试。
|
1月前
|
存储 NoSQL 算法
面试官:Redis 大 key 多 key,你要怎么拆分?
本文介绍了在Redis中处理大key和多key的几种策略,包括将大value拆分成多个key-value对、对包含大量元素的数据结构进行分桶处理、通过Hash结构减少key数量,以及如何合理拆分大Bitmap或布隆过滤器以提高效率和减少内存占用。这些方法有助于优化Redis性能,特别是在数据量庞大的场景下。
面试官:Redis 大 key 多 key,你要怎么拆分?
|
2月前
|
NoSQL Java API
美团面试:Redis锁如何续期?Redis锁超时,任务没完怎么办?
在40岁老架构师尼恩的读者交流群中,近期有小伙伴在面试一线互联网企业时遇到了关于Redis分布式锁过期及自动续期的问题。尼恩对此进行了系统化的梳理,介绍了两种核心解决方案:一是通过增加版本号实现乐观锁,二是利用watch dog自动续期机制。后者通过后台线程定期检查锁的状态并在必要时延长锁的过期时间,确保锁不会因超时而意外释放。尼恩还分享了详细的代码实现和原理分析,帮助读者深入理解并掌握这些技术点,以便在面试中自信应对相关问题。更多技术细节和面试准备资料可在尼恩的技术文章和《尼恩Java面试宝典》中获取。
美团面试:Redis锁如何续期?Redis锁超时,任务没完怎么办?
|
1月前
|
存储 NoSQL Redis
Redis常见面试题:ZSet底层数据结构,SDS、压缩列表ZipList、跳表SkipList
String类型底层数据结构,List类型全面解析,ZSet底层数据结构;简单动态字符串SDS、压缩列表ZipList、哈希表、跳表SkipList、整数数组IntSet
|
4月前
|
存储 Java
【IO面试题 四】、介绍一下Java的序列化与反序列化
Java的序列化与反序列化允许对象通过实现Serializable接口转换成字节序列并存储或传输,之后可以通过ObjectInputStream和ObjectOutputStream的方法将这些字节序列恢复成对象。
|
1月前
|
存储 缓存 算法
面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!
本文介绍了多线程环境下的几个关键概念,包括时间片、超线程、上下文切换及其影响因素,以及线程调度的两种方式——抢占式调度和协同式调度。文章还讨论了减少上下文切换次数以提高多线程程序效率的方法,如无锁并发编程、使用CAS算法等,并提出了合理的线程数量配置策略,以平衡CPU利用率和线程切换开销。
面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!
|
1月前
|
存储 算法 Java
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
本文详解自旋锁的概念、优缺点、使用场景及Java实现。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
|
1月前
|
存储 缓存 Java
大厂面试必看!Java基本数据类型和包装类的那些坑
本文介绍了Java中的基本数据类型和包装类,包括整数类型、浮点数类型、字符类型和布尔类型。详细讲解了每种类型的特性和应用场景,并探讨了包装类的引入原因、装箱与拆箱机制以及缓存机制。最后总结了面试中常见的相关考点,帮助读者更好地理解和应对面试中的问题。
57 4