【架构设计之道】这一波优雅的操做,会把你的中间件系统架构带到另外一个Level【石杉的架构笔记】

目录

一、Master-Slave架构数据库

二、异步日志持久化机制架构

三、检查点机制:定时持久化全量数据并发

四、引入检查点节点异步

五、总结 & 思考分布式

这篇文章,给你们来聊一个生产级的中间件系统的架构设计实践,但愿给对中间件系统感兴趣的同窗一点启发。


(1)Master-Slave架构

这个中间件系统的本质是但愿可以用分布式的方式来处理一些数据,可是具体的做用涉及到核心技术,因此这里不能直接说明。微服务

可是他的核心思想,就是把数据分发到不少台机器上来处理,而后须要有一台机器来控制N多台机器的分布式处理,大概以下图所示。高并发

那么既然是分布式的处理,就确定涉及到在Master中要维护这个集群的一些核心元数据。性能

好比说数据的分发处理是如何调度的,处理的具体过程如今什么进度了,还有就是对集群里存放数据进行描述的一些核心元数据。线程

这些核心元数据确定会不断的频繁的修改,你们此时能够想,不管你是基于外部的文件仍是数据库,或者是zookeeper来存放这些元数据的话,其实都会致使他的元数据更新性能下降,由于要访问外部依赖。架构设计

况且这种复杂的元数据其实还不必定能经过zk或者数据库来存放,由于他多是非格式化的。

因此这里一个核心的设计,就是将核心元数据直接存放在Master的内存里,这样能够保证高并发更新元数据的时候,他的性能是极高的,并且直接基于内存来提供对外的更新服务。

若是Master部署在高配置物理机上,好比32核128GB的那种,每秒支持10万+的请求都没问题。




(2)异步日志持久化机制

可是这里有一个问题,假如说Master进程重启,或者是忽然宕机了,那么内存里的数据不就丢失了么?

对,因此针对这个问题,既然已经否决掉了基于外部存储来写入元数据,那么这里就能够采起异步持久化日志的机制,来经过异步化的方式把元数据的更新日志写入磁盘文件。

每次Master收到一个请求,在内存里更新元数据以后,就须要生成一条元数据的更新日志,把这个更新日志须要写入到一个内存缓冲里去。

而后等内存缓冲满了以后,由一个后台线程把这里的数据刷新到磁盘上去,以下图。



确定会有人说,那若是一条更新日志刚写入缓冲区,结果Master宕机了,此时不是仍是会丢失少许数据吗?由于还没来得及刷入磁盘。

没错啊,这个为了保证高并发请求都是由内存来处理的,你必须得用异步持久化磁盘的模式,因此必然要容忍极端宕机状况下,可能丢失好比几秒钟的数据。

那么若是是正常的Master重启呢?

那简单,必须先把日志缓冲区清空刷入磁盘,而后才能正常重启Master,保证数据都在磁盘上不会丢失。

接着重启的时候,从磁盘上读取更新日志,每一条都依次回访到内存里,恢复出来核心元数据便可。


(3)检查点机制:定时持久化全量数据

可是这里又有一个问题了,那个磁盘上的日志文件愈来愈大,由于元数据不断的在更新,不断在产生最新的变动日志写入磁盘文件。

那么系统运行一段时间之后,每次重启都须要从磁盘读取历史所有日志,一条一条回放到内存来恢复核心元数据吗?

不可能,因此这里必定要配合引入检查点机制。

也就是说,每隔一段时间,就须要开启一个后台线程,把内存里的所有核心元数据序列化后写入磁盘上的元数据文件,做为这个时间的一个快照文件,同时清空掉日志文件,这个叫作检查点操做。

下次重启,只要把元数据文件读取出来直接反序列化后方入内存,而后把上次检查点以后的变动日志从日志文件里读出来回放到内存里,就能够恢复出来完整的元数据了。

这种方式,可让Master重启很快,由于大部分数据都是在检查点写入的那个元数据文件里。

整个过程,以下图所示:



(4)引入检查点节点

可是这个时候又有一个问题了。

你们能够想一下,Master内存里的元数据须要高并发的被人访问和修改,同时每隔一段时间还要检查点写入磁盘。

那么在检查点过程当中,是否是须要把内存数据所有加锁,不容许别人修改?

在加锁的时候,把不会变更的数据写入磁盘文件中,可是这个过程是很慢的,意味着此时别人高并发的写入操做都须要等待核心元数据的锁。

由于此时别人锁住了,你没法加锁去写数据进去,这会致使系统在几秒内出现卡顿没法响应请求的问题。

因此此时须要在架构设计里引入一个检查点节点,专门负责同步Master的变动日志。

而后在本身内存里维护一份如出一辙的核心元数据,每隔一段时间由检查点节点来负责将内存数据写入磁盘,接着上传发送给Master。

这样作,就不须要Master本身执行检查点的时候对本身内存数据进行加锁了,以下图。



在这样的一个架构下,对Master来讲,他只须要一个后台线程负责接收Checkpoint进程定时传送过来的元数据文件快照而后写入本地磁盘就能够了,彻底规避掉了对本身内存元数据的锁冲突的问题。


(5)总结 & 思考

总结一下这个架构设计,其实就是Master基于内存维护元数据,这样一台物理机能够支撑每秒10万+的高并发请求。

每次元数据出现更新,写一条日志到内存缓冲区,而后后台线程去刷新日志到日志文件里去,同时须要发送一条日志到Checkpoint节点去。

Checkpoint节点会在本身内存里维护一份如出一辙的元数据,而后每隔一段时间执行checkpoint检查点写一份元数据文件快照。

接着上传给Master节点后清空掉他的日志文件。而后Master节点每次重启的时候直接读取本地元数据文件快照,加上回放上次checkpoint以后的日志便可。

这里可能你们会提几个问题,好比说Master节点忽然宕机会如何?

那很简单,直接影响就是他内存缓冲里的那些日志丢了,致使少许数据丢失,这个在咱们的场景下能够容忍。

若是Checkpoint节点宕机怎么办?

那没关系,由于他以前上传过元数据文件的快照,因此对Master而言最多就是没法同步数据过去。

可是Master重启,仍是能够读取最近一次的元数据快照,而后回放日志便可。

等Checkpoint节点恢复了,能够继续接着上一次同步日志,而后继续执行checkpoint操做。

一大波微服务、分布式、高并发、高可用的原创系列文章正在路上,

欢迎关注公众号:石杉的架构笔记

周一至周五早八点半!精品技术文章准时送上!!!

十余年BAT架构经验倾囊相授