6个版本
新版本 0.0.6 | 2024年8月16日 |
---|---|
0.0.5 | 2024年8月7日 |
0.0.1 | 2024年7月18日 |
#236 在 数据库接口
619 每月下载量
645KB
12K SLoC
Hiqlite
Hiqlite是一个可嵌入的SQLite数据库,它可以形成一个Raft集群以提供强一致性、高可用性(这正是Hiqlite的来源),复制、自动领导者故障转移和自我修复功能。
为什么
为什么还需要另一个SQLite复制解决方案?已经有其他项目可以做到这一点。问题是它们都没有做到完美。它们要么需要一个额外独立运行的进程来进行异步复制,要么需要特殊的文件系统,或者作为服务器运行。
我认为将SQLite作为服务器运行并不是一个好的解决方案。是的,它非常节省资源,当资源非常有限时,这可能是一个好的解决方案,但您失去的是SQLite最大的优势:数据本地化,这使得读取非常快,没有网络延迟。
Hiqlite建立在rusqlite
之上,并为其提供了一个异步包装器,使其易于与tokio
一起使用。对于Raft逻辑,它在openraft
之上构建,同时提供自己的存储和网络实现。
目标
Rust是一种如此高效的编程语言,您通常只需要一个进程就能实现您需要的任何功能,对于大多数应用来说至少是这样。一个嵌入式SQLite使整个过程非常方便。您可以获得非常快的本地读取,同时,它还带来了好处:您不必管理额外的数据库,您需要设置、配置,更重要的是维护。当构建新版本时,嵌入式SQLite几乎可以免费提供数据库更新。
当正确配置时,SQLite提供了非常好的性能,可以处理当今的大多数工作负载。在我最初的基准测试中,我发现这个项目有意义,我在一个廉价的消费级M2 SSD上达到了24.5k单条插入/s。这些测试是在本地主机上进行的,有3个不同的进程,但仍然有它们之间的真实网络。在另一台装有较老SATA SSD的机器上,它达到了16.5k插入/s。
最终的目标是,您可以在享受嵌入式SQLite的简单性和所有优势的同时,仍然能够以高可用性运行您的应用程序(这对于我来说几乎是强制性的),并在出现任何错误或问题时自动故障转移。
哪些功能正在运行
- 完整的Raft集群设置
- Raft 所预期做的所有事情(归功于 openraft)
- Raft 日志的持久化存储(使用 rocksdb)和 SQLite 状态机
- “魔法”自动配置,无需手动初始化或管理 Raft
- 自愈 - 每个节点都可以自动从
- 丢失的状态机缓存的 WAL 缓冲区
- 丢失的日志存储缓存的 WAL 缓冲区
- 状态机数据库(SQLite)的完全丢失
- 日志存储(rocksdb)的完全丢失
- 整个卷的完全丢失
- 自动数据库迁移
- 完全认证的网络安全
- 可选的 TLS 遍布所有地方,以实现零信任哲学
- 加密备份到 s3、cron 作业或手动(使用 s3-simple + cryptr)
- 从远程备份恢复(带有日志索引回滚)
- 强一致性、复制的
execute
查询- 在领导者节点上,客户端甚至不会麻烦使用网络
- 在非领导者节点上,它将自动切换到网络连接,以便请求被转发并在当前 Raft 领导者上发起
- 通过 Raft 返回语句的强一致性、复制的
execute
查询- 您可以选择获取自定义
RowOwned
结构的原始句柄 - 或将
RETURNING
语句映射到现有结构
- 您可以选择获取自定义
- 在领导者上的一致读取/选择查询
- 事务执行
- 简单的
String
批处理执行 query_as()
用于本地读取,自动映射到实现serde::Deserialize
的struct
。这最终将包含在一个尚未实现的serde
功能中。query_map()
用于本地读取的structs
,它们实现impl<'r> From<hiqlite::Row<'r>>
,这是更快速的方法,但需要更多手动工作- 除了 SQLite 之外 - 具有可选独立 TTL 的多个内存中的 K/V 缓存
- 监听/通知通过 Raft 发送实时消息
dlock
功能提供分布式锁的访问- 具有
server
功能的独立二进制文件,可以作为单个节点、集群或现有集群的代理运行 - 集成简单的仪表板 UI,用于在生产中调试数据库 - 目前相当基础,但能完成任务
在 v0.1.0 之前的 TODO
- 真实世界的稳定性测试和修复
- 适当的文档
- 更多的示例
依赖关系
~31–71MB
~1M SLoC