首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >慕课网2021-01-29 Redis6直播笔记 - 下(多线程/哈希slot/集群)

慕课网2021-01-29 Redis6直播笔记 - 下(多线程/哈希slot/集群)

作者头像
风间影月
发布于 2021-02-05 06:46:24
发布于 2021-02-05 06:46:24
3960
举报
文章被收录于专栏:BeJavaGodBeJavaGod

io多线程

以前的redis是单线程模型,其实就是多路复用机制,知道多路复用的来一波6,我们在架构师课程中讲过,那么netty也有,看过老师相关课程的也应该知道。这里不多说了。

Redis6开始有了IO读写多线程,只不过执行用户的命令和早期版本也是一样的,都是单线程执行,所以线程安全。

我们先来看一下老版本的单线程:

首先读取客户端的命令,读取后执行命令,然后回写给客户端,这个就是一组命令的执行,由于单线程安全,他们会一组一组的去进行执行。

他们的读写命令以及执行命令都是在一个线程中执行的,这个线程在redis6中称之为主线程。

在这里我们可以回顾一下netty的reactor的线程模型,也就是多路复用。

你可以把这个单线程理解为是一个人,他是酒吧会所的接待员,在门口接待了以后,然后还要领到里面去一个一个的招待他们。

我们可以打开redis.conf配置文件,看一下:

默认情况下,是按照老版本的样子,如果要使用多线程,那么开启即可,这里的io-threads就是设置多线程的数量,开启多线程后,整体的性能要比单线程要更高。

io-threads设置的数量最大不建议超过8,提升的空间不大。另外线程数和服务器的硬件配置也是有关系的。比如4核8g,那么建议设置2或者3,如果8核建议设置6或者7,因为一定要预留,万事兜底万事保底,这一点和nginx的配置也是同样的道理。

假设现在io-threads设置为4,那么他的模型就如下:

那么在这里,读用户的命令以及执行命令都是在一个线程中执行的,然后写操作是多线程执行。在这里如果比作是一个银行的话,那么读操作相当于是门口的保安,给你测个体温,执行就是店里的大堂经理,会带你去取号,多个写操作就是窗口的办事人员。

可以参考一下图:

刚刚我们举例是只有一个人在接待和招待,这个时候接待只有一个人,他只在门口把客人带进里面,里面会有专门的多个招待员来处理这些客人的请求。

读操作能不能设置多线程呢?

如果想要读操作也变成多线程读的话,那么io-threads-do-reads可以开启,设置为yes就行。这个时候他的模型就是下面这张图:

只不过官方说明,这个多线程读开启的意义不大,不会帮助很多的。

这个时候,还是引入刚刚的例子,客人多了,生意好了,门口的接待员增加了,那么两边接待和招待都是多个员工在处理客人了。

那么在这里说明一点,多线程只针对数据的读写以及协议的解析。真正用户端的命令执行还是单线程,所以是线程安全的。

Redis集群原理

其实只要涉及到中间件,那么必定会有集群的概念,一方面为了高可用,一方面为了达到水平扩容,那么这次来讲一下redis的集群。

其实在很早以前,早期的redis版本是没有集群这个概念的,你需要实现集群得依靠一些中间件,比如codis,还有twemproxy。redis集群概念是在3.0开始引入的,它是自带的分布式存储方案,是一个去中心化的集群,叫做Redis Cluster,是由多个主从节点共同存在的一个模式,一般以3主3从为比较经典的模式,当然多主多从也可以。其中master负责读写请求以及整个集群信息的维护,slave只做他所对应的主节点数据和状态信息的复制。

Redis Cluster

关于集群,有两点需要注意

  • 之前我们聊过主从模式,可以做读写分离,redis集群虽然是3主3从,也有主从的概念,但是我们并不会做读写分离,读写都是交给master去处理,数据会同步给slave,如果集群做读写分离一方面没有意义一方面slave就没有容错机制了,这一点是需要注意。
  • 此外还有一点,单节点的redis默认有16个db,但是在集群模式下,这些db都融合了,没有db库的概念,他是一片汪洋大海。

