首页 运营 正文
刷盘(刷盘机制)

来源:网友投稿 浏览数:3702 关注:355人

大家好,近很多小伙伴在关注刷盘,以下是(www.liyan0123)小编整理的与刷盘相关的内容分享给大家,一起来看看吧。

本文目录一览:

刷盘机制

RocketMQ的消息会在消息的发送者发送到队列之后存储到本地磁盘上,这样的好处就是可以保证系统挂掉之后,消息不至于丢失,还可以恢复。同时另一个好处就是可以使得存储的消息超出内存的限制。刷盘有两种方式,分布式同步刷盘和异步刷盘。

在返回写成功状态时,消息已被写入磁盘,具体流程是,消息写入内存的PAGECCACHE后,立刻通知刷盘线程刷盘,然后等待刷盘完成,刷盘线程执行完成后唤醒等待的线程,返回消息写成功的状态。

在返回写成功状态时,消息可能只是被写入了内存的PAGECACHE,写*作的返回快,吞吐量大;当内存里的消息量积累到一定程度时,统一触发写磁盘动作,快速写入。

同步刷盘还是异步刷盘,都是通过Broker配置文件里的flushDiskType参数设置的,这个参数被配置成SYNC_FLUSH,ASYNC_FLUSH中的一个

RocketMQ刷盘机制

RocketMQ的存储读写是基于JDK NIO的内存映射机制的,消息存储时首先将消息追加到内存中。在根据不同的刷盘策略在不同的时间进行刷盘。如果是同步刷盘,消息追加到内存后,将同步调用MappedByteBuffer的force()方法,同步等待刷盘结果,进行刷盘结果返回。如果是异步刷盘,在消息追加到内存后立刻,不等待刷盘结果立刻返回存储成功结果给消息发送端。RocketMQ使用一个单独的线程按照一个设定的频率执行刷盘*作。通过在broker配置文件中配置flushDiskType来设定刷盘方式,ASYNC_FLUSH(异步刷盘)、SYNC_FLUSH(同步刷盘)。默认为异步刷盘。本次以Commitlog文件刷盘机制为例来讲解刷盘机制。Consumequeue、IndexFile刷盘原理和Commitlog一直。索引文件的刷盘机制并不是采取定时刷盘机制,而是每更新一次索引文件就会将上一次的改动刷写到磁盘。

刷盘服务是将commitlog、consumequeue两者中的MappedFile文件中的MappedByteBuffer或者FileChannel中的内存中的数据,刷写到磁盘。还有将IndexFile中的MappedByteBuffer(this.mappedByteBuffer = this.mappedFile.getMappedByteBuffer())中内存的数据刷写到磁盘。

刷盘服务的入口是CommitLog类对象,FlushCommitLogService是刷盘服务对象,如果是同步刷盘它被赋值为GroupCommitService,如果是异步刷盘它被赋值为FlushRealTimeService;还有一个FlushCommitLogService的commitLogService对象,这个是将 TransientStorePoll 中的直接内存ByteBuffer,写到FileChannel映射的磁盘文件中的服务。

putMessage()方法,将消息写入内存的方式不同,调用的刷盘方式也不同。如果是asyncPutMessage()异步将消息写入内存,submitFlushRequest()方法是刷盘入口。如果是putMessage()同步将消息写入内存,handleDiskFlush()方法是刷盘入口。handleDiskFlush()和submitFlushRequest()都包含有同步刷盘和异步刷盘的方法。

一条消息调用一次刷盘服务,等待刷盘结果返回,然后再将结果返回;才能处理下一条刷盘消息。以handleDiskFlush()方法来介绍同步刷盘和异步刷盘,这里是区分刷盘方式的分水岭。

同步刷盘会创造一个刷盘请求,然后将请求放入处理写刷盘请求的requestsWrite队列,请求里面封装了CompletableFuture对象用来记录刷盘结果,利用CompletableFuturee的get方法同步等待获取结果。flushStatus = flushOkFuture.get(this.defaultMessageStore.getMessageStoreConfig().getSyncFlushTimeout(),TimeUnit.MILLISECONDS);flushStatus为刷盘结果,默认等待5秒超时。

GroupCommitService为一个线程,用来定时处理requestsWrite队列里面的写刷盘请求,进行刷盘;它的requestsWrite和requestsRead队列进行了读写分离,写GroupCommitRequest请求到requestsWrite队列,读GroupCommitRequest请求从requestsRead读取,读取请求今夕写盘*作。这两个队列,形成了化零为整,将一个个请求,划分为一批,处理一批的GroupCommitRequest请求,然后requestsWrite和requestsRead队列进行交换,requestsRead作为写队列,requestsWrite作为读队列,实现读写分离。从中使用CountDownLatch2来实现处理刷盘请求线程和提交刷盘请求之前的协调,通过控制hasNotified状态来实现写队列和读队列的交换。

异步刷盘根据是否开启TransientStorePool暂存池,来区分是否有commit*作。开启TransientStorePool会将writerBuffer中的数据commit到FileChannel中(fileChannel.write(writerBuffer)),然后再将FileChannel中的数据通过flush*作(fileChannel.force())到磁盘中;

如果为开启TransientStorePool,就不会有commit*作,直接flush(MappedByteBuffer.force())到磁盘中。

定时将 transientStorePool 中的直接内存 ByteBuffer,提交到FileChannel中,然后唤醒刷盘*作。

异步刷盘服务

这里讲一下刷盘是否开启TransientStorePool的区别。

MappedByteBuffer是直接内存,它暂时存储了message消息,MappedFile.mapp()方法做好MappedByteBuffer对象直接内存和落盘文件的映射关系,然后flush()方法执行MappedByteBuffer.force():强制将ByteBuffer中的任何内容的改变写入到磁盘文件。

MappedFile的writerBuffer为直接开辟的内存,然后MappedFile的初始化*作,做好FileChannel和磁盘文件的映射,commit()方法实质是执行fileChannel.write(writerBuffer),将writerBuffer的数据写入到FileChannel映射的磁盘文件,flush*作执行FileChannel.force():将映射文件中的数据强制刷新到磁盘。

TransientStorePool 相当于在内存层面做了读写分离,写走内存磁盘,读走pagecache,同时大程度消除了page cache的锁竞争,降低了毛刺。它还使用了锁机制,避免直接内存被交换到swap分区。

参考:

FileChannel和MappedByteBuffer都是NIO模块的类,ByteBuffer直接内存映射到磁盘文件通过FileChannel。

FileChannel.force()只会将FileChannel类中方法使FileChannel发生改变的内容强制刷新到存储设备文件中。

MappedByteBuffer.force()会将Map类中方法使ByteBuffer发生改变的内容强制刷新到存储设备文件中。

洗地机的刷盘有哪些尺寸?

不同尺寸的刷盘所使用的洗地机类型也是不一样的,

洗地机刷盘有13寸,15寸,16寸,17寸,18寸,20寸以及22寸。

以上就是刷盘的相关介绍,希望能对大家有所帮助。

获赞:289 | 收藏:84 | 发布时间:2024-05-10 12:52:12

  •  标签:  

原文链接:http://www.liyan0123.com/39566.html

=========================================

特别声明:以上内容来源于网友投稿,编辑整理发布,如有不妥之处,请与我方联系删除处理。

推荐阅读