#record #log #queue #position #shared #truncate #durable

bin+lib mrecordlog

Quickwit 共享记录日志

3 个版本 (破坏性更新)

0.4.0 2023年7月3日
0.3.0 2023年3月23日
0.2.0 2023年3月13日

#4 in #durable

MIT 许可证

130KB
3K SLoC

这是什么?

此crate实现了一种高效处理多个记录日志的解决方案。每个记录日志都有自己的“本地”位置概念。可以单独截断每个队列。

目标

  • 持久化,在 fsync 策略上提供一些灵活性。
  • 提供在特定位置截断队列的方法
  • 处理任意数量的队列
  • 具有有限的IO
  • 速度快
  • 提供实现推回的可能性
pub struct MultiRecordLog {
    pub async fn create_queue(&mut self, queue: &str) -> Result<(), CreateQueueError>;
    pub async fn delete_queue(&mut self, queue: &str) -> Result<(), DeleteQueueError>;
    pub fn queue_exists(&self, queue: &str) -> bool;
    pub fn list_queues(&self) -> impl Iterator<Item = &str> {
    pub async fn append_record(
        &mut self,
        queue: &str,
        position_opt: Option<u64>,
        payload: &[u8],
    );
    pub async fn truncate(&mut self, queue: &str, position: u64) -> Result<(), TruncateError>;
    pub fn range<R>(
        &self,
        queue: &str,
        range: R,
    ) -> Option<impl Iterator<Item = (u64, &[u8])> + '_>;
}

非目标

这不是Kafka。该记录日志是为“少量数据”设计的。所有保留的数据都可以放入RAM中。

在quickwit的上下文中,该队列用于PushAPI,并打算包含1单位的数据。(60MB/s意味着3.6GB的RAM)

仅在启动时读取记录日志文件。读取记录日志文件的高性能不是目标。另一方面,快速写入很重要。

实现细节。

mrecordlog 将多个独立的队列多路复用到同一个记录日志中。这种方法的好处是限制了所需文件描述符的数量,更重要的是,限制了 fsync 的数量。

它还提供了截断给定记录日志队列的可能性。实际的数据删除发生在文件仅包含删除的记录时。然后,只有在那时,整个文件才会被删除。

该记录日志每1GB生成一个新的文件。一旦所有队列在文件的最后一个记录之后都被截断,记录日志文件就会被删除。

没有压缩逻辑。

待办事项

  • 添加背压。
  • 添加fsync策略
  • 更好的测试
  • 非自增位置
  • 减少Arc

依赖项

~3–5.5MB
~90K SLoC