按照单节点,主从,哨兵来说的话,redis始终都可以说是单库,数据存储量是有上限的,你的服务器节点内存有多大,那么这个就是存储上限。一旦到达存储上限,redis就会进行缓存key的自我淘汰机制。很明显,这种方式面对海量数据的时候并不太好,哪怕你买1个t内存的,也总有一天会到达存储瓶颈,所以任何分布式系统我们都要考虑一个水平扩容机制,这个redis集群就可以做到。扩容的同时也满足高可用机制。

同时,使用集群之后,数据其实进行了分片,多个master节点都能够提供读写服务,这样整体集群的响应能力就要比原先单节点来的更好。并且,在集群模式下,任意节点发生故障时,集群还是可以继续对外提供服务,主节点有故障转移的功能。

传统的水平扩容

传统早期的redis扩容方案其实是基于业务层的,在业务层进行redis的分割,可以扩容,可以集群隔离。 我们之前讲过redis主从,以这个为例,当然用哨兵也可以,我们可以手动来实现redis的扩容,先看下图:

上图中的3主3从其实是由3个主从redis构成的,用户在进行set或者get的时候,首先需要对key做哈希,哈希后的值对节点数求模,取模的值就是数据路由到某个主从库里,就针对这个主从库去做set和get的操作,这个哈希原理其实和nginx的ip_hash道理是一样的,数据库分库也是这个道理。目的就是根据key哈希后的结果去寻址找到最终他的存储位置去存值或取值。这个其实就是哈希取模

那么哈希以及寻址的这个过程需要自己在业务层去封装实现,但是本质目的就已经达到了横向扩容,假设每个主从容量是8g,那么目前总容量就是24g,想怎么扩容直接加机器就行。

这这样的情况之下,那么扩容会带来一个弊端,这个弊端也就是哈希取模带来的,一旦有节点宕机或者增加节点,那么就需要重新哈希和求模运算,这么一来会影响所有的缓存数据,这个时候所有数据会重新路由,影响会很大,怎么解决呢?可以使用一致性哈希算法,就是小部分数据受影响,这个我们在架构班里有提到过的吧。

一致性哈希

首先他会有一个域,这个域很长,有2的32次方减1,哈希不仅针对key,也会针对服务器节点,我们这里是redis,如果是服务器集群那么道理也是一样。

Redis集群 - hash slot 算法

上面的传统方式是很古老的,我曾经也见识过一次,我们了解一下就行了。现在都使用redis cluster,这种模式下,redis可以有多个master节点,每个master节点下又可以对应1~n个slave节点,这样会形成一个多主多从的集群模式,这种模式下不再需要向上面讲过的那样需要在业务层去处理,redis自身帮我们做好了存取的过程,我们可以不用过多关注业务过程就可以直接使用和应用了。他自身是基于hash slot的算法来存值的,不论是哪种算法,其实本质为了解决的就是数据分布的问题。

redis集群其实是把数据分片了,由于他有多个master共同构成,他会分数据,他有一个hash slot算法,也可以称之为哈希槽,每个槽上存放了一些数据,slot的范围是0~16384,redis对key的存取会有一个CRC16的算法,得到的值,在对16384做取模,最终判断该key应该在哪个slot中进行存取,本质和服务器节点数取模是一样的,只不过redis cluster的slot算法更精妙,成本更低廉。

以三主三从为例,这个时候的slot总数会平均等份,使得每个master节点中都会有slot,目前3个的话那就是{0..5461}{5462..10922}{10923..16383},这个取值区间在搭建好集群之后是可以看到的。

