提炼设计框架,一文搞懂Redis/MySQL/Kafka为什么这样设计

大家好,我是东邪狂想,本文是Redis、MySQL、Kafka系列第一篇。

本专题主要讲解Redis/MySQL/Kafka,先阐述它们之间的共性的设计思想,然后逐步讲解Redis/MySQL/Kafka分别是如何具体实现,最终被塑造成这样一个“有血有肉”的系统

在学习MySQL、Redis、Kafka的过程中,发现了它们之间其实存在一定的共性,在设计之初,均考虑过相同的问题,在《Designing Data-Intensive Applications》这本中便提到了很多系统的设计思想。本篇文章精炼一下其中通用的设计框架,一文搞懂Redis/MySQL/Kafka设计理念

其实好多系统都是对这套框架的具体实现,个人认为只要理解这套框架,学习其它类似的系统也没有啥困难,仅仅是不同系统在具体实现有所差别,但是搞懂框架,就相当于学到一套数学公式,摸透了系统的“骨架”,其余的只是在“血肉”上有所差别,即有的系统“腿部肌肉”强壮,而有的系统“肱二头肌”更发达,如此而已。

废话不多说,直接介绍设计思想中的三大骨骼,分别是可扩展性,高可用,持久化,太抽象?不明白?没关系,下面分别一一介绍这三大中流砥柱:

一、高可用:简单来说就是系统是否可靠,系统容灾能力如何,是否有多个节点提供服务,某个节点突然挂掉,系统是否还能正常提供服务或者某个节点挂掉是否会导致用户的部分数据丢失等。

二、可扩展性:也可以说是伸缩性,即系统应对负载增长的能力,比如系统是否可以通过增加节点来应对徒增的流量或者负载,服务依旧保持良好的性能。

三、持久化:保存系统的状态信息,使得系统因为某种原因重启,但数据不会丢。

图书馆

本文尝试通过讲述如何经营一个能够应对高流量阅读任务、容灾等级强的图书馆,来讲明白MySQL\Redis\Kafka的设计框架

比如现在我们需要设计一个数据存储系统,那么设计之初我们将所有的数据均放在一个机器节点上,那么这样会有什么问题呢

所有的数据“放在一个篮子里”,意味着后续所有用户查询数据时,所有的查询请求将全部打在同一个机器节点上,形成了一种“一夫当关,万夫莫开”的局面。

这里我给大家举个例子,好比大家去图书馆借阅图书,如果图书馆仅有一本《射雕英雄传》,但是有10同学想要借本书,但最终只有一位同学能把《射雕英雄传》借到手,其余的9位同学只能依次等上一位同学把书归还之后,再继续借阅。

那么,如何才能想办法要10位同学尽快读上《射雕英雄传》呢,毕竟武侠小说谁能不爱呢?办法之一就是图书馆可以把《射雕英雄传》这本书多复印几本或者把一本书的各个章节撕开分别借阅,这样就可以应对多位同学同时借阅图书的情况了!这样即使后续借书的同学再次增多,依旧可以按照同样的方法,再复制同样的一本书,放到其它书架上,提高图书馆的服务能力,这便是“可扩展性”

其中,原版书籍所在的书架可以称为“主库节点Leader”,复印的书籍所在的书架可以称为“从库节点Follower”。

虽然图书馆已经可以应对高流量阅读人群了,进一步试想在图书馆运营过程中,假如图书馆的“小说类书架”不慎发生火灾,导致书架上的书焚毁了,那么意味同学们无法读到《射雕英雄传》等小说了!!!

那我们应该怎么办?比如《射雕英雄传》这本小说已经复印了多本,图书馆可以它们放到不同的书架上,这样即使某个书架不慎毁灭,那么还可以有其它的书架依旧可以找到《射雕英雄传》并提供服务,这便是“高可用”

对应在系统中也是一样,我们可以将一个机器节点上的数据复制多份,备份的同时,还可以将其分散到其它机器节点上,这样多个机器均可以提供查询服务,并发访问量以及访问速度自然而然就大大提升了。

但是试想后面数据量逐渐增加,一个机器节点上根本放不下完整的一份数据集合,那该怎么办?类似把一本书按照章节撕开,同样可以将一个大型的数据集合拆分成较小的子集(称分区),然后不同的分区可以放在不同的机器节点上。

如图,我们将数据集合拆分成了2份Partition1和Partition2,同时为了保证高可用,Partition1和Partition2各自有一个副本,避免因为某个机器节点挂掉导致数据丢失

在这里插入图片描述

注:分区一是提高服务的并发能力,另一方面是考虑到单一机器节点无法直接持有整个数据集

以上通过改造图书馆的例子,详细阐述了“分区和复制”的思想,成功让图书馆既可以应对高流量人群,又可以提高容灾能力。

主从节点引入的新挑战

目前我们的“图书馆”还并不能完全算作高扩展性,高可用的系统,因为还有一系列的问题需要解决。

比如目前图书馆为了应对高流量的阅读人群,增加了新的书架(即系统增加了新的节点),那么图书馆的书是否需要重新分配吗(重平衡分区),比如分到新书架上一些书?

如果之前的旧书架(主节点)上增加了新订阅的小说《天龙八部》,那新增的书架(从节点)如何才能拿到《天龙八部》的复印本呢?这便涉及到主从同步问题

另外考虑新增书架与旧书架之间 同步书籍出现延迟,那么将会导致一个问题,即旧书架的阅读人群能读到《天龙八部》,而新书架的阅读人群需要再等几天才能阅读,这便是主从同步延迟问题

另外,假如同学小明向图书馆捐赠了一本《天龙八部》,然后图书馆放在了旧书架上,小明过了一周后图书馆借阅,发现在书架上根本没有《天龙八部》,哦!原来这是新增的书架,上面还没有复印版的《天龙八部》,这便是主从同步延迟导致的主从不一致问题

主从同步

前面提到系统为了支持更高的并发量以及高可用性,会增设多个节点,即系统由主节点和多个从节点组成,其中一般只有主节点处理写请求,从节点仅支持读请求,主节点接收写请求而新增的数据会逐渐同步到从节点上,即主从同步

主从同步如何实现才能保证新增节点拥有主库节点的精确副本呢?仅仅将数据文件从主节点拷贝到新节点是不可以的,因为客户端总是在不断的向数据库写入数据,换句话说数据是不断变化的。

一般可以通过如下流程进行主从同步
a. 在某个时刻获取主库的一致性快照,而不必锁定整个数据库;
b. 将快照复制到新的从库节点;
c. 从库连接到主库,并拉取快照之后发生的所有变更;
d. 当从库处理完快照之后积压的数据变更,便“赶上”了主库;

过程很简单,但是快照是什么,如何获取得到快照呢,这便涉及到数据落盘(持久化)问题

快照指的是系统在某个时刻的状态,类似“照片”可以将某个时刻的人物定格,快照也可以将系统的某个时刻的状态保存下来。一般有如下几种方式,可以对系统的状态进行刻画:

1. 基于语句:简单来说,主库记录下每个写入请求的语句,从节点拿到这些语句执行一般就能获取同样的数据。这种实现方式很粗糙,在某些场景下式不适合的,比如一些非确定性函数语句now()等,在不同时间执行得到的数据是不一样的

2. 预写式日志(Write Ahead Log):是一种物理日志,系统的存储引擎也是直接使用该日志存储数据,直接记录了磁盘块的哪些字节发生了修改,因此从库使用该日志便可以直接建立和主库节点一模一样的数据副本

3. 逻辑日志:基于行的一种逻辑日志,以行为粒度,描述对数据库表的修改:对于新插入的行,日志直接包含所有列的新值;对于删除的行,日志包含足够信息标识已删除的行(通常是主键);对于更新的行,日志同样需要包含足够的信息标识更新的行,另外需要记录更改后的列的新值

注:其实在MySQL、Redis、Kafka均有上述类似的实现,比如个人认为Redis中的RDB文件便是一种预写式日志,RDB文件为二进制的格式,通过该文件可以将数据库还原到生成RDB文件是的状态,同时Redis中还有AOF日志,那便是基于行的逻辑日志。
同样的MySQL中的binlog日志也是预写式二进制日志,而redo log则是逻辑日志

那上述的同步过程是同步复制还是异步复制呢?通常不同的系统有不同的实现,或者是一个配置项。同步复制优点是能保证从库有与主库一致的最新数据副本,如果主库突然失效,那么从库上的数据并不落后与主库;缺点是如果同步从库没有及时响应,主库便无法执行写入操作。因此将所有从库设置为同步不切实际,因为任何一个节点的中断,均会导致整个系统stop the world。

