#log #commit #logged #applications #events #kafka #networking

streambed-logged

Logged是一个小型的库,实现了基于文件系统的提交日志

5个不稳定版本

0.11.0 2024年8月16日
0.10.2 2024年8月13日
0.10.1 2024年8月13日
0.10.0 2024年8月13日
0.9.1 2023年10月18日

#1213 in 文件系统

Download history 1/week @ 2024-05-08 12/week @ 2024-05-15 9/week @ 2024-05-22 5/week @ 2024-06-05 18/week @ 2024-06-12 8/week @ 2024-07-24 9/week @ 2024-07-31 218/week @ 2024-08-07 349/week @ 2024-08-14

584次每月下载
用于 streambed-logged-cli

Apache-2.0

135KB
2.5K SLoC

logged

Logged是一个小型的库,为经常位于更大网络边缘的自主系统实现了基于文件系统的提交日志功能。

Logged实现了Streambed提交日志API,该API反过来又以Kafka API为模型。

快速介绍

没有什么能比代码更快地介绍事物了!以下是一个建立提交日志、生产记录然后消费它的例子。请参考各种测试以获取更完整的示例。

  let cl = FileLog::new(logged_dir);

  let topic = Topic::from("my-topic"_;

  cl.produce(ProducerRecord {
      topic: topic.clone(),
      headers: None,
      timestamp: None,
      key: 0,
      value: b"some-value".to_vec(),
      partition: 0,
  })
  .await
  .unwrap();

  let subscriptions = vec![Subscription {
      topic: topic.clone(),
  }];
  let mut records = cl.scoped_subscribe("some-consumer", None, subscriptions, None);

  assert_eq!(
      records.next().await,
      Some(ConsumerRecord {
          topic,
          headers: None,
          timestamp: None,
          key: 0,
          value: b"some-value".to_vec(),
          partition: 0,
          offset: 0
      })
  );

为什么选择logged?

Logged的主要功能用例包括

  • 事件溯源 - 从事件中重新构建状态;
  • 观察 - 为一个或多个消费者可靠地传递事件。

Logged的主要操作用例包括

  • 由资源受限的设备托管,通常具有小于128MiB的内存和8GB的存储空间。

什么是logged?

无网络

Logged没有关于网络的任何概念。Logged管理的数据的任何复制都应在它之外处理。

内存与速度

Logged针对小内存使用进行了优化,速度其次,同时认识到存储是有限的。

单写者/多读者

Logged故意限制了将提交日志追加到一个进程。这被称为单写者原则,极大地简化了Logged的设计。

多读者进程

读者可以存在于写入提交日志主题的进程之外。由于读者和写者都读取文件系统上的相同文件,因此不需要涉及任何代理进程。由于单写者原则,写入不需要锁定。

无加密、压缩或认证

加密和压缩是应用关注的问题,鼓励加密。压缩可能不太重要,这取决于应用程序需要保留的数据量。

在假设加密的情况下,身份验证被绕过。如果一个读者无法解密一条消息,那么这被认为和一开始就得不到访问权限一样。避免身份验证会产生一个额外副作用,即不需要管理身份,从而保持日志的复杂性最低。

数据保留是应用程序关注的问题。

Logged提供了工具,使应用程序能够执行压缩。我们应用提交日志的经验表明,数据保留策略通常是应用程序关注的问题,通常取决于数据内容。

Apache Kafka模型

Logged采用了与Apache Kafka相同的概念,包括主题、分区、键、记录、偏移量、时间戳和头信息。因此,使用Logged的服务可能易于移植到Kafka和其他平台。

数据完整性

使用CRC32C校验和来确保数据完整性,以应对主机突然断电的残酷现实。任何检测到的错误,包括不完整的写入或压缩,都将自动恢复。

Logged是如何实现的?

Logged作为一个库实现,避免了需要代理进程。这与JVM上的Chronicle Queue类似。

文件系统用于根据主题和单个分区存储记录。《Tokio》用于文件读写操作,以便任何停滞的操作允许其他任务继续运行。《Postcard》用于序列化,因为它能够方便地表示内存结构,并且针对资源受限的目标进行了优化。

当在主题中查找偏移量时,Logged将按顺序读取记录,因为没有索引。这种简单的方法依赖于处理器快速扫描内存的能力(它们确实如此),以及应用级压缩的有效性。我们所说的“有效”是指扫描可以避免遍历数千条记录。

主题的压缩是应用程序关注的问题,因为它能够考虑记录的内容。Logged提供了原子性地“分割”现有主题日志的头部并生成一个新主题以进行压缩的函数。基于应用程序的压缩器可以消耗现有主题,保留它需要的记录在内存中。在消耗主题后,基于应用程序的压缩器将保留的记录追加到要压缩的主题。一旦追加完成,Logged可以被指示用压缩后的日志替换旧的日志。同时,任何在分割日志后追加的新记录将写入另一个新的日志文件。因此,在压缩活动期间,可能会有两个表示主题的文件,有时甚至有三个。Logged负责解释当应用程序与主题一起操作时使用的文件系统和各种文件。

何时不应使用Logged?

当你有Kafka时。

依赖关系

~7–9.5MB
~163K SLoC