如果这个时候,集群环境增加或者减少节点,slot可以重新迁移或者合并,那么slot中的缓存key其实还是存在的,如此一来,节点宕机或者新增就不会造成缓存丢失了。这就相当于家里房子拆迁,我到新家里以后,会把我的私人物品家具啊电器啊一起携带过去,东西跟着人走,东西就是缓存key,人就slot,服务器节点是redis实例,比较灵活。并不是说你房子没了,家里的东西就没了。

提问:搬家的过程,新家能住人吗? 当然,你搬家并不是马上就能完成的,搬家需要耗时,需要等待,所以等待期间你的家具啊电器啊不可用。redis slot也是这样,宕机的时候,那部分需要迁移的slot是不可用,会有一个短暂的迁移的过程,等待迁移完成之后,才能为用户提供读写服务。

hash slot 图示:

如下图:中间的master宕机了,slot会迁移到slave

如果,新增master节点,重新分配,那么会把一些slot迁移过去,缓存数据不变,跟着slot走,虽然slot会变动到其他的master节点,但是数据key哈希的时候,还是会到跟着固定的slot。

格子铺

如果还不能理解,那就再举个栗子,格子铺,每个格子归属一个卖家,这个卖家把各自托管给某些商铺,由他们代运营,如果商铺倒闭,格子还是存在的,他可以把各自带着走,各自里的商品就是redis集群中的数据呀,它是不会发生更改的,只是外壳换了一家商铺而已。

Redis集群搭建

时间关系,我们在这里就只讲原理了,操作部分,我们提供了慕课网的手记文档,很简单,大家可以去看一下就行。 链接地址:https://www.imooc.com/article/313301

只不过在集群中有一些注意点,我们大致总结了如下:

  1. 读写都是在master,slave加入集群,会进行数据同步,连接集群中的任意主或从节点去读写数据,都会根据key哈希取模后路由到某个master节点去处理。slave不提供读写服务,只会同步数据。
  2. 关闭任意一主,会导致部分写操作失败,是由于从节点不能执行写操作,在Slave升级为Master期间可能会有少量的失败。
  3. 关闭从节点对于整个集群没有影响
  4. 某个主节点和他麾下的所有从节点全部挂掉,我们集群就进入faill状态,不可用。因为slot不完整。
  5. 如果集群超过半数以上master挂掉,无论他们是否有对应slave,集群进入fail状态,因为无法选举。
  6. 如果集群中的任意master宕机,且此master没有slave。集群不可用。(同3)
  7. 投票选举过程是集群中所有master参与,如果半数以上master节点与master节点通信超时(cluster-node-timeout),认为当前master节点挂掉。
  8. 选举只会针对某个master下的所有slave选举,而不是对所有全量的slave选举。
  9. 原先的master重新恢复连接后,他会成为新master的从服务器。由于主从同步,客户端的写入命令,有可能会丢失。redis并非强一致性,由于主从特性,所以最后一部分数据会丢失。这也符合CAP理论。
  10. 集群只实现了主节点的故障转移;从节点故障时只会被下线,不会进行故障转移。因此,使用集群时,一般不会使用读写分离技术,因为从节点故障会导致读服务不可用,可用性变差了。所以不要在集群里做读写分离。

需要注意,为了保证集群的完整性,只有当16384个槽slot完全的全部分配完毕,集群才可以上线。而且,如果主节点发生故障转移,并且处于故障转移过程中还未完成时,原主节点的槽slot不会在任何节点中,集群会处于下线状态,客户端无法调用。CAP原理。

Redis集群数据迁移

已有数据的单节点的redis如何扩展为集群

搭建集群的时候,包清除节点中现有的aof以及rdb文件,那么如果现在本来就是单节点,那么如何扩展为集群呢?并且要保证数据不丢失。其实原理就是把rdb或者aof文件保存以后,再导入,然后通过slot来分配。具体步骤如下:

如上图,其原理就是slot迁移。整个过程阻塞,网站服务不对外提供服务。如果使用自建集群,那么运维成本很高,一般采用云redis的话会更好。哪怕阿里云,也会在配置变更的时候出现网络中断的情况。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-01-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 BeJavaGod 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Redis6安装(下) - 集群与故障转移
如果一个master挂了,那么剩余的2个master会发起投票选举,从挂了的master对应的slave中选举出一个新的master,发生故障的master不会参与投票,这个要注意。
风间影月
2020/12/24
8630
Redis常见面试题(二):redis分布式锁、redisson;Redis集群、主从复制,哨兵模式,分片集群;Redis为什么这么快,I/O多路复用模型
还记得Redis使用场景、缓存穿透、缓存击穿、缓存雪崩、Redis持久化、数据过期策略、数据淘汰策略吗?如果忘记可以到这里重新温习, Redis常见面试题(一):Redis使用场景,缓存、分布式锁;缓存穿透、缓存击穿、缓存雪崩;双写一致,Canal,Redis持久化,数据过期策略,数据淘汰策略。
寻求出路的程序媛
2024/07/24
3.6K0
Redis常见面试题(二):redis分布式锁、redisson;Redis集群、主从复制,哨兵模式,分片集群;Redis为什么这么快,I/O多路复用模型
java-redis
Redis是基于内存运行的高性能 K-V 数据库,官方提供的测试报告是单机可以支持约10w/s的QPS,每秒的请求.
知识浅谈
2022/05/19
2860
java-redis
Redis集群原理详解
在讲Redis集群架构之前,我们先简单讲下Redis单实例的架构,从最开始的一主N从,到读写分离,再到Sentinel哨兵机制,单实例的Redis缓存足以应对大多数的使用场景,也能实现主从故障迁移。
全栈程序员站长
2022/06/29
2.8K0
Redis集群原理详解
【云原生进阶之PaaS中间件】第一章Redis-2.1架构综述
        Redis 组件的系统架构如图所示,主要包括事件处理、数据存储及管理、用于系统扩展的主从复制/集群管理,以及为插件化功能扩展的 Module System 模块。
