TiDB是新兴的NEWSQL数据库,由国内的PINGCAP团队研发。
有关于TiDB的架构、部署和运维,官方有中文的文档,链接是:
https://github.com/pingcap/docs-cn
官方还有另外一份文档,讲的是TiDB和TiKV的设计思想和技术细节,个人很喜欢,但是用英文写的。这里提供该文档的翻译。
这个系列共三篇译文:
TiDB 官方设计文档翻译(一)
TiDB 官方设计文档翻译(二)
TiDB 官方设计文档翻译(三)
原文:
https://pingcap.github.io/blog/2016/10/17/how-we-build-tidb/
TiDB是一个分布式SQL数据库,灵感来自Google的F1和Spanner。TiDB汲取了传统RDBMS(译者注:关系型数据库)和NoSQL的优点。
在开始介绍之前,我们回到原点,问自己一个问题:为什么要重新做一个数据库。我们都知道,已经有很多成熟的数据库了,例如传统的关系型数据库和NoSQL。为什么我们不采用这些方案?
- 关系型数据库,例如MySQL,Oracle,PostgreSQL等,伸缩性很差。尽管我们可以有分片的解决方案,例如Youtube的vitness,MySQL代理,但是他们都不能满足分布式事务和跨节点的连接(join)。
- NoSQL,例如HBase,Mongo DB和Cassandra,伸缩性不错,但是不支持SQL和一致性事务。
- NewSQL,代表是Google Spanner和F1,和NoSQL系统一样具有良好的伸缩性,也保留了ACID事务。这才是我们所需要的。受到Google Spanner和F1的启发,我们决定做一款开源的NewSQL数据库。
我们要做的NewSQL数据库,必须有下面的功能:
- 首先,支持SQL。我们用SQL很多年了,而且许多应用都是基于SQL的,弃之可惜,代价也太大;
- 第二,必须有良好的伸缩性。只需要加入更多的机器,就可以增加性能或者实现负载均衡;
- 第三,支持ACID事务,这是传统的关系型数据库最大的优点之一。有了强一致性保证,开发者可以用更少的代码保证逻辑的正确;
- 最后,满足高可用,机器故障,甚至是整个数据中心宕机,都应该可以自动恢复。
总之,我们要做一个分布式、一致性、可伸缩的SQL数据库,取名为TiDB。
现在我们弄清了要做一个怎样的数据库,下一步是如何设计、开发和测试。
接下来一节中,首先介绍如何设计TiDB,包括设计原则、架构和决策。
在开始设计之前,必须清楚一些设计原则:
首要的设计原则是建立一个数据不会丢失的数据库。 为了确保数据的安全,我们发现多个副本是不够的,我们仍然需要在SQL层和key-value层维护Binlog(二进制日志)。 当然,我们必须确保有一个备份,以防整个集群崩溃。
第二个设计原则是关于可用性。 经过多年在不同的解决方案之间的权衡,我们完全意识到用户的痛点。 因此,当我们设计一个数据库时,我们将使它易于使用,并且应该没有令人头疼的分片键,没有分区,没有明确的手工本地索引或全局索引,并使让系统伸缩对用户完全透明。
这个数据库还需要跨平台。 数据库可以在本地设备上运行。 下图展示了TiDB运行在有20个节点的树莓派集群。
它还可以支持流行的容器,如Docker。 我们正在与Kubernetes合作。 当然,它也可以在任何云平台上运行,无论是公共的,私有的还是融合的。
下一个设计原则是关于社区和软件生态。 我们想站在巨人的肩膀上,而不是创造出全新的令人陌生的产品。 TiDB支持MySQL协议,与大多数MySQL驱动程序(ODBC,JDBC)、SQL语法、MySQL客户端、ORM、下列MySQL管理和bench工具兼容。
- etcd——etcd是一个伟大的项目。 在我们的键值存储TiKV中(后面会详细介绍),我们一直与etcd团队密切合作。 我们共享Raft实现,并且互相进行Raft模块代码审查;
- RocksDB——RocksDB也是一个伟大的项目。 成熟,快速,可调谐,并广泛应用于大规模的生产环境,尤其在Facebook。 TiKV使用RocksDB作为本地存储。 当我们在系统中测试时,发现了RocksDB的一些bug。 RocksDB团队后来很快地修复了;
- Namazu——几个月前,我们需要一个工具来模拟速度慢而且不稳定的磁盘,团队成员发现了Namazu。 但是那时候,Namazu不支持hooking fsync。 当团队成员将此请求提交给Namazu的团队时,他们立即回复并在短短几个小时内实现该功能,他们也非常愿意实现其他功能。 我们对他们的反馈速度和效率印象深刻;
- Rust社区——Rust社区是惊人的。 除了使用Rust的良好开发经验之外,我们还在Rust中构建了Prometheus驱动程序以收集指标。我们很高兴成为这个大家庭的一部分。 非常感谢Rust团队,gRPC,Prometheus和Grafana。
- spark连接器。我们在TiDB中使用Spark连接器。 TiDB非常适合小型或中型查询,Spark更适合具有大量数据的复杂查询。 我们相信我们也可以从Spark社区学到很多,当然我们希望尽可能多地贡献。
因此,总体来说,我们希望成为大型开源社区的一员,并愿意参与,贡献和合作,一起构建伟大的开源产品。
下图显示了数据库的逻辑架构。
正如我前面提到的设计原则,我们采用松耦合方法。 从图中我们可以看出TiDB是高度分层的。 我们有TiDB作为MySQL服务器,TiKV作为分布式Key-Value层。 TiDB内部,分为MySQL Server层和SQL层。 在TiKV内部,分为事务,MVCC,Raft和本地键值存储(RocksDB)。
对于TiKV,我们使用Raft协议来保证数据一致性和水平伸缩性。 Raft是一个一致性算法,在容错和性能可以媲美Paxos。 我们从etcd移植了广泛使用的实现方法,容易测试并且高度稳定。 稍后将介绍技术细节。
从架构中,你也能看到,并没有分布式文件系统。我们使用RocksDB作为本地存储。
在接下来的几节中,我将讨论与Spanner和F1相比,使用替代技术的设计决策,以及这些替代方案的利弊。
如果阅读过Spanner论文,你可能知道Spanner有TrueTime API,它使用原子钟和GPS接收器来保持不同数据中心之间的时间一致。
我们选择的第一种替代技术是用TimeStamp Allocator替换TrueTime API。 毫无疑问,实时性在分布式系统中至关重要。 但是我们能得到实时吗? 时钟漂移怎么办?
可悲的是,即使我们使用GPS或原子钟,因为时钟漂移,也不能得到完全准确的时间,
在TiDB中,我们没有使用原子钟和GPS时钟。 我们使用Percolator(2006年Google发布的一篇文章)中引入的Timestamp Allocator。
使用Timestamp Allocator的优点是易于实现,并且不依赖于任何硬件。 缺点在于,如果存在多个数据中心,特别是如果这些数据中心跨地区分布,延迟会很高。
Spanner使用Colossus文件系统作为其分布式文件系统,Colossus是Google文件系统(GFS)的继承者。 但是在TiKV中,我们不依赖于任何分布式文件系统。 我们使用RocksDB。 RocksDB是一个可嵌入的快速持久化键值存储。 RocksDB的最大优点是其针对服务器工作负载的卓越性能。 很容易调整读、写和放大空间。 非常简单、快速和容易调整。 但是,与Kubernetes协同工作并不容易。
下一个选择是使用Raft一致性算法代替的Paxos。Raft的主要特点是:强有力的领导者,领导者选举和成员的变化。 我们从etcd移植了Raft实现方法。 优点是易于理解和实现,广泛使用并且便于测试。 至于缺点,目前还没发现。
至于编程语言,TiDB使用Go语言,TiKV使用Rust。 我们选择了Go,因为它对快速开发和并发非常有利,而Rust可以实现高质量和性能保障。 至于缺点,没有那么多的第三方库。
上文介绍了设计TiDB的过程中,使用替代技术的原则、架构和设计决策。 下一步是开发TiDB。
说明
如有转载,请注明出处:
http://blog.csdn.net/antony9118/article/details/60467256