最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

RocketMQ設(shè)計(jì)之異步刷盤

 更新時(shí)間:2022年03月21日 10:29:20   作者:周杰倫本人  
本文介紹RocketMQ設(shè)計(jì)之異步刷盤,RocketMQ消息存儲(chǔ)到磁盤上,這樣既保證斷電后恢復(fù),也讓存儲(chǔ)消息量超出內(nèi)存限制,RocketMQ為了提高性能,會(huì)盡可能保證磁盤順序?qū)?消息通過Producer寫入RocketMQ的時(shí)候,有兩種方式,上篇介紹了同步刷盤,本文介紹異步刷盤,需要的朋友可以參考下

上一篇RocketMQ設(shè)計(jì)之同步刷盤

異步刷盤方式:在返回寫成功狀態(tài)時(shí),消息可能只是被寫入了內(nèi)存的PAGECACHE,寫操作的返回快,吞吐量大;當(dāng)內(nèi)存里的消息量積累到一定程度時(shí),統(tǒng)一觸發(fā)寫磁盤操作,快速寫入

RocketMQ默認(rèn)采用異步刷盤,異步刷盤兩種策略:開啟緩沖池,不開啟緩沖池

CommitLog的handleDiskFlush方法:

public void handleDiskFlush(AppendMessageResult result, PutMessageResult putMessageResult, MessageExt messageExt) {
? ? // Synchronization flush
? ? if (FlushDiskType.SYNC_FLUSH == this.defaultMessageStore.getMessageStoreConfig().getFlushDiskType()) {
? ? ? ? final GroupCommitService service = (GroupCommitService) this.flushCommitLogService;
? ? ? ? if (messageExt.isWaitStoreMsgOK()) {
? ? ? ? ? ? GroupCommitRequest request = new GroupCommitRequest(result.getWroteOffset() + result.getWroteBytes());
? ? ? ? ? ? service.putRequest(request);
? ? ? ? ? ? boolean flushOK = request.waitForFlush(this.defaultMessageStore.getMessageStoreConfig().getSyncFlushTimeout());
? ? ? ? ? ? if (!flushOK) {
? ? ? ? ? ? ? ? log.error("do groupcommit, wait for flush failed, topic: " + messageExt.getTopic() + " tags: " + messageExt.getTags()
? ? ? ? ? ? ? ? ? ? + " client address: " + messageExt.getBornHostString());
? ? ? ? ? ? ? ? putMessageResult.setPutMessageStatus(PutMessageStatus.FLUSH_DISK_TIMEOUT);
? ? ? ? ? ? }
? ? ? ? } else {
? ? ? ? ? ? service.wakeup();
? ? ? ? }
? ? }
? ? // Asynchronous flush
? ? else {
? ? ? ? if (!this.defaultMessageStore.getMessageStoreConfig().isTransientStorePoolEnable()) {
? ? ? ? ? ? flushCommitLogService.wakeup();
? ? ? ? } else {
? ? ? ? ? ? commitLogService.wakeup();
? ? ? ? }
? ? }
}

不開啟緩沖池:默認(rèn)不開啟,刷盤線程FlushRealTimeService會(huì)每間隔500毫秒嘗試去刷盤。

