Vitess是用于扩展MySQL的数据库解决方案, 他可以有效的运行在基于专用硬件设备的公有云或者私有云上;
通过NoSQL数据库的可扩展性它结合并扩展了许多重要的MySQL功能。自2011年起,Vitess一直为所有YouTube数据库流量提供服务。
Kubernetes是一个开源的容器管理系统,Vitess可以作为Kubernetes可感知的云本地分布式数据库运行。
Kubernetes处理集群中的节点调度计划,管理节点上的工作负载,方便管理构成应用的容器组。他提供了一个类似于Vitess在YouTube运行的
开源环境。
以下部分将Vitess与两个常见的替代方案(普通MySQL和NoSQL)进行比较。
Vitess在以下几个方面对普通的MySQL进行改进:
普通Mysql | Vitess |
---|---|
每个MySQL连接的内存开销在256KB到近3MB之间,具体的取决于你使用的MySQL版本;随着用户数量的增长,必须要添加RAM以支持其他连接,但是增加RAM并不能带来查询速度的提高。另外,获取更多连接的同时会增加CPU的成本。 | Vitess基于gRPC协议创建的都是轻量级的连接,Vitess连接池功能使用Go的并发支持将这些轻量级连接映射到一个小型的MySQL连接池;因此,Vitess可以轻松处理数千个连接。 |
写的不好的查询(例如:sql中没有增加limit)会给数据库的所有用户带来负面的影响 | Vitess采用SQL解析器,它使用一组可配置的规则来重写可能损害数据库性能的查询。 |
分片是对数据进行分区以提高可伸缩性和性能的过程。MySQL缺少本机分片支持,需要在应用程序中编写分片代码和嵌入分片逻辑 | Vitess使用基于范围的分片;它支持水平和垂直重新分区,只需几秒钟的只读停机即可完成大多数数据转换。Vitess甚至可以适应您已有的自定义分片计划。 |
基于复制协议的MySQL集群包含一个主库和多个从库, 如果主库宕机,其中一个从库会被提升为主库继续提供服务; 这就需要管理数据库的生命周期同时告知应用当前系统的状态。 | Vitess有助于管理数据库方案的生命周期。它支持并自动处理各种场景,包括主故障转移和数据备份。 |
MySQL集群可以具有针对不同工作负载的自定义数据库配置,例如用于写入的主库、为web客户端提供的快速只读从库、为批处理作业提供的较慢的只读副本等等。如果数据库具有水平分片,则需要为每个分片重复设置,应用程序需要编写逻辑来确认如何找到正确的数据库。 | Vitess使用支持数据一致性的存储系统来存储拓扑结构,例如etcd或ZooKeeper。这意味着集群视图始终是最新的,并且对于不同的客户端都是一致的;Vitess还提供了一个代理,可以将查询有效地路由到最合适的MySQL实例。 |
如果你考虑一个NoSQL解决方案主要是出于对MySQL的可扩展性的担忧,那么Vitess可能是您的应用程序最佳的选择。虽然NoSQL为非结构化数据提供了极大的支持,但Vitess仍然提供了NoSQL数据存储中不可用的几个优点:
NoSQL | Vitess |
---|---|
NoSQL数据库不定义数据库表之间的关系,并且只支持SQL语言的一个子集。 | Vitess不是一个简单的键值存储,它支持复杂的查询语义,如where子句,JOINS,聚合函数等。 |
NoSQL数据存储不支持事务。 | Vitess支持单分片中的事务。我们还在探索使用2PC支持跨分片事务的可行性。 |
NoSQL解决方案具有定制API,从而导致定制架构,应用程序和工具。 | Vitess对MySQL增加很少的变动(一个大多数人已经习惯于使用的数据库)。 |
与MySQL相比,NoSQL解决方案对数据库索引提供有限的支持。 | Vitess允许您使用所有MySQL的索引功能来优化查询性能。 |
- 性能
- 连接池 - 扩展前端连接,同时优化MySQL性能
- 查询去重 - 对于正在运行的查询在执行期间接收的任何相同请求都会复用查询结果
- 事务管理 - 限制并发事务的数量并管理截止时间以优化整体吞吐量
- 保护
- 查询重写和预防 - 添加限制并避免任何非确定性更新
- 查询黑名单 - 自定义规则防止可能有问题的查询命中数据库
- 查询终止 - 终止需要太长的时间才能返回数据的查询
- 表访问控制 - 指定连接用户对表的访问控制列表
- 监控
- 性能分析 - 工具允许您监视,诊断和分析数据库性能
- 流式查询 - 使用传入查询列表来提供OLAP工作负载
- 流式更新 - A server streams the list of rows changing in the database, which can be used as a mechanism to propagate changes to other data stores.
- 拓扑管理工具
- 主库管理工具(处理主切换)
- 基于Web GUI管理工具
- 设计用于在多个数据中心/地区提供服务
- 分片
- 几乎无缝的动态重新分片
- 垂直和水平分片支持
- 内置基于范围的分片方式和应用程序自定义的分片方式的支持。
Vitess平台包括多个服务器进程、命令行工具、基于web的工具、元数据的一致性存储支持。
根据应用程序的当前状态, 你可以通过多个不同的处理流程来达到一个完整的Vitess实现。例如:如果你从头开始构建一个服务,你使用Vitess的第一步就是定义数据库的拓扑结构。如果您需要扩展现有的数据库,你的第一步可能就是从启动一个连接代理开始。
Vitess工具和服务器主要是帮助您是从一个完整的数据库实现开始还是基于最小实现,然后随着时间的推移逐步扩展。对于最小实现,vttablet的特性连接池和查询重写可以帮助我们在当前已经存在的机器上获取更大的性能;Vitess自动化工具对于大型项目可以提供更好的支持。
下图是Vitess的结构图:
拓扑服务是元数据存储服务包含有关运行服务器的信息,数据库分片信息和数据复制拓扑图;拓扑服务是基于一致性数据存储引擎。 您可以使用vtctl(命令行)和vtctld(web)来查看系统的拓扑结构数据。
在Kubernetes中,元数据存储是etcd, 同时在Vitess源代码也附带Apache ZooKeeper支持。
vtgate是一个轻量级的代理服务器,他可以把数据路由到正确的vttablet服务并且将合并的结果返回给客户端;他是应用程序发送查询的服务器。所以,客户端可以非常简单,因为它只需要能够找到一个vtgate实例即可。
对于路由查询,vtgate考虑分片方案,所需的延迟以及tablets和底层数据库的可用性。
vttablet是一个位于MySQL数据库前面的代理服务器;Vitess实现是每个MySQL实例都对应有一个vttablet进程。
vttablet执行任务的时候尝试最大化吞吐量同时对于有害查询的任务会保护MySQL;其功能包括连接池、查询重写、查询去重。另外,可以通过vtctl对vttablet发起管理任务,它提供用于过滤复制和数据导出的流服务。
轻量级的Vitess实现使用vttablet作为单个MySQL数据库查询的智能连接代理。通过在MySQL数据库前运行vttablet并且更改您的应用程序以使用Vitess客户端,而不是您的MySQL驱动程序;vttablet的连接池、查询重写、查询去重这些特性会给你的应用带来很多好处。
vtctl是一个用来管理Vitess集群的命令行工具;它允许人或应用程序轻松地与Vitess实现交互。使用vtctl你可以识别数据库的主从关系,创建表,启动故障切换,执行分片(和重新分片)操作等。vtctl执行操作时它会根据需要更新锁服务器;其他Vitess服务器会观察这些更改并相应做出反应。例如:如果使用vtctl故障切换到新的主数据库,vtgate会获取到更改并将后续的写操作指向新的主节点。
vtctld是一个HTTP服务器,它允许您浏览存储在锁服务器中的信息,它对于故障排除或者获取服务器更高级概述及其当前状态的非常有用。
vtworker托管长时间运行的进程,它支持插件架构并且提供库,以便您可以轻松地选择使用tablets。插件适用于以下类型的工作:
- resharding differ - resharding后校验数据完整性
- vertical split differ - 垂直拆分后校验数据完整性 vtworker还允许您轻松添加其他验证过程,您可以进行片内完整性检查,以验证外键式关系或交叉分片完整性检查。例如:一个keyspace中的索引表在另一个keyspace中的参考数据。
Vitess还包括以下工具:
- mysqlctl: 管理MySQL实例
- zk: ZooKeeper命令行客户端和浏览器
- zkctl: 管理ZooKeeper实例
自2011年以来,Vitess一直是YouTube基础设施的基本组成部分,本节简要总结了导致Vitess创建的事件序列:
- YouTube的MySQL数据库达到了一个点,当高峰流量将很快超过数据库的服务容量,为了暂时缓解这个问题,YouTube为写入流量创建了主数据库,为读取流量创建了一个副本数据库。
- 随着对cat视频的需求达到一个历史最高点,只读流量仍然高到足以使副本数据库过载。因此,YouTube添加了更多副本,再次提供了一个临时解决方案。
- 最终,写流量变得太高,以至于master数据库无法处理;要求YouTube分割数据以处理传入的流量,如果单个MySQL实例数据量太大,那么分片也将变得必要)。
- YouTube修改了应用程层代码,以便在执行任何数据库操作之前,通过代码识别特定的查询到达正确的数据库分片。
Vitess让YouTube从源代码中删除逻辑代码,在应用程序和数据库之间引入代理,通过路由来管理和数据库间的交互。从此以后,YouTube已将用户群规模扩大了50倍,大大增加了其页面的服务能力,处理新上传的视频,等等。更重要的是,Vitess是一个可以继续扩展的平台。
YouTube选择使用Go语言开发Vitess,因为Go语言优秀的表现能力和性能。它几乎和Python一样富有表现力,非常易于维护。但是,它的性能与Java相同,在某些情况下接近C++。此外,该语言非常适合并发编程,并具有非常高质量的标准库。
Vitess的开源版本与YouTube使用的版本非常相似,虽然有一些变化让YouTube可以利用Google的基础设施,但核心功能是一样的。当开发新功能时,Vitess团队首先使它们在开源树中工作,在某些情况下,团队编写一个使用Google特定技术的插件。这种方法确保Vitess的开源版本维持与内部版本相同的质量水平。
绝大多数Vitess开发发生在开放的GitHub上。因此,Vitess的构建具有可扩展性,以便您可以根据您的基础设施的需求进行调整。