江中散人_Jun
2023/10/16
4510
【云原生进阶之PaaS中间件】第一章Redis-2.1架构综述
redis高并发高可用
对于性能来说,单主用来写入数据,单机几万QPS,多从用来查询数据,多个从实例可以提供每秒 10w 的 QPS。
Tim在路上
2020/08/04
2.9K0
一个例子,看懂关系型数据库和Redis的区别
互联网产品正从“满足用户单向浏览的需求”发展为“满足用户个性化信息获取及社交的需求”。随着 5G的到来,会有越来越多“不可思议”的场景被搬到互联网上。这就要求产品做到以用户和关系为基础,对海量数据进行实时分析计算。
江南一点雨
2023/01/04
7810
一个例子,看懂关系型数据库和Redis的区别
2024年java面试准备--redis(2)
一个简单直观的想法是直接用Hash来计算,以Key做哈希后对节点数取模。可以看出,在key足够分散的情况下,均匀性可以获得,但一旦有节点加入或退出,所有的原有节点都会受到影响,稳定性无从谈起。
终有救赎
2023/10/16
4740
2024年java面试准备--redis(2)
Redis的集群解决分布式系统中负载均衡的原理
一 Redis单机缺陷 redis单机容量方面会有瓶颈,主从模式只能保证支撑更多读并发,但是slave和master的数据是一模一样的,也就是说master能存储多少数据,slave就也只能存储这么多
名字是乱打的
2022/09/29
2.7K0
Redis的集群解决分布式系统中负载均衡的原理
面试必问之redis
redis是当前比较热门的NOSQL系统之一,它是一个开源的使用ANSI c语言编写的key-value存储系统(区别于MySQL的二维表格的形式存储。)。和Memcache类似,但很大程度补偿了Memcache的不足。和Memcache一样,Redis数据都是缓存在计算机内存中,不同的是,Memcache只能将数据缓存到内存中,无法自动定期写入硬盘,这就表示,一断电或重启,内存清空,数据丢失。所以Memcache的应用场景适用于缓存无需持久化的数据。而Redis不同的是它会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,实现数据的持久化
一笠风雨任生平
2022/01/06
3780
面试必问之redis
Redis、面试、缓存、雪崩、分布式锁实现一篇文章搞定!
近乎所有与Java相关的面试都会问到缓存的问题,基础一点的会问到什么是“二八定律”、什么是“热数据和冷数据”,复杂一点的会问到缓存雪崩、缓存穿透、缓存预热、缓存更新、缓存降级等问题,这些看似不常见的概念,都与我们的缓存服务器相关,一般常用的缓存服务器有Redis、Memcached等,而笔者目前最常用的也只有Redis这一种。
马士兵的朋友圈
2020/09/18
7590
Redis缓存那点破事 | 绝杀面试官 25 问!
为了便于大家查找问题,了解全貌,整理个目录,我们可以快速全局了解关于Redis 缓存,面试官一般喜欢问哪些问题?
微观技术
2021/09/15
5500
Redis 面试题
阿彬学java
2025/01/13
2010
Redis 常见面试题
(1)Redis 支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。
Tim在路上
2020/08/05
7670
Redis 常见面试题
4种 Redis 集群方案介绍+优缺点对比
点击上方“芋道源码”,选择“设为星标” 管她前浪,还是后浪? 能浪的浪,才是好浪! 每天 10:33 更新文章,每天掉亿点点头发... 源码精品专栏 原创 | Java 2021 超神之路,很肝~ 中文详细注释的开源项目 RPC 框架 Dubbo 源码解析 网络应用框架 Netty 源码解析 消息中间件 RocketMQ 源码解析 数据库中间件 Sharding-JDBC 和 MyCAT 源码解析 作业调度中间件 Elastic-Job 源码解析 分布式事务中间件 TCC-Transaction
芋道源码
2022/05/06
2.4K0
4种 Redis 集群方案介绍+优缺点对比
Redis相关底层面试题
Redis是一个开源的高性能键值对存储系统,具有快速、灵活和可扩展的特性。它是一个基于内存的数据结构存储系统,可以用作数据库、缓存和消息代理。Redis支持多种类型的数据结构,如字符串(strings),散列(hashes),列表(lists),集合(sets)等。
半月无霜
2023/10/18
2880
Redis相关底层面试题
Redis读写分离和分布式缓存算法原理
当启动一个slave node的时候,它会发送一个PSYNC命令给master node
丁D
2022/08/12
5480
redis集群的架构、问题,附脑洞
Redis 是一种开源(BSD 许可)、数据结构存储在内存中的系统,用作数据库、缓存和消息队列。Redis 提供了诸如字符串、散列、列表、集合、带范围查询的排序集合、位图、超级日志、地理空间索引和流等数据结构。Redis 内置复制、Lua 脚本、LRU 驱逐、事务和不同级别的磁盘持久化,并通过 Redis Sentinel 和 Redis Cluster 自动分区提供高可用性。
一凡sir
2023/07/19
6320
Redis原理—3.复制、哨兵和集群
命令传播操作用于在主服务器的数据库状态被修改,导致主从服务器的数据库状态出现不一致时,让主从服务器的数据库重新回到一致状态。
东阳马生架构
2025/02/24
3210
一篇文章理解Redis集群
Redis作为一款性能优异的内存数据库,支撑着亿级数据量的社交平台,也成为很多互联网公司的标配。这里将以Redis Cluster 集群为核心,基于最新的Redis5版本,从原理到实战,玩儿转Redis集群。
用户1212940
2019/11/02
9250
相关推荐
Redis6安装(下) - 集群与故障转移
更多 >
交个朋友
加入架构与运维学习入门群
系统架构设计入门 运维体系构建指南
加入架构与运维趋势交流群
技术趋势前瞻 架构演进方向
加入[架构及运维] 腾讯云技术交流站
云架构设计 云运维最佳实践
换一批
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档