用于存储仅附加消息的数据结构和文件结构



消息是具有唯一消息ID(整数)的可变大小的数据束。我想有一个设计/数据结构/算法:

  1. 能够有效地将消息存储在磁盘上,消息的数量可以很大,长度是可变的。但没有对存储的内容进行更新或修改
  2. 能够检索具有消息ID的消息,即返回存储的消息
  3. 查询最近存储的消息的频率高于查询旧消息的频率
  4. 每个消息都有一个TTL,需要一种用旧消息截断文件的方法

满足此需求的适当数据结构和文件结构是什么?

如果我们每秒谈论五条消息,那么您每天谈论的消息数量约为50万条。

我过去所做的就是维护多个文件。如果消息的TTL是以天为单位测量的,那么我每天有一个消息文件。读取和存储消息的过程会为新一天的第一条消息创建一个新文件。通过跟踪最后一条消息的接收日期和时间,实现这一点很简单。

我还维护了一个与每个消息文件成对的索引文件。这也是一个简单的顺序文件,包含每条消息的消息ID和位置。因此,要查找特定日期的消息,请加载当天的文件,对消息ID进行二进制搜索,然后使用相应的位置在消息文件中查找消息。如果消息ID是连续的并且没有数字丢失,那么在索引中查找应该非常快。如果你可以有丢失的数字,那么二进制搜索工作得很好。由于只有512K条消息,二进制搜索将非常快。

要处理多天,您需要查找程序的启动顺序扫描目录中的所有每日消息索引,并构建一个元索引,其中包含每天第一条消息的ID。

要删除旧邮件,您可以让查找程序在启动时删除旧文件,或者让它在每天午夜删除旧文件。届时,它还可以获得第二天文件中第一条消息的ID。

或者,消息收集器可以在收到新的一天的第一条消息时生成删除旧文件的任务。您还可以让它通知查找程序新的一天,以便查找程序可以更新其元索引。

由于每天只有512K条消息(每秒5条大约相当于每天50万条),您应该能够在内存中保留10天的索引条目,而不会遇到麻烦。您的索引将包含一个消息ID和文件偏移量,因此请为每个条目计算16个字节。10天500万次,相当于80兆字节:零钱。要删除旧条目(每天一次),只需从内存中删除当天的索引即可。

如果消息的TTL不同,那么您可以保留旧消息,但要跟踪它们的TTL。当有人查找过期邮件时,在返回之前,你必须对过期日期进行二次检查。当然,你还必须跟踪每天最长的TTL,以便在所有邮件过期时删除文件。

这是一个技术含量很低的解决方案,但你可以在一天内对其进行编码,而且它的工作和性能都非常好。我已经在几个项目中使用过它,效果很好。

最新更新