RockEtMQ中存储的文件主要包括提示文件文件,“使用”文件和索引文件。
RocketMQ将所有主题消息存储在同一文件中,以确保发送消息时编写消息以确保消息发送的高可用性和高吞吐量。
但是,消息的中间软件通常基于主题订阅和发布模式。当消息消耗主题时,必须根据主题选择它。显然,筛选消息将根据主题文件从collionlog文件效率低下。根据效率,RockEtMQ引入了Clasteumequeue文件,该文件是消费者队列文件。
关系数据库可以根据字段属性记录。作为主要面向的消息中间件,RocketMQ还提供了消息属性检索能力。在索引文件中。
在RocketMQ中写入Commitlog文件后,使用和索引文件是异步的。数据流量如下:
RocketMQ在消息编写期间追求终极磁盘顺序。所有主题消息都写入文件,即commitlog文件。所有消息都按照到达顺序添加到文档中。一旦写出新闻,它就不支持修改。提交文件的特定布局如下图所示:
基于文件编程和基于内存的编程有很大的差异。在基于内存的编程模式下,我们有准备好制造的数据结构,例如列表和hashmap。如何找到?
就像关系数据将向每个数据引入一个ID字段一样。在基于文件的模型中,它还将向消息介绍一条消息:消息的物理偏移,即,该消息存储在文件的起始位置中。
这是物理偏移的概念,Commitlog文件的名称也非常熟练。该文件中的文件中存储的第一条消息命名为.commitlog文件为
00000000000000000,第二个文件是
000000000073741824,然后按顺序按下。
这样做的优点是给出任何消息的物理偏移。例如,消息偏移为73741824。您可以通过两个点方法找到它。该文件很快位于第一个文件中,然后使用消息的物理偏移。减去文件名是文件中的绝对地址。
Commitlog文件的设计概念是传达最终信息,但是我们知道消息消费模型基于主题订阅机制,即,消费者群体是一个特殊的消费者特定于特定的主题。根据主题,我们将发现这绝不是一个好主意。它只能从文件的第一消息中检索。可以想象它的性能。引入了消费式文件,下图显示了用途的结构。
消耗文件是消息消费者队列文件。这是基于主题索引文件的提交文件。它主要根据主题消费消息用于消费者。组织方法是/主题/队列。同一队列中有多个文件。
Castumequeue的设计非常熟练,每个条目都是固定的(8个字节commitlog物理偏移量,4个字节消息长度,8个字节标签哈希码)。
这不是存储标签的原始字符串,并且存储主题的选择是确保固定每个条目的长度。您可以使用访问类似阵列的竞标的方法快速定位条目,从而大大提高了消耗文件的读取性能。
想象一下,基于主题和消息消费进度的新闻消费者(comenumeuqe逻辑偏移),即几个消费条目。访问消息的方法可以找到这样的消费进度来找到逻辑偏移逻辑 * 20以找到此条目。启动偏移(在Clubseumequeue文件中偏移),然后在阅读偏移后读取20个字节以获取音符,注释,不穿越消耗文件。
与Kafka相比,RocketMQ具有强大的优势,也就是说,支持消息属性的信息检索,引入了“使用量”文件以解决基于主题的搜索问题,但是如果您想根据消息找到消息,请使用COUBSUMEQUEUE FILE是无与伦比的。
RocketMQ引入索引索引文件以实现基于文件的哈希索引。IndexFile的文件存储结构如下图所示:
IndexFile文件实现了基于物理磁盘文件的哈希索引。ITS文件为40个bytes,500万个哈希插槽,每个哈希插槽的4个字节,最后由2000万个索引条目组成。每个条目由20个字节组成,即4个字节索引keyhashcode,8个字节消息物理偏移,4个字节时间戳记,第一个索引条目的4个字节(哈希冲突的链接列表结构)。
也就是说,建立了索引键和物理偏移之间的映射关系,并根据密钥迅速将其定义为collistLog文件。
基于基于磁盘的读取和写作的另一个设计原理是磁盘的顺序。
磁盘顺序广泛用于基于文件的存储模型。每个人都可能希望考虑引入MySQL重做日志。我们知道,在MySQL InnoDB的存储引擎中,将有一个用于缓存磁盘以进行更新的内存块。语句修改数据后,它将首先在内存中修改,然后将更改写入重做文件(刷子在磁盘上),然后定期将InnoDB内存池中的数据刷到磁盘。
为什么不尽快更改数据,直接将其直接更新为指定的数据文件?在MySQL InnoDB中使用了数千个库存,每件的数据将使用单独的文件存储。如果每个表的数据更改,将编写大量随机写作。因此,性能无法提高。因此,用重做文件介绍了重做文件,这是从表面逐步操作的步骤,但是由于按顺序编写,与相比,性能改进非常重要随机写作。
尽管基于磁盘的顺序的顺序可以极大地提高IO的写作效率,但如果基于文件的存储的存储使用常规的Java文件操作API,例如FileOutputStream,则其性能将非常有限。RockEtMQ引入内存映射并映射磁盘文件绘制内存,通过操作内存操作磁盘,并且性能改善了另一个等级。
通过Java中的Filechannel Map方法创建内存映射文件。
该方法在Linux服务器中创建的文件使用操作系统的PageCache,即页面缓存。
在Linux操作系统中使用内存策略时,它将尽可能多地使用计算机的物理内存,在居民内存中,它是So -call page cache。在操作系统内存不足的情况下使用缓存替换算法。例如,LRU将恢复未使用的页面缓存,也就是说,操作系统将自动管理内存的这一部分。
如果RockEtMQ经纪流程异常退出,则将存储在页面缓存中的数据不会丢失,并且操作系统将定期将数据存放到磁盘中以确保数据安全可靠。一个异常情况(例如机器)可能会丢失页面缓存中的数据。
有了写作和记忆映射顺序的祝福,RocketMQ的写作表现得到了极大的保证。磁盘没有真正的持久性。页面缓存并恢复成功,还是必须持续到磁盘才能恢复成功?
这是一个“困难”的选择,在性能和新闻可靠性方面权衡。为此,RocketMQ提供了多种策略:同步刷牙和异步刷牙。
1.同步刷盘
在RocketMQ实现时,同步刷牙刷到了组提交中,并非必须刷所有消息。设计概念如图所示:
使用同步刷盘。每个线程将数据追溯到内存之后,将笔刷请求提交到滚动线程中,然后将其阻止;从任务队列中获取任务,然后触发刷子,但不仅是ininstead,与请求相关的消息将直接在内存中批处理中的内存中的所有消息,然后您可以唤醒一组请求线程要实现小组刷。
2.异步刷盘
同步刷牙的优点是,它可以确保消息不会丢失,也就是说,返回客户的成功意味着新闻已持续到磁盘上,也就是说,新闻非常可靠,但这是在牺牲延迟表现的费用。因为这是因为牺牲的表现延迟,所以RocketMQ的信息是首先编写PageCache,因此丢失消息的可能性较小。如果您可以忍受一定机会的损失,则可以考虑使用异步刷。
异步刷是指立即将消息存储到PageCache,然后返回成功,然后打开一个异步线程一次执行FileChannel Forece方法,并定期将数据写入磁盘中。默认间隔为500ms。
为了减少Pagecache使用PageCache的压力,RocketMQ引入了瞬态店主机制,即记忆级别的读取和编写分离机制。
默认情况下,RocketMQ将消息读取到PageCache中。当消息消耗时,请从Pagecache阅读。在高并发期间,这将相对较高。它很容易瞬时经纪人。以下:
该消息在阅读时不会尝试从外部内存中读取,而是从Pagecache读取的。这形成了内存级别的读取和写作分离,也就是说,当消息写在pagecache上时。
该方案的优点是,该消息是直接写入内存堆,然后与Pagecache.com异步到每条消息,最大的优势是直接写入Pagechae,其最大优势是书面消息是编写的。进入PageCache操作。
该方案的缺点是,如果经纪人流程由于某些事故而异常退出,则存储在堆外部的数据将丢失,但是如果将其放入Pagecache中,则违反了异常出口不会丢失信息。
资料来源:阿里巴巴云
