Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactoring and improving Tiered Storage Implementation #6633

Closed
lizhimins opened this issue Apr 23, 2023 · 2 comments · Fixed by #7342
Closed

Refactoring and improving Tiered Storage Implementation #6633

lizhimins opened this issue Apr 23, 2023 · 2 comments · Fixed by #7342

Comments

@lizhimins
Copy link
Member

lizhimins commented Apr 23, 2023

我阅读了关于分级存储的代码,现有的模型与实现非常混乱,因此我对分级存储进行了一些改进。

这些改动主要包括以下内容:

1. 关于模型抽象

1. 去除抽象耦合

在原本的设计中,MessageQueue 的概念和所有的模型强耦合。先来对比本地的 default message store,对于 File 和 File Queue 的抽象,是将多个 mmap 的文件组合成链表。这属于偏向文件系统侧的实现,和消息队列本身概念无关,不应该把 mq 的概念向其他组件渗透。内存中的 FileSegment 和 FileSegmentQueue 属于冰山对象的引用,他们应该只关心文件路径 filePath。这个设计也破坏了 TieredIndexFile 中的一些代码层次,这种持久化模型和实际运行模型不匹配的设计是非常不友好的。

2. 封装,上帝类与可观测性问题

在原来的实现中,FileSegment 和 FileSegmentQueue 是最小粒度的数据管理者,不应该把 metadata store 和 attribute 向下传递,糅合到这些简单对象中,这是一种严重破坏封装的设计。举个例子,假设某个类有一个计数器,这个值需要对其他类暴露,不应该把上层对象向下传递,而应该暴露出当前值。
例如 messageStore.getMinOffset(), getMaxOffset() 的做法,这是一个类似于 Monitor 的实现。

3. 使用组合向下屏蔽

例如:FileSegmentQueue 的 getFileToWrite getFileSegment 暴露了底层实现,这里应该在中间加一个组合实现(某种意义上的桥接)来屏蔽。

2. 线程模型和锁粒度

目前的设计中 commit 和 append 线程模型不合理,导致锁的粒度过大。swap queue 的最小粒度是和定时任务绑定。在上传的时候 commitlog 是优先于 consumequeue 持久化的,这里线程的等待设计不合理,需要减小 swap 锁的粒度。

3. 对象构造和元数据管理

1. 反射存在于构造函数中

在原本的设计中,FileSegment 和 SegmentQueue 每次初始化都会依赖于 storeConfig,这里就很适合使用工厂模式复用配置而不是传递引用,当然更好的实现是 SPI 化。

2. 元数据管理改进

元数据管理结构混乱,模型层次不清晰,领域知识比较分散。
例如:TieredMetadataStore 不应该关心 FileSegment,只需要关注 FileSegmentMetadata。
就像 TopicConfigManager 只关心 TopicConfig 而不需要关心 MappedFile 一样。
例如:下面这两个实现应该在 SegmentQueue 而不应该在 MetadataStore 中

void updateFileSegment(TieredFileSegment fileSegment);

FileSegmentMetadata getOrCreateFileSegment(TieredFileSegment fileSegment);

4. 其他优化部分

  • getFileToWrite() 实际上包含了很多写行为,去除只读方法的副作用。
  • 修复 offset 未声明 volitile,config manager encode 时候序列化没有生效
  • destroyContainer 重复删除等 bug 修复和保护性逻辑优化
  • 增加单测,对于返回值错误码添加说明。

当然,改进后的设计并不是尽善尽美的,欢迎提交 pr 共建,之后我还将提交一个 bugfix list。

lizhimins added a commit to lizhimins/rocketmq that referenced this issue May 21, 2023
lizhimins added a commit to lizhimins/rocketmq that referenced this issue May 21, 2023
@absolute8511
Copy link
Contributor

冷存储上topic已经分离了,是否还需要保留consumequeue这样的文件,收益好像不是很明显?

lizhimins added a commit that referenced this issue Jun 9, 2023
[ISSUE #6633] [RIP-65] Improving Tiered Storage Implementation
@lizhimins
Copy link
Member Author

冷存储上topic已经分离了,是否还需要保留consumequeue这样的文件,收益好像不是很明显?

cq 是为了索引拆分后的 commitlog,以定长结构去定位变长结构,还是比较合理的。。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants