106 个版本 (6 个重大变更)
新 0.6.12 | 2024 年 8 月 18 日 |
---|---|
0.5.1 | 2024 年 7 月 23 日 |
0.2.19 | 2024 年 3 月 31 日 |
0.1.2 | 2023 年 12 月 31 日 |
0.0.12 | 2023 年 7 月 31 日 |
#55 在 数据库接口
每月 1,017 次下载
在 iggy-cli 中使用
795KB
19K SLoC
Iggy
Iggy 是用 Rust 编写的持久消息流平台,支持 QUIC、TCP(自定义二进制规范)和 HTTP(常规 REST API)传输协议。目前作为单个服务器运行,允许创建流、主题、分区和段,并可以向/从它们发送/接收消息。消息以追加日志的形式存储在磁盘上,并在重启之间持久化。
项目的目标是创建一个分布式流平台(作为集群运行),该平台能够水平扩展并处理每秒数百万条消息(实际上,它已经非常快了,请参阅下面的基准测试)。
Iggy 在利用最少的计算资源的同时提供了 非常高的吞吐量和性能。
这不是在现有基础设施(如 Kafka 或 SQL 数据库)之上运行的另一个扩展。
伊吉(Iggy)是一款持久化消息流日志,它从头开始构建,使用低级I/O来提高速度和效率。
这个名字是意大利猎犬的缩写——体型小巧但速度极快,是这个类别中的佼佼者。就像我那可爱的Fabio & Cookie ❤️
特性
- 高性能,持久化的只追加日志,适用于消息流
- 读写吞吐量非常高
- 得益于Rust编译语言(无GC),具有低延迟和可预测的资源使用
- 用户身份验证和授权,具有细粒度权限和PAT(个人访问令牌)
- 支持多流、主题和分区
- 支持多种传输协议(QUIC、TCP、HTTP)
- 完全可操作的RESTful API,可选择性启用
- 提供多种语言的客户端SDK
- 直接与二进制数据工作(无强制的模式,无序列化和反序列化)
- 可配置的服务器功能(例如,缓存、段大小、数据刷新间隔、传输协议等)
- 可在服务器上存储消费者偏移量
- 多种轮询消息的方式
- 通过偏移量(使用索引)
- 通过时间戳(使用时间索引)
- 前N/后N条消息
- 为特定消费者获取下一N条消息
- 支持自动提交偏移量(例如,实现最多一次投递)
- 消费者组提供消息顺序和跨连接客户端的水平扩展
- 消息过期,根据可配置的保留策略自动删除
- 其他功能,如服务器端消息去重
- 由于流的概念,支持多租户,这些流将主题分组
- 所有传输协议(TCP、QUIC、HTTPS)都支持TLS
- 可选的AES-256-GCM服务器端和客户端数据加密
- 可选的支持消息头形式的元数据
- 内置的CLI,用于管理流服务器
- 内置的基准测试应用,用于测试性能
- 单一二进制部署(无外部依赖项)
- 作为单个节点运行(目前不支持集群)
路线图
- 低级优化(零拷贝等)
- 无共享设计和支持io_uring
- 集群和数据复制
- 高级Web UI
- 支持多种语言的开发者友好的SDK
- 插件和扩展支持
有关当前进度的详细信息,请参阅项目板。
支持的语言SDK(工作中)
CLI
全新的丰富、交互式CLI正在cli
项目下实施,以提供最佳的开发者体验。这将是对Web UI的重大补充,特别是对于所有更喜欢使用控制台工具的开发者。
Web UI
目前正在努力构建服务器的管理Web UI,这将允许管理流、主题、分区、消息等。请查看Web UI存储库
Docker
您可以在存储库的根目录下找到Dockerfile
和docker-compose
。要构建和启动服务器,请运行:docker compose up
。
此外,您还可以在运行中的容器中运行CLI
,通过以下命令执行: docker exec -it iggy-server /iggy
。
请注意,在除Linux以外的操作系统上运行容器,其中Docker在虚拟机中运行,可能会导致性能显著下降。
官方镜像可以在这里找到,只需输入docker pull iggyrs/iggy
。
配置
默认配置可以在server.toml
(默认配置)或server.json文件中找到,该文件位于
configs
目录下。
配置文件是从当前工作目录加载的,但您可以通过设置IGGY_CONFIG_PATH
环境变量来指定配置文件的路径,例如export IGGY_CONFIG_PATH=configs/server.json
(或根据操作系统其他命令)。
有关配置文件的详细文档,请参阅配置部分。
快速入门
构建项目(较长的编译时间是由于在发布配置中启用了LTO)
cargobuild
运行测试
cargotest
启动服务器
cargor --biniggy-server
请注意,以下所有命令都使用iggy
二进制文件,它是发布(cli
子crate)的一部分。
使用默认凭证和tcp
传输(可用传输:quic
,tcp
,http
,默认tcp
)创建名为dev
的流(服务器将自动分配数字ID)
cargor --biniggy ----transport tcp --username iggy --password iggy stream create dev
列出可用的流
cargor --biniggy ----username iggy --password iggy stream list
获取dev
流详情
cargor --biniggy ---u iggy -p iggy stream get dev
为流dev
创建名为sample
的主题(服务器将自动分配数字ID),具有2个分区(ID 1和2),禁用压缩(none
)和禁用消息过期(跳过可选参数)
cargor --biniggy ---u iggy -p iggy topic create dev sample 2 none
列出流dev
的可用的主题
cargor --biniggy ---u iggy -p iggy topic list dev
获取流dev
中主题sample
的详细信息
cargor --biniggy ---u iggy -p iggy topic get dev sample
向流dev
的主题sample
和分区1发送消息'hello world'(消息ID 1)
cargor --biniggy ---u iggy -p iggy message send --partition-id 1 dev sample"hello world"
向同一流、主题和分区发送另一条消息'lorem ipsum'(消息ID 2)
cargor --biniggy ---u iggy -p iggy message send --partition-id 1 dev sample"lorem ipsum"
通过ID为1的常规消费者从流dev
的主题sample
和ID为1的分区中轮询消息,从偏移量0开始,消息计数2,不自动提交(在服务器上存储消费者偏移量)
cargor --biniggy ---u iggy -p iggy message poll --consumer 1 --offset 0 --message-count 2 --auto-commit dev sample 1
最后,重新启动服务器以查看它是否能够加载持久化的数据。
HTTP API端点可以在server.http文件中找到,可以使用VS Code的REST Client扩展来使用。
要查看CLI/服务器上的详细日志,请使用带有环境变量RUST_LOG=trace
的命令运行。见下文图片。
文件结构
服务器
示例
您可以在examples
目录下找到示例消费者和生成器应用程序。这些应用程序的目的是展示客户端SDK的用法。有关构建应用程序的更多信息,请参阅入门指南。
要运行示例,首先使用以下命令启动服务器:cargo r --bin iggy-server
,然后分别使用以下命令运行生成器和消费者应用程序:cargo r --example message-envelope-producer
和cargo r --example message-envelope-consumer
。
您可能同时启动多个生成器和消费者,以查看消息如何被多个客户端处理。查看Args结构以查看可用选项,例如传输协议、流、主题、分区、消费者ID、消息大小等。
默认情况下,消费者将使用自动提交启用来轮询消息,使用下一个可用的偏移量来在服务器上存储其偏移量。使用这种方法,您可以轻松实现最多一次投递。
SDK
Iggy附带Rust SDK,可在crates.io上找到。
SDK提供低级客户端,用于特定传输,包括消息发送和轮询以及所有管理操作,如管理流、主题、用户等,以及高级客户端,它抽象了底层细节,并为消息生产者和消费者提供易于使用的API。
您可以在examples
目录下找到更多示例,包括多租户示例。
// Create the Iggy client
let client = IggyClient::from_connection_string("iggy://user:secret@localhost:8090")?;
// Create a producer for the given stream and one of its topics
let mut producer = client
.producer("dev01", "events")?
.batch_size(1000)
.send_interval(IggyDuration::from_str("1ms")?)
.partitioning(Partitioning::balanced())
.build();
producer.init().await?;
// Send some messages to the topic
let messages = vec![Message::from_str("Hello Iggy.rs")?];
producer.send(messages).await?;
// Create a consumer for the given stream and one of its topics
let mut consumer = client
.consumer_group("my_app", "dev01", "events")?
.auto_commit(AutoCommit::IntervalOrWhen(
IggyDuration::from_str("1s")?,
AutoCommitWhen::ConsumingAllMessages,
))
.create_consumer_group_if_not_exists()
.auto_join_consumer_group()
.polling_strategy(PollingStrategy::next())
.poll_interval(IggyDuration::from_str("1ms")?)
.batch_size(1000)
.build();
consumer.init().await?;
// Start consuming the messages
while let Some(message) = consumer.next().await {
// Handle the message
}
基准测试
要基准测试项目,首先以发布模式构建项目
cargo build --release
然后,使用所需选项运行基准测试应用程序
-
轮询(读取)基准测试
cargo r --bin iggy-bench -r -- -c -v send tcp
-
发送(写入)基准测试
cargo r --bin iggy-bench -r -- -c -v poll tcp
-
并行发送和轮询基准测试
cargo r --bin iggy-bench -r -- -c -v send-and-poll tcp
-
带有消费者组的轮询
cargo r --bin iggy-bench -r -- -c -v send --streams 1 --partitions 10 --disable-parallel-producers tcp
cargo r --bin iggy-bench -r -- -c -v consumer-group-poll tcp
这些基准测试将启动服务器,使用默认配置,创建流、主题和分区,然后发送或轮询消息。默认配置针对最佳性能进行了优化,因此您可能需要根据需要对其进行调整。如果您需要更多选项,请参阅iggy-bench
子命令的help
和examples
。例如,要为已启动的服务器运行基准测试,请提供附加参数--server-address 0.0.0.0:8090
。
根据硬件、传输协议(quic
、tcp
或 http
)以及有效载荷大小(messages-per-batch * message-size
),您可能期望写入时超过 3000 MB/s(例如,每秒 3M 的 1 KB 消息)吞吐量,读取时为 10000 MB/s。这些结果是在 Ryzen 9 7950X、64 GB RAM 和第四代 NVMe SSD 上实现的。
依赖项
~28–47MB
~1M SLoC