通常情况下,基于领导者(主节点)的复制都设置成异步,异步复制优点是主从复制并不阻塞主节点处理写入;缺点是如果主库失效,那么尚未同步给从库的数据将会丢弃,意味着即使已经向客户端写入成功,但是其实因为主库故障,数据已经丢失了;

比如在Redis中主从同步便是异步操作,大致过程与前面介绍的流程一致:

在这里插入图片描述

a. 首先,redis从节点向主节点返送SYNC命令
b. 主节点收到SYNC命令后,会执行BGSAVE命令,在后台生成一个RDB快照文件,同时使用一个缓冲记录后续执行的写命令
c. 主节点将生成的RDB文件发送给从节点,从节点便可以更新至主节点执行BGSAVE命令时的数据库状态
d. 主节点再把缓冲区中记录的所有写命令发送给从节点,这样从节点便完全追赶上了主节点,主从同步完成

同样的MySQL中的主从同步也是异步操作,大致原理类似只不是日志文件是binlog,具体细节不再赘述。

到这里本篇文章对设计框架的介绍已经接近尾声,但是还有好多问题,这里没有做过多概述,比如:主从异步复制时,同步延迟会导致主从数据不一致的问题,这里各个系统均会存在类似的问题,但是优化方法不太一样,后续准备单独介绍Redis、MySQL、Kafka时会一一解答。

小结

本篇以图书馆为例子,讲解了Redis、MySQL、Kafka三大系统的设计框架,通过分区和复制的思想保证系统可扩展、高可用,又对主从节点同步(同步复制/异步复制)做了节点的介绍,关于主从同步还有许多问题待解决,本篇文章碍于篇幅并没有一一提及,后续系列文章会一一解答。

本篇文章希望大家有所收获,通过设计框架的“三大骨骼”,懂得如何一步一步思考,比如为了系统的高扩展高可用,需要多增加从节点,那么便涉及到主从同步?是同步复制还是异步复制?引入从节点之后,数据需要重新分配吗?从节点中的数据稍微落后与主节点,即主从延迟问题会导致不同的用户读到的数据可能不一致?节点挂掉之后(区分主节点还是从节点),系统如何处理?系统是否支持事务?

欢迎大家留言讨论,指出不足之处!

在这里插入图片描述

原文地址:https://blog.csdn.net/qq_44886707/article/details/135307726

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