class FlushRealTimeService extends FlushCommitLogService {
? ? private long lastFlushTimestamp = 0;
? ? private long printTimes = 0;

? ? public void run() {
? ? ? ? CommitLog.log.info(this.getServiceName() + " service started");

? ? ? ? while (!this.isStopped()) {
? ? ? ? ? ? boolean flushCommitLogTimed = CommitLog.this.defaultMessageStore.getMessageStoreConfig().isFlushCommitLogTimed();

? ? ? ? ? ? //每次Flush間隔500毫秒
? ? ? ? ? ? int interval = CommitLog.this.defaultMessageStore.getMessageStoreConfig().getFlushIntervalCommitLog();
? ? ? ? ? ? //每次Flush最少4頁內(nèi)存數(shù)據(jù)(16KB)
? ? ? ? ? ? int flushPhysicQueueLeastPages = CommitLog.this.defaultMessageStore.getMessageStoreConfig().getFlushCommitLogLeastPages();

? ? ? ? ? ??? ?//距離上次刷盤時(shí)間閾值為10秒
? ? ? ? ? ? int flushPhysicQueueThoroughInterval =
? ? ? ? ? ? ? ? CommitLog.this.defaultMessageStore.getMessageStoreConfig().getFlushCommitLogThoroughInterval();

? ? ? ? ? ? boolean printFlushProgress = false;

? ? ? ? ? ? // Print flush progress
? ? ? ? ? ? long currentTimeMillis = System.currentTimeMillis();
? ? ? ? ? ? if (currentTimeMillis >= (this.lastFlushTimestamp + flushPhysicQueueThoroughInterval)) {
? ? ? ? ? ? ? ? this.lastFlushTimestamp = currentTimeMillis;
? ? ? ? ? ? ? ? flushPhysicQueueLeastPages = 0;
? ? ? ? ? ? ? ? printFlushProgress = (printTimes++ % 10) == 0;
? ? ? ? ? ? }

? ? ? ? ? ? try {
? ? ? ? ? ? ? ? if (flushCommitLogTimed) {
? ? ? ? ? ? ? ? ? ? Thread.sleep(interval);
? ? ? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? ? ? this.waitForRunning(interval);
? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? if (printFlushProgress) {
? ? ? ? ? ? ? ? ? ? this.printFlushProgress();
? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? long begin = System.currentTimeMillis();
? ? ? ? ? ? ? ? CommitLog.this.mappedFileQueue.flush(flushPhysicQueueLeastPages);
? ? ? ? ? ? ? ? long storeTimestamp = CommitLog.this.mappedFileQueue.getStoreTimestamp();
? ? ? ? ? ? ? ? if (storeTimestamp > 0) {
? ? ? ? ? ? ? ? ? ? CommitLog.this.defaultMessageStore.getStoreCheckpoint().setPhysicMsgTimestamp(storeTimestamp);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? long past = System.currentTimeMillis() - begin;
? ? ? ? ? ? ? ? if (past > 500) {
? ? ? ? ? ? ? ? ? ? log.info("Flush data to disk costs {} ms", past);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? } catch (Throwable e) {
? ? ? ? ? ? ? ? CommitLog.log.warn(this.getServiceName() + " service has exception. ", e);
? ? ? ? ? ? ? ? this.printFlushProgress();
? ? ? ? ? ? }
? ? ? ? }

? ? ? ? // Normal shutdown, to ensure that all the flush before exit
? ? ? ? boolean result = false;
? ? ? ? for (int i = 0; i < RETRY_TIMES_OVER && !result; i++) {
? ? ? ? ? ? result = CommitLog.this.mappedFileQueue.flush(0);
? ? ? ? ? ? CommitLog.log.info(this.getServiceName() + " service shutdown, retry " + (i + 1) + " times " + (result ? "OK" : "Not OK"));
? ? ? ? }

? ? ? ? this.printFlushProgress();

? ? ? ? CommitLog.log.info(this.getServiceName() + " service end");
? ? }

? ? @Override
? ? public String getServiceName() {
? ? ? ? return FlushRealTimeService.class.getSimpleName();
? ? }

? ? private void printFlushProgress() {
? ? ? ? // CommitLog.log.info("how much disk fall behind memory, "
? ? ? ? // + CommitLog.this.mappedFileQueue.howMuchFallBehind());
? ? }

? ? @Override
? ? public long getJointime() {
? ? ? ? return 1000 * 60 * 5;
? ? }
}
  • 判斷是否超過10秒沒刷盤了,如果超過強(qiáng)制刷盤
  • 等待Flush間隔500ms
  • 通過MappedFile刷盤
  • 設(shè)置StoreCheckpoint刷盤時(shí)間點(diǎn)
  • 超過500ms的刷盤記錄日志
  • Broker正常停止前,把內(nèi)存page中的數(shù)據(jù)刷盤

開啟緩沖池:

class CommitRealTimeService extends FlushCommitLogService {

? ? private long lastCommitTimestamp = 0;

? ? @Override
? ? public String getServiceName() {
? ? ? ? return CommitRealTimeService.class.getSimpleName();
? ? }

? ? @Override
? ? public void run() {
? ? ? ? CommitLog.log.info(this.getServiceName() + " service started");
? ? ? ? while (!this.isStopped()) {
? ? ? ? ? ? //每次提交間隔200毫秒
? ? ? ? ? ? int interval = CommitLog.this.defaultMessageStore.getMessageStoreConfig().getCommitIntervalCommitLog();

? ? ? ? ? ? //每次提交最少4頁內(nèi)存數(shù)據(jù)(16KB)
? ? ? ? ? ? int commitDataLeastPages = CommitLog.this.defaultMessageStore.getMessageStoreConfig().getCommitCommitLogLeastPages();

? ? ? ? ? ? //距離上次提交時(shí)間閾值為200毫秒
? ? ? ? ? ? int commitDataThoroughInterval =
? ? ? ? ? ? ? ? CommitLog.this.defaultMessageStore.getMessageStoreConfig().getCommitCommitLogThoroughInterval();

? ? ? ? ? ? long begin = System.currentTimeMillis();
? ? ? ? ? ? if (begin >= (this.lastCommitTimestamp + commitDataThoroughInterval)) {
? ? ? ? ? ? ? ? this.lastCommitTimestamp = begin;
? ? ? ? ? ? ? ? commitDataLeastPages = 0;
? ? ? ? ? ? }

? ? ? ? ? ? try {
? ? ? ? ? ? ? ? boolean result = CommitLog.this.mappedFileQueue.commit(commitDataLeastPages);
? ? ? ? ? ? ? ? long end = System.currentTimeMillis();
? ? ? ? ? ? ? ? if (!result) {
? ? ? ? ? ? ? ? ? ? this.lastCommitTimestamp = end; // result = false means some data committed.
? ? ? ? ? ? ? ? ? ? //now wake up flush thread.
? ? ? ? ? ? ? ? ? ? flushCommitLogService.wakeup();
? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? if (end - begin > 500) {
? ? ? ? ? ? ? ? ? ? log.info("Commit data to file costs {} ms", end - begin);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? this.waitForRunning(interval);
? ? ? ? ? ? } catch (Throwable e) {
? ? ? ? ? ? ? ? CommitLog.log.error(this.getServiceName() + " service has exception. ", e);
? ? ? ? ? ? }
? ? ? ? }

? ? ? ? boolean result = false;
? ? ? ? for (int i = 0; i < RETRY_TIMES_OVER && !result; i++) {
? ? ? ? ? ? result = CommitLog.this.mappedFileQueue.commit(0);
? ? ? ? ? ? CommitLog.log.info(this.getServiceName() + " service shutdown, retry " + (i + 1) + " times " + (result ? "OK" : "Not OK"));
? ? ? ? }
? ? ? ? CommitLog.log.info(this.getServiceName() + " service end");
? ? }
}

RocketMQ申請(qǐng)一塊和CommitLog文件相同大小的堆外內(nèi)存來做緩沖池,數(shù)據(jù)會(huì)先寫入緩沖池,提交線程CommitRealTimeService也每間隔500毫秒嘗試提交到文件通道等待刷盤,刷盤最終由FlushRealTimeService來完成,和不開啟緩沖池的處理一致。使用緩沖池的目的是多條數(shù)據(jù)合并寫入,從而提高io性能。

  • 判斷是否超過200毫秒沒提交,需要強(qiáng)制提交
  • 提交到MappedFile,此時(shí)還未刷盤
  • 然后喚醒刷盤線程
  • 在Broker正常停止前,提交內(nèi)存page中的數(shù)據(jù)

到此這篇關(guān)于RocketMQ設(shè)計(jì)之異步刷盤的文章就介紹到這了,更多相關(guān)RocketMQ異步刷盤內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Spring定時(shí)任務(wù)只執(zhí)行一次的原因分析與解決方案

    Spring定時(shí)任務(wù)只執(zhí)行一次的原因分析與解決方案

    在使用Spring的@Scheduled定時(shí)任務(wù)時(shí),你是否遇到過任務(wù)只執(zhí)行一次,后續(xù)不再觸發(fā)的情況?這種情況可能由多種原因?qū)е?如未啟用調(diào)度、線程池問題、異常中斷等,本文將深入分析Spring定時(shí)任務(wù)只執(zhí)行一次的原因,并提供完整的解決方案,需要的朋友可以參考下
    2025-03-03
  • Java 類型信息詳解和反射機(jī)制介紹

    Java 類型信息詳解和反射機(jī)制介紹

    這篇文章主要介紹了Java 類型信息詳解和反射機(jī)制介紹,需要的朋友可以參考下
    2020-11-11
  • 關(guān)于SpringBoot打包測(cè)試、生產(chǎn)環(huán)境方式

    關(guān)于SpringBoot打包測(cè)試、生產(chǎn)環(huán)境方式

    這篇文章主要介紹了關(guān)于SpringBoot打包測(cè)試、生產(chǎn)環(huán)境方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • 淺試仿?mapstruct實(shí)現(xiàn)微服務(wù)編排框架詳解

    淺試仿?mapstruct實(shí)現(xiàn)微服務(wù)編排框架詳解

    這篇文章主要為大家介紹了淺試仿?mapstruct實(shí)現(xiàn)微服務(wù)編排框架詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • Springboot如何設(shè)置靜態(tài)資源緩存一年

    Springboot如何設(shè)置靜態(tài)資源緩存一年

    這篇文章主要介紹了Springboot如何設(shè)置靜態(tài)資源緩存一年,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-11-11
  • java.lang.IllegalStateException異常解決

    java.lang.IllegalStateException異常解決

    異常是程序在執(zhí)行過程中遇到的錯(cuò)誤或異常情況,本文就來介紹一下java.lang.IllegalStateException異常解決,感興趣的可以了解一下
    2023-11-11
  • java中List接口的方法詳解

    java中List接口的方法詳解

    這篇文章主要介紹了java中List接口的方法詳解,List接口是繼承Collection接口,所以Collection集合中有的方法,List集合也繼承過來,本文主要介紹一下list下的方法,需要的朋友可以參考下
    2023-10-10
  • 詳解Mybatis Generator的具體使用教程

    詳解Mybatis Generator的具體使用教程

    Mybatis Generator可以幫助我們自動(dòng)生成很多結(jié)構(gòu)化的代碼,比如每張表對(duì)應(yīng)的Entity、Mapper接口和Xml文件,可以省去很多繁瑣的工作,今天通過本文給大家介紹Mybatis Generator的具體使用教程,感興趣的朋友一起看看吧
    2022-02-02
  • struts2自定義攔截器的示例代碼

    struts2自定義攔截器的示例代碼

    本篇文章主要介紹了struts2自定義攔截器的示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-08-08
  • java基礎(chǔ)的詳細(xì)了解第四天

    java基礎(chǔ)的詳細(xì)了解第四天

    這篇文章對(duì)Java編程語言的基礎(chǔ)知識(shí)作了一個(gè)較為全面的匯總,在這里給大家分享一下。需要的朋友可以參考,希望能給你帶來幫助
    2021-08-08

最新評(píng)論

鄯善县| 永嘉县| 梓潼县| 疏附县| 铜山县| 井陉县| 西峡县| 东台市| 呈贡县| 林西县| 横峰县| 合江县| 志丹县| 仁化县| 洱源县| 南康市| 方城县| 旅游| 郎溪县| 金寨县| 孝昌县| 乾安县| 绵阳市| 浠水县| 铜陵市| 沁水县| 富阳市| 张家川| 唐海县| 郑州市| 光山县| 板桥市| 班玛县| 凤冈县| 高平市| 中山市| 惠水县| 新绛县| 靖江市| 新建县| 江陵县|