如果你平时写 Redis,应该很熟悉这样的场景:临时查一个 key、看一段 JSON、确认某个 Hash 字段、检查慢查询、扫一下内存占用,最后往往会在命令行、Web 控制台和脚本之间来回切换。
这也是我做 Rust Redis Desktop 的原因:希望有一个足够轻量、跨平台、工程化程度高的 Redis 桌面管理工具,同时也验证一下用 Rust 写桌面软件到底能做到什么程度。
如果你对 Rust 桌面开发、Redis 工具或者开发者效率工具感兴趣,欢迎到 GitHub 点一个 Star。Star 是开源项目持续迭代最直接的动力。
先说结论:Rust 可以认真写桌面软件
很多人对 Rust 的第一印象还是系统编程、CLI、后端服务、嵌入式,桌面软件往往会先想到 Electron、Qt、Flutter 或 Tauri。但 Rust 这几年在桌面端的生态已经越来越完整,尤其适合这类“UI 不一定极复杂,但业务逻辑、IO、性能和稳定性都很重要”的工具型软件。
Rust Redis Desktop 当前采用的是 Rust + Dioxus desktop + Freya 的技术路线,核心依赖包括:
dioxus:组件化 UI 和桌面窗口入口。freya:Rust 生态中的桌面 UI 方案之一。tokio:异步运行时,用于 Redis 请求、更新检查、下载等 IO 场景。redis:Redis 客户端,启用了异步、Cluster、连接管理和 TLS 能力。serde/serde_json/toml:配置、数据结构和格式化能力。reqwest:自动更新和远程清单请求。ssh2:SSH Tunnel 支持。aes/cbc:本地连接密码加密保存。
和很多把业务逻辑主要放在前端页面里的方案不同,这个项目的大部分产品能力都在 Rust 侧实现:连接管理、Redis 命令封装、数据结构解析、序列化识别、本地配置、自动更新、跨平台打包等。UI 只是把这些能力组织成一个桌面应用。
这个软件解决什么问题
Rust Redis Desktop 是一个桌面 Redis 管理器,目标不是简单替代 redis-cli,而是把 Redis 日常使用中高频、繁琐、容易出错的操作做成可视化工具。
当前已经支持的能力包括:
- 多连接管理:支持直连、Cluster、Sentinel、SSL/TLS、SSH Tunnel。
- 本地配置保存:连接、设置、命令历史都会落到平台配置目录。
- 凭据加密:保存连接时不会把密码直接明文写入
config.json。 - Key 浏览:基于
SCAN增量扫描,支持搜索、分组、树形展示和虚拟列表。 - 数据编辑:支持 String、Hash、List、Set、ZSet、Stream、Bitmap 等常见类型。
- JSON 与二进制查看:JSON 格式化、图片预览、Hex/Base64 等格式展示。
- 序列化识别:支持 Java Serialization、Protobuf、MessagePack、CBOR、BSON、PHP、Pickle、Kryo/FST 等格式。
- 运维工具:命令终端、Lua 脚本、Pub/Sub、Slowlog、Client 列表、Server Info、内存分析。
- 用户体验:多主题、跟随系统深浅色、中英文界面、系统托盘、自动更新。
- 跨平台发布:macOS
.dmg、Windows.exe、Linux.AppImage和.deb。
对很多后端开发来说,Redis 里存的不只是字符串,而是各种业务对象、序列化二进制、缓存结构和运行态数据。普通客户端通常能看 key,却很难把值“看懂”。这个项目的一个核心方向,就是让 Redis 里的复杂值更容易被理解和编辑。
项目架构拆解
从代码结构看,项目不是把所有逻辑塞到 UI 组件里,而是按领域拆成了几个清晰模块:
src/
main.rs # 桌面窗口、菜单、托盘、更新检查入口
connection/ # Redis 连接、连接池、SSH Tunnel、错误类型
redis/ # Redis 命令封装、Key 树、搜索、命令文档
ui/ # Dioxus/Freya UI 组件
config/ # 本地配置读写
crypto/ # 凭据加密
serialization/ # 多语言序列化格式识别和解析
formatter/ # JSON、压缩、编码等格式化器
protobuf_schema/ # Protobuf schema 导入和解析
theme/ # 主题系统
i18n/ # 中英文国际化
updater/ # 自动更新、下载、平台安装器
1. 启动层:桌面窗口、菜单和运行时检查
入口在 src/main.rs。应用启动时会初始化日志和错误报告,然后进入 run_app():
dioxus::LaunchBuilder::new()
.with_cfg(launch_config)
.launch(App);
这一层主要处理桌面应用需要面对的“平台问题”:
- macOS 下隐藏标题栏、使用透明 titlebar。
- Windows 下检查 WebView2 Runtime,并准备可写的数据目录。
- 初始化系统菜单,包括设置和检查更新入口。
- 非 Linux 平台初始化系统托盘。
- 根据用户设置选择窗口主题。
桌面开发和 Web 开发很大的区别在这里:你不能只关心页面,还要关心窗口、菜单、图标、托盘、安装包、运行时依赖和操作系统差异。
2. 连接层:把 Redis 复杂性封装起来
连接配置定义在 connection/config.rs。一个连接不仅包含 host、port、db、password,还包含连接模式、SSL、SSH、Cluster、Sentinel、只读模式、心跳间隔和排序信息。
真正执行连接的是 ConnectionPool:
- 直连模式使用
redis::Client和 asyncConnectionManager。 - Cluster 模式使用
ClusterClient和异步 Cluster 连接。 - SSH Tunnel 会先在本地绑定临时端口,再通过 SSH 转发到远端 Redis。
- SSL 开启后使用
rediss://scheme。 ensure_connection()会先PING,失败后尝试重连。- 只读连接会在执行写命令前拦截,例如
SET、DEL、HSET、XADD、FLUSHDB等。
这类封装对桌面软件非常重要。UI 层不应该到处拼 Redis URL,也不应该理解 Cluster 和 SSH Tunnel 的细节。UI 只关心“当前连接能否执行某个操作”,底层细节都交给连接模块。
3. Key 浏览:用 SCAN、树和虚拟列表处理大库
Redis 客户端最容易踩坑的功能就是 key 列表。直接 KEYS * 对生产库很危险,所以项目使用 SCAN 分批拉取:
SCAN cursor MATCH pattern COUNT 500
在 ui/key_browser.rs 中,扫描过程支持取消、进度展示、失败重连和二次重试。拿到 key 后,再由 TreeBuilder 按 : 分隔符构建树形结构。
项目还做了两个重要优化:
- Key 类型懒加载:可见范围内的 key 再批量调用
TYPE,避免一次性查询所有 key 类型。 - 虚拟滚动:大 keyspace 下只渲染可见区域,避免 UI 卡死。
这也是 Rust 写桌面工具的一个典型优势:业务逻辑可以写得很扎实,状态和并发边界清晰,面对大数据量时更容易做细粒度优化。
4. Value Viewer:不只是展示字符串
ui/value_viewer/ 是这个项目最核心的模块之一。它会根据 Redis key type 切换不同的面板:
- String:文本、二进制、JSON、图片、序列化数据展示。
- Hash:字段搜索、编辑、新增和删除。
- List:分页加载、元素编辑。
- Set / ZSet:成员查看、搜索、编辑、score 管理。
- Stream:消息和 Consumer Group 相关能力。
- Bitmap:位图查看。
这里不只是简单 GET 一下再显示。对于大型 Hash、Set、ZSet,项目会使用游标和分页,避免一次加载过多数据。对于 String 类型,还会尝试判断它是不是 JSON、图片、Java 序列化、Protobuf、MessagePack 等格式。
这也是 Rust Redis Desktop 和普通 Redis GUI 拉开差异的地方:它更关注“值的语义”。很多缓存问题不是找不到 key,而是找到了 key 也看不懂里面的内容。
5. 序列化解析:为真实业务数据服务
后端系统里 Redis 经常存储各种语言的序列化结果。项目在 serialization/ 下专门做了一层格式识别:
pub enum SerializationFormat {
Unknown,
Java,
Php,
MsgPack,
Pickle,
Kryo,
Fst,
Protobuf,
Bson,
Cbor,
}
比如 Java Serialization 会识别 0xAC 0xED 魔数,MessagePack、CBOR、BSON、Pickle 等也有对应的解析逻辑。Protobuf 还支持导入 .proto schema 后按字段解析。
这类能力很适合 Rust:二进制处理、类型建模、错误处理和性能都比较可控。相比在前端用 JavaScript 硬解析,Rust 侧更适合承担这些偏底层的数据处理工作。
6. 本地配置和安全边界
配置由 ConfigStorage 管理,默认写入各平台配置目录:
Linux: ~/.config/rust-redis-desktop/config.json
macOS: ~/Library/Application Support/rust-redis-desktop/config.json
Windows: %AppData%\rust-redis-desktop\config.json
配置里保存连接、应用设置和命令历史。保存连接前,密码字段会经过 AES-CBC 加密,并保存为 ciphertext + iv 的结构。
这里需要客观看待:当前实现已经避免了明文存储,但桌面端最佳实践仍然是进一步接入系统级 Keychain、Windows Credential Manager 或 Linux Secret Service。对开源桌面工具来说,先明确安全边界,再持续迭代,比简单声称“绝对安全”更可靠。
7. 更新和发布:桌面软件不是 cargo build 就结束
真正把 Rust 程序做成桌面产品,发布链路非常关键。这个项目在 .github/workflows/release.yml 中做了完整的跨平台构建:
- macOS:构建
.app,打包.dmg,集成 Sparkle,支持签名和 notarize。 - Windows:构建 release binary,使用 NSIS 打包安装器,并处理 WebView2 Runtime。
- Linux:构建 AppImage 和
.deb。 - GitHub Pages:生成
appcast.xml和update.json,供自动更新检查使用。
应用内的 updater/ 模块会从 https://yelog.github.io/rust-redis-desktop/update.json 拉取更新清单,判断当前版本和平台,再下载对应安装包。
这部分经常被桌面项目低估。用户真正使用的软件,不只是代码仓库里的二进制,而是安装、升级、回滚、报错都要能闭环的产品。
用 Rust 写桌面软件的几个实践建议
结合这个项目,我总结了几条比较实用的经验。
第一,UI 组件只负责表达状态,不负责承载业务复杂度。Redis 连接、命令执行、序列化解析、配置读写都应该放到独立模块中。这样 UI 换技术栈时,核心能力还能复用。
第二,所有 IO 都要异步化。Redis 请求、扫描 key、下载更新、读取大值,都不应该阻塞 UI。项目里大量使用 Dioxus 的 spawn(async move { ... }) 配合 tokio 完成异步任务。
第三,大数据量场景从第一天就要考虑增量策略。Redis keyspace 可能是几十万甚至上百万级,必须使用 SCAN、分页、虚拟列表、懒加载和取消机制。
第四,错误类型要工程化。项目使用 thiserror 定义 AppError、StartupError、ConfigError、ConnectionError 等错误类型,让启动错误、连接错误、配置错误和更新错误有清晰边界。
第五,桌面软件要尊重平台。窗口样式、托盘、菜单、WebView2、macOS 签名、Linux 依赖、Windows 安装器,都是产品体验的一部分。
如何运行
如果你想本地体验,可以直接从源码运行:
git clone https://github.com/yelog/rust-redis-desktop.git
cd rust-redis-desktop
cargo run
也可以从 Release 页面下载预构建安装包:
当前发布产物包括:
- macOS
.dmg - Windows
.exe - Linux
.AppImage - Linux
.deb
适合谁看这个项目
如果你正在考虑用 Rust 写桌面软件,这个项目可以作为一个真实案例参考。它不是一个 demo,而是包含了连接管理、异步任务、本地配置、主题、国际化、更新、打包发布等桌面软件常见问题。
如果你是 Redis 用户,它也可以作为日常开发和排查问题的工具。尤其是当你的 Redis 中有大量 JSON、二进制、序列化对象、Stream 或复杂结构时,可视化工具能节省很多排查时间。
如果你想参与开源,也欢迎提 Issue 或 PR。这个项目还有很多可以继续完善的地方,比如更深的文档、更细致的交互打磨、更强的安全凭据存储、更丰富的数据格式识别等。
最后
Rust 写桌面软件并不是“炫技”。对于 Redis 管理器这类工具来说,Rust 的类型系统、性能、错误处理、异步生态和跨平台能力,刚好能解决很多实际问题。
Rust Redis Desktop 还在持续迭代中。如果你觉得这个项目有价值,欢迎访问 GitHub:
顺手点一个 Star,也欢迎把你的使用反馈、Bug 或功能建议提交到 Issue。你的 Star 和反馈,会直接影响这个项目后续能走多远。