文章浏览阅读4.1k次。kafka认证_kafka认证
文章浏览阅读4.8k次,点赞4次,收藏11次。kafka常用参数_kafka配置
文章浏览阅读1.4k次,点赞25次,收藏10次。Kafka 生产者发送消息的流程涉及多个步骤,从消息的创建到成功存储在 Kafka 集群中。_kafka发送消息流程
文章浏览阅读854次,点赞22次,收藏24次。点对点模型:适用于一对一的消息传递,具有高可靠性。发布/订阅模型:适用于广播消息给多个消费者,实现消息的广播。主题模型:适用于根据消息的主题进行灵活的过滤和匹配,处理复杂的消息路由需求。
文章浏览阅读1.5k次,点赞2次,收藏3次。kafka 自动配置在KafkaAutoConfiguration
文章浏览阅读1.3w次,点赞6次,收藏33次。Offset Explorer(以前称为Kafka Tool)是一个用于管理和使Apache Kafka ®集群的GUI应用程序。它提供了一个直观的UI,允许人们快速查看Kafka集群中的对象以及存储在集群主题中的消息。它包含面向开发人员和管理员的功能。二、环境信息系统环境:windows 10版本:2.2Kafka版本:Kafka2.0.0三、安装和使用3.1 下载Offset Explorer 和安装下载到本地的 .exe文件Next安装路径 ,Next。_offset explorer
文章浏览阅读1.3k次,点赞12次,收藏19次。kafka broker 在启动的时候,会根据你配置的listeners 初始化它的网络组件,用来接收外界的请求,这个listeners你可能没配置过,它默认的配置是listeners=PLAINTEXT://:9092就是告诉kafka使用哪个协议,监听哪个端口,如果我们没有特殊的要求的话,使用它默认的配置就可以了,顶多是修改下端口这块。
文章浏览阅读1.3k次,点赞2次,收藏2次。Kafka 是一个强大的分布式流处理平台,用于实时数据传输和处理。通过本文详细的介绍、使用教程和示例,你可以了解 Kafka 的核心概念、安装、创建 Topic、使用生产者和消费者,从而为构建现代分布式应用打下坚实的基础。无论是构建实时数据流平台、日志收集系统还是事件驱动架构,Kafka 都是一个可靠、高效的解决方案。_博客系统怎么使用kafka
文章浏览阅读3.5k次,点赞42次,收藏56次。对于Java开发者而言,关于 Spring ,我们一般当做黑盒来进行使用,不需要去打开这个黑盒。但随着目前程序员行业的发展,我们有必要打开这个黑盒,去探索其中的奥妙。本期 Spring 源码解析系列文章,将带你领略 Spring 源码的奥秘。本期源码文章吸收了之前 Kafka 源码文章的错误,将不再一行一行的带大家分析源码,我们将一些不重要的分当做黑盒处理,以便我们更快、更有效的阅读源码。废话不多说,发车!
文章浏览阅读1.1k次,点赞14次,收藏16次。一、自动提交offset1、概念Kafka中默认是自动提交offset。消费者在poll到消息后默认情况下,会自动向Broker的_consumer_offsets主题提交当前主题-分区消费的偏移量2、自动提交offset和手动提交offset流程图3、在Java中实现配置4、自动提交offset问题自动提交会丢消息。因为如果消费者还没有消费完poll下来的消息就自动提交了偏移量,那么此时消费者挂了,于是下一个消费者会从已经提交的offset的下一个位置开始消费消息。_kafka中自动提交offsets
文章浏览阅读1.6k次。如果生产者发送消息的速度超过发送到服务器的速度,则会导致生产者空间不足,这个时候KafkaProducer的send()方法调用要么被阻塞,要么抛出异常,这个取决于参数max.block.ms的配置,此参数的默认值为60000,即60秒。在默认情况下,生产者发送的消息是未经压缩的。如果应用程序调用send()方法的速度超过生产者将消息发送给服务器的速度,那么生产者的缓冲空间可能会被耗尽,后续的send()方法调用会等待内存空间被释放,如果在max.block.ms之后还没有可用空间,就抛出异常。_kafka producer 参数
文章浏览阅读2.9k次,点赞3次,收藏10次。kafka解决通信问题_kafka3.6
文章浏览阅读1.5k次,点赞9次,收藏11次。上面都配置完了之后可以先验证下,保证数据最终到ck,如果有问题,需要再每个节点调试,比如先调试nginx->rsyslog ,可以先不配置kafka 输出,配置为console或者文件输出都可以,具体这里就不写了。这里做了一个类型转换,因为nginx,request-time 单位是s,我想最终呈现在grafana 中是ms,所以这里做了转换,当然grafana中也可以做。kafka 相关部署这里不做赘述,只要创建一个topic 就可以。
文章浏览阅读1.4k次,点赞22次,收藏16次。Kafka中的enable-auto-commit和auto-commit-interval配置_auto-commit-interval
文章浏览阅读742次。thingsboard规则链调用外部 kafka_thingsboard kafka
文章浏览阅读1.3k次,点赞18次,收藏22次。Kafka_简介
文章浏览阅读1.1k次,点赞16次,收藏14次。在数据库系统中有个概念叫事务,事务的作用是为了保证数据的一致性,意思是要么数据成功,要么数据失败,不存在数据操作了一半的情况,这就是数据的一致性。在很多系统或者组件中,很多场景都需要保证数据的一致性,有的是高度的一致性。特别是在交易系统等这样场景。有些组件的数据不一定需要高度保证数据的一致性,比如日志系统。本节从从kafka如何保证数据一致性看通常数据一致性设计。
文章浏览阅读1.4k次。概述介绍架构发展架构原理类型系统介绍类型hive_table类型介绍DataSet类型定义Asset类型定义Referenceable类型定义Process类型定义Entities(实体)Attributes(属性)安装安装环境准备安装Solr-7.7.3安装Atlas2.1.0Atlas配置Atlas集成HbaseAtlas集成SolrAtlas集成KafkaAtlas Server配置Kerberos相关配置Atlas集成HiveAtlas启动Atlas使用Hive元数据初次导入Hive元数据增量同步。_atlas元数据管理
文章浏览阅读659次。Zookeeper是一个开源的分布式服务管理框架。存储业务服务节点元数据及状态信息,并负责通知再 ZooKeeper 上注册的服务几点状态给客户端。
文章浏览阅读1.4k次。Kafka-Kraft 模式架构部署_kafka kraft部署