英语在线翻译网站RocketMQ⽂件过期策略详解
aeroplane怎么读
1.为什么会有⽂件过期删除机制
由于RocketMQ操作CommitLog、ConsumeQueue⽂件是基于⽂件内存映射机制,并且在启动的时候会将所有的⽂件加载,为了避免内存与磁盘的浪费、能够让磁盘能够循环利⽤、避免因为磁盘不⾜导致消息⽆法写⼊等引⼊了⽂件过期删除机制
2.RocketMQ删除过期⽂件的思路
RocketMQ顺序写CommitLog⽂件、ComsumeQueue⽂件,所有的写操作都会落到最后⼀个⽂件上,因此在当前写⽂件之前的⽂件将不会有数据插⼊,也就不会有任何变动,因此可通过时间来做判断,⽐如超过72⼩时未更新的⽂件将会被删除
PS:RocketMQ删除过期⽂件时不会关注该⽂件的内容是否全部被消费
3.⽂件过期删除机制实现
3.1 触发删除的操作
image.png
由上图可知,触发⽂件清除操作的是⼀个定时任务,⽽且只有定时任务
// Resource reclaim interval
private int cleanResourceInterval = 10000;
⽂件过期删除定时任务的周期由该删除决定,默认每10s执⾏⼀次
3.2 删除源码分析
MesssageSDefaultStore#CleanCommitLogService#deleteExpiredFiles
private void deleteExpiredFiles() {
//省略
}
我们⼀点⼀点来分析其中的代码
long fileRervedTime = MessageStoreConfig().getFileRervedTime();
int deletePhysicFilesInterval = MessageStoreConfig().getDeleteCommitLogFilesInterval();
int destroyMapedFileIntervalForcibly = MessageStoreConfig().getDestroyMapedFileIntervalForcibly();
上⾯三个属性需要重点讲解下
1. fileRervedTime:⽂件过期时间,也就是从⽂件最后⼀次的更新时间到现在为⽌,如果超过该时间,则是过期⽂件可被删除
2. deletePhysicFilesInterval:删除物理⽂件的时间间隔,在⼀次定时任务触发时,可能会有多个物理⽂件超过过期时间可被删除,因深圳商务英语培训
此删除⼀个⽂件后需要间隔deletePhysicFilesInterval这个时间再删除另外⼀个⽂件,我猜测可能是由于删除⽂件是⼀个⾮常耗费IO 的操作,会引起消息插⼊消费的延迟(相⽐于正常情况下),所以不建议直接删除所有过期⽂件
3. destroyMapedFileIntervalForcibly:在删除⽂件时,如果该⽂件还被线程引⽤,此时会阻⽌此次删除操作,同时将该⽂件标记不可
⽤并且纪录当前时间戳destroyMapedFileIntervalForcibly这个表⽰⽂件在第⼀次删除拒绝后,⽂件保存的最⼤时间,在此时间内⼀直会被拒绝删除,当超过这个时间时,会将引⽤每次减少1000,直到引⽤ ⼩于等于 0为⽌,即可删除该⽂件,实现代码如下:
口译笔记ReferenceResource#shutdown
public void shutdown(final long intervalForcibly) {
if (this.available) {
this.available = fal;
this.firstShutdownTimestamp = System.currentTimeMillis();
} el if (RefCount() > 0) {
if ((System.currentTimeMillis() - this.firstShutdownTimestamp) >= intervalForcibly) {
degrees
}
}
tower}
MesssageSDefaultStore#CleanCommitLogService#deleteExpiredFilescold是什么意思中文翻译
boolean timeup = this.isTimeToDelete();
pac man
boolean spacefull = this.isSpaceToDelete();
boolean manualDelete = this.manualDeleteFileSeveralTimes > 0;
if (timeup || spacefull || manualDelete) {
//执⾏删除逻辑
}
mark zuckerberg
1.
timeup:是否到了指定的时间点,RocketMQ可通过deleteWhere设置每天固定的时间删除过期⽂件,默认是凌晨4点,由于这个参数设定是⼩时,因此在这1个⼩时内每次定时任务都能进来删除过期的⽂件
image.png
UtilAll#isItTimeToDo
public static boolean isItTimeToDo(final String when) {
String[] whiles = when.split(";");
if (whiles.length > 0) {
Calendar now = Instance();
for (String w : whiles) {
int nowHour = Integer.parInt(w);
if (nowHour == (Calendar.HOUR_OF_DAY)) {
return true;
}
}
}
return fal;
}
1. spacefull:磁盘空间是否充⾜,磁盘不⾜返回true,执⾏过期⽂件删除策略,我们进去看看this.isSpaceToDelete()这个⽅法
MesssageSDefaultStore#CleanCommitLogService#isSpaceToDelete
double ratio = MessageStoreConfig().getDiskMaxUdSpaceRatio() / 100.0;
//是否⽴即清除
cleanImmediately = fal;
{
String storePathPhysic = MessageStoreConfig().getStorePathCommitLog();
double physicRatio = DiskPartitionSpaceUdPercent(storePathPhysic);
if (physicRatio > diskSpaceWarningLevelRatio) { /**#1*/
boolean diskok = DefaultMessageStore.AndMakeDiskFull();
if (diskok) {
("physic disk maybe full soon " + physicRatio + ", so mark disk full");
}
cleanImmediately = true;
} el if (physicRatio > diskSpaceCleanForciblyRatio) {/**#2*/
cleanImmediately = true;
} el {/**#3*/
boolean diskok = DefaultMessageStore.AndMakeDiskOK();
if (!diskok) {
DefaultMessageStore.log.info("physic disk space OK " + physicRatio + ", so mark disk ok");
}
}
if (physicRatio < 0 || physicRatio > ratio) {/**#4*/
DefaultMessageStore.log.info("physic disk maybe full soon, so reclaim space, " + physicRatio);
return true;
}
}
1:物理使⽤率⼤于diskSpaceWarningLevelRatio(默认90%可通过参数设置),则会阻⽌新消息的插⼊
2:物理使⽤率⼤于diskSpaceCleanForciblyRatio(默认85%,可设置),则过进⾏过期物理⽂件的删除
3:恢复磁盘可写配合 #1使⽤
4:物理磁盘使⽤率⼩于diskMaxUdSpaceRatio 表⽰磁盘使⽤正常
2. manualDelete:预留,⼿⼯触发,⽬前rocketmq暂未封装
MappedFileQueue#deleteExpiredFileByTime
for (int i = 0; i < mfsLength; i++) {
MappedFile mappedFile = (MappedFile) mfs[i];
long liveMaxTimestamp = LastModifiedTimestamp() + expiredTime;
if (System.currentTimeMillis() >= liveMaxTimestamp || cleanImmediately) {
if (mappedFile.destroy(intervalForcibly)) {
files.add(mappedFile);
deleteCount++;
if (files.size() >= DELETE_FILES_BATCH_MAX) {
break;
}
if (deleteFilesInterval > 0 && (i + 1) < mfsLength) {
try {
Thread.sleep(deleteFilesInterval);
} catch (InterruptedException e) {
}
}
} el {
break;
}
} el {
//avoid deleting files in the middle
break;
}
}
image.png
从第⼀个⽂件开始遍历,判断该⽂件的最⼤存活时间(该⽂件的最后⼀次更新时间+⽂件的存活时间)⼩于 当前系统时间 或者 需要强制删除⽂件(上⾯有讲,哪些情况下强制删除),则执⾏MappedFile#destroy ⽅法清除MappedFile占⽤的相关资源,如果执⾏成功则将该⽂件加⼊待删除⽂件列表中统⼀从磁盘中删除。DELETE_FILES_BATCH_MAX 决定每次能够删除的⽂件个数上限、deleteFilesInterval连续清除两个⽂件的时间间隔由该参数决定(deletePhysicFilesInterval)
4.总结-整体流程汤圆 英文
1. 开启定时任务每10s扫描是否有⽂件需要删除
2. 有三种情况会进⼊删除⽂件操作:到了deleteWhere指定的时间点(默认是凌晨4点)、磁盘不⾜、⼿动触发
3. 对于磁盘不⾜的情况,当磁盘使⽤率⼤于磁盘空间警戒线⽔位(默认是90%),会阻⽌消息写⼊,当超过85%时会强制删除⽂件(需
要设置允许强制删除参数,否者不⽣效),其他两种情况都只能删除过期的⽂件(⽂件最后更新时间+⽂件最⼤的存活时间 < 当前时间)
4. 当被删除的⽂件存在引⽤时,会有⼀个⽂件删除缓存时间,在这段时间内,该⽂件不会被删除,主要是留给引⽤该⽂件程序⼀些时
间,当超过了⽂件删除缓存时间后,每次都会将该⽂件的引⽤减少1000,直到减少⼩于等于0后才释放该⽂件引⽤的相关资源,然后将该⽂件放⼊⼀个“⽂件删除集合”中
5. ⼀次连续删除⽂件中间会存在⼀定的间隔,不会连续释放⽂件相关的资源
6. ⼀次连续删除的⽂件和不⼤于10
7. 将“⽂件删除集合”中的⽂件从