3. 本地存储技术选型:SQLite、RocksDB、LevelDB 的对比与选型策略

边缘计算里,存储选型是个绕不开的坎儿。

我见过不少团队,一上来就上 MySQL,结果边缘设备那点资源根本扛不住。也见过有人图省事全用文件存,最后查询慢到怀疑人生。

说白了,边缘存储没有银弹。SQLite、RocksDB、LevelDB 这三兄弟,各有各的脾气。今天我就把它们的底裤扒干净,告诉你什么场景该选谁。

核心结论先放这:

  • 需要 SQL 查询、数据结构简单、单机写入不频繁 → SQLite
  • 需要高吞吐写入、Key-Value 场景、数据量大 → RocksDB
  • 资源极度受限、纯嵌入式、写入量中等 → LevelDB

3.1 SQLite:边缘界的"瑞士军刀"

SQLite 是我个人用得最多的边缘存储方案。为什么?因为它太省心了。

你想想看,一个几百 KB 的库文件,就能跑完整的 SQL 引擎。不需要单独部署服务,不需要配置账号密码,你的程序直接调 API 就行。

适合的场景:

  • 设备配置信息管理(比如网关的规则表)
  • 日志结构化存储(需要按时间、级别查询)
  • 小规模数据的关系查询(几百 MB 以内)

但要注意它的短板:

  • 写入并发差。默认是串行写入,多线程同时写会锁库
  • 数据量超过 2GB 后性能下降明显
  • 不支持主从复制,数据冗余得自己想办法

我的经验: 在工业网关项目里,我用 SQLite 存设备配置和告警记录。单设备每天产生约 50MB 数据,保留 7 天,完全够用。但千万别拿它当时序数据库用——写入一上去就崩。

3.2 RocksDB:写入狂魔,LSM-Tree 的代言人

RocksDB 是 Facebook 从 LevelDB fork 出来的增强版。说白了,它就是为"写多读少"的场景量身定做的。

核心优势:

  • 写入吞吐极高,单机每秒几十万次写入很轻松
  • 支持列族(Column Family),可以逻辑上分表
  • 内置压缩、Bloom Filter、缓存等优化
  • 支持多线程 compaction,后台合并效率高

代价是什么?

  • 读性能不如 B+Tree,尤其是随机读
  • 内存占用偏高,默认配置下 1GB 数据可能吃掉 200MB 内存
  • 编译依赖多,交叉编译到 ARM 平台有点折腾

我曾经踩过的坑: 在一个视频分析边缘盒子里,我用 RocksDB 存特征向量和元数据。一开始没调 compaction 参数,结果后台合并线程把 CPU 吃满了,视频处理帧率直接掉到 10fps。后来把 max_background_compactions 从 4 降到 1,才稳住。

3.3 LevelDB:轻量级的老前辈

LevelDB 是 Google 出品的老牌 LSM-Tree 实现。RocksDB 就是基于它改的。

现在纯用 LevelDB 的场景不多了,但有些极端资源受限的设备还是得靠它。

它比 RocksDB 好在哪?

  • 代码量小,编译后体积只有几百 KB
  • 内存占用低,适合只有 32MB/64MB RAM 的设备
  • API 简单,学习成本几乎为零

缺点也很明显:

  • 单线程 compaction,写入量大了容易卡住
  • 没有列族,所有数据挤在一个命名空间
  • 不支持事务,没有 WAL 的原子性保证

我的建议: 除非你的设备 RAM 低于 64MB,否则直接上 RocksDB 吧。LevelDB 已经停止活跃开发了,社区支持也弱。我手头有个温湿度传感器节点,用 STM32 + LevelDB 存一周的数据,勉强能跑——但但凡内存多 32MB,我都会换成 RocksDB。

3.4 三者的核心对比

维度 SQLite RocksDB LevelDB
数据模型 关系型(SQL) Key-Value Key-Value
写入性能 中等(串行写入) 极高(LSM-Tree) 高(但单线程 compaction)
读取性能 高(B+Tree) 中等(需查多层) 中等
内存占用 低(几十 MB) 中高(200MB+) 极低(几十 MB)
事务支持 完整 ACID 单行原子性
并发写入 差(写锁) 好(多线程) 一般
编译难度 极低(Amalgamation) 中(依赖多)
典型场景 配置管理、小规模日志 时序数据、特征存储 极端资源受限设备

3.5 选型决策流程

我一般按这个思路来选,你可以参考一下:

  1. 需要 SQL 查询吗? 是 → SQLite。不是 → 下一步。
  2. 写入量超过 1000 ops/s? 是 → RocksDB。不是 → 下一步。
  3. 设备 RAM 小于 64MB? 是 → LevelDB。不是 → RocksDB。
  4. 需要事务和 ACID? 是 → SQLite。不是 → RocksDB。

一个真实案例: 去年我做智能电表边缘网关,ARM Cortex-A7,512MB RAM,每天产生约 200 万条用电记录。我选了 RocksDB,按小时分列族存储。查询时按时间范围扫列族,配合 Bloom Filter,单次查询平均 3ms。如果当时用 SQLite,写入就卡死了。

3.6 核心知识体系

下面这张图总结了本章的选型逻辑,你可以保存下来当参考:

边缘存储选型决策树 边缘设备存储需求 需要 SQL 查询? Key-Value 场景 SQLite 写入量 > 1000 ops/s? RAM < 64MB? RocksDB LevelDB RocksDB 注:实际选型还需考虑数据量、并发数、硬件平台等因素 决策节点 最终选型

3.7 避坑指南

最后分享几个我亲手踩过的坑,你遇到了能少走弯路:

  • 别在 SQLite 上做高并发写入。 我曾经用 8 个线程同时写同一个 SQLite 库,结果 5 分钟后数据库就报 "database is locked"。后来改成单线程队列写入,问题解决。
  • RocksDB 的 compaction 要调参。 默认配置是为服务器设计的,边缘设备 CPU 弱,一定要限制后台线程数。我一般设 max_background_jobs = 1 或 2。
  • LevelDB 的读放大问题。 数据量超过 1GB 后,一次读取可能要查 5-6 层 SST 文件。建议配合 Bloom Filter 使用,能减少 90% 的无用 IO。
  • 别忘了 WAL。 边缘设备经常意外断电。RocksDB 和 SQLite 默认都写 WAL,但 LevelDB 需要手动开启。不写 WAL,断电丢数据是必然的。

一句话总结: 能上 SQLite 就上 SQLite,它最省心。写入量大就上 RocksDB,但要舍得给它内存。只有资源实在不够了,才考虑 LevelDB。


公众号:蓝海资料掘金营,微信deep3321