- 团队名称: 42
- 作者: 戴赛, 李江南, 刘伊阳
- 项目进展:
- 方案调研 (done)
- TiDB 支持 TTL (doing)
- Kine 接入 TiDB (done)
- 仓库地址:
作为一款高可用强一致性的 KV 数据库, ETCD 因其有着轻量易扩展的特点, 现在已被广泛的使用. 但是 ETCD 限制了其最大存储空间不可超过 8GB, 这极大影响了业务对 ETCD 的使用. 在本次 Hackathon 中, 我们将使用 TiDB 作为 ETCD 的存储组件, 让 ETCD 能够突破 8GB 存储上限的同时, 保留其高可用, 易扩展的特性, 让业务更加无痛地使用 ETCD.
随着 CoreOS 和 Kubernetes 等项目在开源社区日益火热, 它们项目中都用到的 ETCD 组件作为一个高可用强一致性的数据库, 渐渐为开发人员所关注. ETCD 不仅可以用于存储元数据, 还可以作为服务发现与分布式锁. 但是 ETCD 的存储空间上限仅 8GB, 作为一款数据库产品来说, 该限制过于不合理了. 特比是当数据版本过多或出现数据空洞时, 会很容易的到达该上限. 虽然可以通过 Compact 的方式来压缩已用空间, 但这会影响 ETCD 性能并损失数据的历史版本. 而 TiDB 理论上存储空间是无限扩展的, 如果能用 TiDB 替代 ETCD 的存储层, 那么我们就收获了一个存储空间可无限扩展的 ETCD, 更无所谓 8GB 的限制了.
项目整体分为两部分工作:
- Kine 适配 TiDB
- TiDB 支持 TTL
如果单纯地将 ETCD 自带的存储引擎替换为 TiDB 是不合理的:
- ETCD 本身是多副本保证高可用, 而 TiDB 每份数据也是冗余的, 若将 TiDB 作为存储引擎的则会导致数据放大, 显著的增加存储成本.
- TiDB 与 ETCD 耦合过重, 维护成本过高.
因此我们这里考虑引入一个接入层, 在实现对 ETCD 存储进行扩展的同时, 保留其高可用的同时, 实现松耦合的效果.
架构上, 项目整体分为两层:
- 接入层:
- 负责接收 ETCD 协议的请求, 并将其进行一系列处理后将请求发送到存储层, 实现读写数据等操作.
- 由多个 Kine 服务构成, 每个 Kine 服务为无状态服务, 使得服务比原生 ETCD 有着更好的易迁移和扩展性.
- Kine 服务区分主从关系, 为了避免写冲突, 所有的写操作只能由主节点来完成, 从节点收到写操作后要将请求发送到主节点上.
- 存储层:
- 负责实际的数据存储.
- 由 TiDB 服务构成存储层, 依赖 TiDB 的可靠性和扩展性, 保证数据的持久性, 突破存储空间的限制.
但是 Kine 还是有部分缺陷, Kine 并未实现 ETCD 中的 Lease(租约) 接口, 这使得其无法良好的兼容 ETCD. 这里我们参考了 MongoDB 的 TTL 索引的方式, 在 TiDB 中实现 TTL 索引的功能.
通过对某个 DATE 列增加 TTL 索引, 当某行数据中的该 DATE 列索引中的时间早于当前时间时, 该索引会被删除.
ALTER TABLE table_name ADD TTL_INDEX index_name (date_column_list)
实现上, 删除策略分为主动删除和惰性删除两部分:
- 主动删除: 为每张添加了 TTL 索引的表设置一个后台任务, 定时的发现过期数据并进行删除.
- 惰性删除: 当添加了 TTL 索引的表被访问到后, 检查一遍是否与过期数据, 若存在则删除该部分数据再进行后续的请求.
基于 TTL 索引的功能, 我们可以实现 ETCD 的 Lease 接口. 从而最终使得该项目完全兼容 ETCD.
同时 TTL 索引功能丰富了 TiDB 的能力, 使得 TiDB 在日志数据, 事件数据, session 会话场景下有更好的泛用性.