五个不同的数据存储,每个都回答了一个问题,而其他数据存储的回答则不尽相同:用于事务性业务数据的分布式 SQL、用于高写远程测量的宽列、用于瞬态的内存存储、用于文件的对象存储以及用于语义搜索的矢量数据库。
| 措施 | 价值 | 资料来源 | 已计量 |
|---|---|---|---|
| 生产环境中的独立数据存储 | 5 (YugabyteDB, ScyllaDB, Redis/Valkey, MinIO, Qdrant) | kubectl get statefulsets,deployments --all-namespaces | |
| 分布式SQL拓扑 | yb-master and yb-tserver as separate stateful sets | kubectl get statefulsets -n kamo | |
| 版本控制下的SQL迁移文件 | 90 | find . -name '*.sql' across all service repositories | |
| 完成生产数据库引擎迁移 | 1 (CockroachDB to YugabyteDB, live data) | service configuration history; port 26257 retired in favour of 5433 |
它教会了我们什么建筑
对于数据去哪里,默认的答案是最后使用的项目,这就是企业最终如何对接收客户订单的数据库运行分析聚合,或在表行中保留 30GB 的上传文件。 我们根据工作负载选择每个商店,并在出错时进行迁移 — — 平台之前在不同的分布式 SQL 引擎上运行,然后离开了它,这对于生产数据来说确实是件困难的事情,而作为经验,这比任何数量的架构讨论都更有价值。
分布式 SQL 并不是单节点数据库的直接替代品,它的差异是非常明显的。 即使在读提交模式下,事务在其整个生命周期中都会看到一个快照,因此,在一个事务中,行的第二次读取不会观察到在此期间提交的另一个写入事务 — — 在单节点上正确的代码在此处是悄悄地错误的。 读写冲突会以从未写入任何内容的事务上的可重试错误的形式出现。
对象存储会运行每个上传的文件,并按内容进行去重,这有其自身的教训:上传失败可能会留下一行,以后的重试会对其进行去重,从而产生系统认为存在但无法服务的文件。 我们在生产环境中发现了这一点,现在我们在构建的任何去重系统中都会检查这一点。
建于
- YugabyteDB
- ScyllaDB
- Redis
- Valkey
- MinIO
- Qdrant
- PostgreSQL wire protocol
- Hibernate
