分库分表之初识Vitess
Vitess,作为海外最为知名的分库分表产品,一直以来在国内声音不多。近期抽空了解下这个产品,特分享出来。本文部分内容取自Vitess官网https://vitess.io。
1. Vitess概述
人生基本上就是两件事,选题和解题。最好的人生是在每个关键点上,既选对题,又解好题。人生最大的痛苦在于解对了题,但选错了题,而且还不知道自己选错了题。正如人生最大的遗憾就是,不是你不行,而是你本可以。
Vitess是一个用于部署、扩展和管理大型开源数据库实例集群的数据库解决方案。它目前支持MySQL、Percona和MariaDB。它的架构设计使其在公共或私有云架构中运行时与在专用硬件上运行时一样有效。它结合并扩展了许多重要的SQL功能和NoSQL数据库的可扩展性。
1).使用场景
- 数据分片
通过允许分片来缩放SQL数据库,同时将应用程序更改保持在最低限度。
- 数据迁移
从裸金属迁移到私有云或公共云。
- 管理实例
部署和管理大量SQL数据库实例。
2).技术特点
性能优化
- 连接池
数据库连接池能力,满足支持大量前端应用连接。
- 查询结果重用
正在运行的查询,对于后续完全相同的请求将重用同一查询的结果。
- 事务管理器
限制并发事务的数量并管理超时,以优化整体吞吐量。
- 行缓存
对于需根据主键随机访问的字段查询,维护一个基于行的缓存(使用 memcached),可优化 OLTP 工作负载非常有用。
运行防护
- 查询重写和净化
添加限制并防止不确定性的更新。
- 查询黑名单
自定义规则,防止潜在有问题的查询提交到数据库。
- 杀掉查询
终止运行需要很长时间才能返回数据的查询。
- 表级别 ACLs
根据连接用户为表定义访问控制列表(ACLs)。
监控诊断
- 性能分析
提供对数据库性能进行监控、诊断和分析的工具。
系统运维
- 集群/拓扑管理工具
提供基于 Web 的的集群管理工具,可显示整体拓扑。上述能力支持面向多个数据中心/区域的场合。
海量存储
- 分片能力
支持垂直、水平分片能力,支持自定义分片策略,支持在线重分片能力。
3). 核心优势
- 分片管理
MySQL本身并不提供拆分分片功能,但是您的业务数据量增大到一定程度是您是需要增加集群的。Vitess提供在线拆分功能,只需要很少的时间就完成新集群的切换,无需您在应用程序中添加任何拆分逻辑。
- 连接池
Vitess避免了MySQL连接的高内存开销。Vitess服务器轻松地一次处理数千个连接。
- 工作流
Vitess会跟踪有关集群配置的所有元数据,以便集群拓扑始终是最新的,对不同的客户端保持一致。
- 性能
Vitess自动重写对数据库性能有损害的查询。它还使用缓存机制来调节查询,并防止重复查询同时到达您的数据库
- 扩展性
Vitess集Mysql数据库的很多重要特性和NoSQL数据库的可扩展性于一体。其内建拆分分片功能使您能够对您的MySQL数据库集群无限水平扩展,同时无需为应用添加分片逻辑
- 管理
Vitess可以支持自动处理主故障转移和备份等功能。它使用分布式元数据服务来跟踪和管理服务器,使您的应用程序无需关心数据库拓扑变化。
4).方案对比
- 与MySQL对比
- 与NoSQL对比
2. Vitess基本架构
人生基本上就是两件事,选题和解题。最好的人生是在每个关键点上,既选对题,又解好题。人生最大的痛苦在于解对了题,但选错了题,而且还不知道自己选错了题。正如人生最大的遗憾就是,不是你不行,而是你本可以。
Vitess 平台由若干服务器进程、命令行工具和基于 web 的工具组成,具备一致性元数据存储支持。根据用户应用程序的现状,可以选择不同的方式接入Vitess。如果正在从头构建一个服务,应该起始于定义数据库拓扑;如果需要对现有数据库进行扩展,那首先需要部署一个连接代理。无论数据库集群规模大小,Vitess 工具和服务器都旨在提供帮助。对于较小的实现,VTTablet 的一些特性诸如连接池和行缓存可以帮助更充分利用现有硬件。Vitess 的自动化工具则为大型实现提供额外的好处。
Cell
Cell 是放置一组服务器和网络基础设施的区域,并且与其他Cell做到故障隔离。它通常是一个完整的数据中心或数据中心子集,有时称为Zone或Availability Zone。Vitess 可以优雅地处理Cell 级故障,例如当一个Cell 断开网络时。Vitess 在每个Cell中托管本地拓扑服务。这一服务在Cell中包含Tablet的大部分信息,这使得Cell能够被拆除并重建。Vitess 限制数据和元数据的跨Cell的流量。虽然其具有将读取流量路由到单个Cell的能力,但 Vitess 目前仅提供来自本地Cell的读取。如有必要,Vitess可跨Cell写入。
Execution Plans
Vitess 在 VTGate 和 VTablet 层解析查询,评估执行查询的最佳方法,进而生成查询执行计划。Vitess 优化策略之一是将尽可能多的工作下推到底层 MySQL 实例。当这不可能时,Vitess 将使用从多个MySQL收集输入并合并结果以生成正确查询结果。
- 评估模式
一个执行计划由操作符组成,每个操作符执行一个特定的工作。整个执行计划是由一组树形结构的操作符组成,每个操作符为树中的一个节点。每个操作符将零或多行作为输入,并产生零或多行作为输出。这意味着一个操作的输出成为下一个操作的输入。连接树中两个分支的操作符组合来自两个传入流的输入并产生单个输出。执行计划的评估从树的叶子节点开始。叶子节点从 VTablet 中提取数据,并且在某些情况下还能够在本地评估表达式值。每个叶子节点不会有来自其他操作符的输入,并且将它们产生的任何节点通过管道传输到其父节点。然后,父节点将通过管道将节点传送到它们的父节点,一直到根节点。根节点产生查询的最终结果并将结果传递给用户。
- 查看计划
可通过浏览/queryz端点,在 VTGate 级别观察缓存的执行计划。从Vitess 6开始,也可通过下面命令来查看:EXPLAIN FORMAT=vitess .
Keyspace
Keyspace 是一个逻辑数据库。如果使用分片技术,则keyspace映射到多个 MySQL 数据库;如果没使用分片,则keyspace直接映射到 MySQL 数据库名称。无论那种情况,从应用侧来看,keyspace都显示为单个数据库。从 keyspace 读取数据就像从 MySQL 数据库读取数据一样。但是根据读取操作的一致性要求,Vitess 可能会选择从主数据库或备数据库中读取。
- Keyspace id
Keyspace ID,就是通常讲的分片键。基于范围的分片,是指创建时指定覆盖特定范围的keyspace ID。使用此方式,可通过用两个或更多新分片,替换原有分片来拆分。而新分片组合在一起以覆盖keyspace ID 的范围,而无需移动其他分片中的任何记录。Keyspace ID本身,是通过对数据中某些列的函数计算所得。Vitess 允许从各种函数 ( vindexes ) 中进行选择来执行此映射。这使你可以选择正确的方法来实现数据在分片之间的最佳分布。
MoveTables
MoveTables 是一种基于 VReplication 的新工作流。它使您能够在 Keyspace 之间重新定位表,从而在不停机的情况下重新定位物理 MySQL 实例。
- 识别候选表
建议将需要相互关联的表保留在同一 Keyspace 中,因此 MoveTables 操作的典型候选对象是一组逻辑上组合在一起或以其他方式隔离的表。如果有多组表作为候选,移动最有意义可能取决于环境的具体情况。例如,一个更大的表将需要更多的时间来移动,但这样做你可能能够利用额外的或更新的硬件,这些硬件在需要执行额外的操作(如分片)之前有更多的空间。同样,以更频繁的速率更新的表可能会增加移动时间。
- 对生产流量影响
在内部,MoveTables 操作由表副本和对表所做的所有更改的订阅组成。Vitess 使用批处理来提高表复制和应用订阅更改的性能,但应该期望修改率较低的表移动得更快。在主动移动过程中,数据是从副本而不是主服务器复制的。这有助于确保最小的生产流量影响。在MoveTables 中SwitchWrites 操作阶段,Vitess 可能会暂时不可用。这种不可用性通常是几秒钟,但如果系统从主副本到副本的复制延迟很高,则会更高。
Query Rewrite
Vitess 努力营造一种用户与单个数据库连接的错觉。实际上,单个查询可能与多个数据库交互,并且可能使用多个连接到同一数据库。
- 查询分解
具有跨分片连接的复杂查询,可能需要先从保持 VIndex 查找表的 Tablet 中获取信息,然后使用此信息查询两个不同的分片以获取更多数据,并将传入的结果连接到用户接收的单个结果中。MySQL 获取的查询通常只是原始查询的一部分,最终结果将在 VTGate 级别组装。
- 连接池
当 Tablet 与 MySQL 对话以代表用户执行查询时,它不会为每个用户使用专用连接,而是会在用户之间共享底层连接。这意味着在会话中存储任何状态都是不安全的,因为无法确定它是否会继续在同一连接上执行查询,并且无法确定此连接稍后是否会被其他用户使用。
Replication Map
Vitess 通过复制图来识别主数据库和它们各自的副本之间的关系。在故障转移期间,复制图使 Vitess 能够将所有现有副本指向新指定的主数据库,以便继续复制。
Shard
分片是一个 Keyspace 的子集。一个 Keyspace 将包含一个或多个分片。一个分片通常包含一个 MySQL 主副本和许多 MySQL 副本。分片中的每个 MySQL 实例都具有相同的数据。副本可以提供只读流量(具有最终的一致性保证)、执行长时间运行的数据分析查询或执行管理任务(备份、恢复、差异等)。
- Reshard
Vitess 支持重新分片,其中在实时集群上更改分片的数量。这可以是将一个或多个分片拆分为更小的部分,或者将相邻的分片合并为更大的部分。在重新分片期间,源分片中的数据被复制到目标分片中,然后与原始分片进行比较以确保数据完整性,最后将实时服务基础设施转移到目标分片,并删除源分片。
- Tablet
Tablet 是mysqld过程和相应的vttablet过程的组合,通常运行在同一机器上。每个 Tablet 都具备对应的角色。查询通过 VTGate 服务器路由到Tablet。Tablet 划分角色如下:
- primary
Tablet对应的MySQL角色是主库。
- replica
Tablet对应的MySQL角色是从库,且该从库有资格提升为主。这一角色一般服务面向实时只读查询的访问。
- rdonly
Tablet对应的MySQL角色是从库,且该从库无法提升为主。这一角色通常用于后台处理作业,例如备份、将数据转储到其他系统、大量分析查询、MapReduce 和重新分片。
- backup
Tablet对应的MySQL角色是从库,且因一致性快照而停止复制,可将其分片上传备份。完成后,它将恢复复制并返回到以前的类型。
- restore
启动时 Tablet 对应MySQL没有数据,正在从最新备份中恢复。完成后,它将进入复制状态,并且角色变为replica或rdonly。
- drained
为Vitess 后台进程保留的Tablet,例如用于重分片等需求。
Topology Service
该拓扑服务是一组在不同服务器上运行的后端进程组成。这些服务器存储全局拓扑数据,并提供分布式锁定服务。Vitess 使用插件系统来支持存储拓扑数据的各种实现,默认的拓扑服务存储插件是etcd2。拓扑服务的存在有几个原因:
协调集群内 Tablets,发现Tablet,并感知将查询路由到哪里。
存储集群中不同服务器上的 Vitess 配置,并且必须在服务器重新启动之间保持不变。
一个 Vitess 集群有一个全局拓扑服务,每个单元有一个本地拓扑服务。
- Global Topology
全局拓扑服务存储不经常更改的 Vitess 数据。具体来说,它包含有 Keyspace 和 Shard 的数据以及每个 Shard 的主要 Tablet。全局拓扑用于一些操作,包括重新选主、重新分片。为了在任何单个单元发生故障时幸免于难,全局拓扑服务应该在多个单元中具有节点,以便在单元发生故障时维持仲裁。
- Local Topology
每个本地拓扑都包含与其自身 Cell 相关的信息。具体来说,它包含有关 Cell 中 Tablet 的数据、该 Cell 的 Keyspace 以及该Cell的复制图。本地拓扑服务必须可供 Vitess 使用以发现Tablet 并在 Tablet 变化时调整路由。但是,在稳定状态下提供查询服务的关键路径中不会调用拓扑服务。这意味着在拓扑暂时不可用期间仍会提供查询服务。
VSchema
一个 VSchema 用来描述数据是如何Keyspace和Shard内组织。此信息用于路由查询,也用于重新分片操作。对于 Keyspace,可以指定它是否被分片。对于分片的 Keyspace,可以为每个表指定 vindexes 列表。
- 序列
Vitess 支持序列生成器,可用于生成新的 id,其工作方式类似于 MySQL 自动增量列。VSchema 允许将表列关联到序列表。如果没有为这样的列指定值,那么 VTGate 将知道使用序列表为它生成一个新值。
VStream
VStream 是一种可通过 VTGate 访问的更改通知服务。VStream 的目的是从 Vitess 集群的底层 MySQL 分片提供与 MySQL 二进制日志等效的信息。gRPC 客户端,包括 Vitess 组件,如 VTablets,可以订阅 VStream 以接收来自其他分片的更改事件。VStream从VTTablet实例上的一个或多个VStreamer实例拉取事件,后者又从底层MySQL实例的二进制日志拉取事件。这允许有效执行诸如 VReplication 之类的功能,其中订阅者可以从一个或多个 MySQL 实例分片的二进制日志中间接接收事件,然后将其应用于目标实例。用户可以利用 VStream 获取有关给定 Vitess Keyspace、Shard和位置的数据更改事件的深入信息。工作原理可参考如下:
vtctl
vtctl是一个命令行工具,用于管理 Vitess 集群。它既可用作独立工具 ( vtctl),也可用作客户端-服务器(vtctlclient与 结合使用vtctld)。建议使用客户端-服务器,因为它在远程使用客户端时提供了额外的安全层。使用 vtctl,可以识别主数据库和副本数据库、创建表、启动故障转移、执行重新分片操作等。随着 vtctl 执行操作,拓扑服务会根据需要进行更新。其他 Vitess 服务器会观察这些变化并做出相应的反应。例如,如果您使用 vtctl 故障转移到新的主数据库,vtgate 会看到更改并将未来的写入操作定向到新的主数据库。
vtctld
vtctld是一个 HTTP 服务器,可浏览存储在拓扑服务中的信息。它对于故障排除或获取服务器及其当前状态的高级概述很有用。vtctld还充当vtctlclient连接的服务器。
VTGate
VTGate 是一个轻量级的代理服务器,它可以将流量路由到正确的 VTTablet 服务器并将合并的结果返回给客户端。它同时使用 MySQL 协议和 Vitess gRPC 协议。因此,应用程序可以像连接 MySQL 服务器一样连接到 VTGate。在将查询路由到适当的 VTablet 服务器时,VTGate 会考虑分片方案、所需的延迟以及表及其底层 MySQL 实例的可用性。
3. Vitess产品理念
人生基本上就是两件事,选题和解题。最好的人生是在每个关键点上,既选对题,又解好题。人生最大的痛苦在于解对了题,但选错了题,而且还不知道自己选错了题。正如人生最大的遗憾就是,不是你不行,而是你本可以。
1). 可扩展理念
Vitess的产品理念,是将数据库分片,将其分解成很小的部分,很容易将它们分解到足以容纳一台机器的程度。在行业中,每个主机只运行一个MySQL实例是很常见的。Vitess建议将实例分解成可管理的块(每个MySQL服务器250GB),并且不要回避每个主机运行多个实例。净资源使用量将大致相同。但是当MySQL实例很小时,可管理性会大大提高。跟踪端口和分离MySQL实例的路径会很复杂。然而,一旦越过这个障碍,其他一切都变得简单了。拆分为更小粒度后,需要担心的锁争用更少,复制更快,停机对生产的影响变得更小,备份和恢复运行更快,并改善资源使用。
2). 复制代替持久性
传统意义上,数据被刷新到磁盘时就将其视为持久的。Vitess 更为推荐的耐久性方法是通过将数据复制到多台机器甚至多个地理位置来实现的。这种形式的耐久性解决了对设备故障和灾难的担忧。Vitess中的许多工作流都是根据这种方法构建的。例如,强烈建议打开半同步复制。这允许Vitess在主数据库崩溃时故障转移到新副本,而不会丢失数据。依赖复制还允许放松一些基于磁盘的耐久性设置。例如,可以关闭sync_binlog,这大大减少了磁盘的IOPS数量,从而提高了有效吞吐量。
3). 有取舍一致性
非一致性读
在 Vitess 中跨分片读取可能彼此不一致。在制定分片决策中,应该试图尽量减少这种情况,因为跨分片读取更昂贵。如果存在可以容忍稍显陈旧的数据,则可将查询发送到replica角色的 Tablet 处理;对于OLAP工作负载,则可发送到rdonly角色的 Tablet 处理。这一方式可提供更为灵活的缩放读取流量,并可按地理位置分布它们。这种权衡允许以陈旧或可能不一致的读取为代价获得更好的吞吐量,因为随着数据的变化(可能在不同的分片上有不同的滞后),读取可能会落后于主分片。为了缓解这种情况,VTGate服务器能够监控副本滞后,并且可以配置为避免来自滞后超过X秒的实例的数据。
- REPLICA/RDONLY read
服务器可以按地理位置缩放。本地读取速度很快,但可能会因副本延迟而失效。
- PRIMARY read
每个分片只有一个全局主要读取。来自远程位置的读取将受制于网络延迟和可靠性,但数据将是最新的(写入后读取一致性)。隔离级别READ_COMMITTED。
- PRIMARY transaction
它们显示与主读取相同的属性。但是,可以为单个分片获得REPEATABLE_READ一致性和ACID写入。跨分片原子事务的支持正在进行中。
快照级读
对于真正的快照,查询必须在事务中发送到主服务器。为了写入后读取的一致性,从主服务器读取而不使用事务就足够了。
分布式事务
在“尽最大努力模式”中,跨分片事务可能会在中间失败,并导致部分提交。可以改为使用“2PC模式”事务,为提供分布式原子保证。然而,选择此选项会增加大约50%的写入成本。单个分片事务继续保持ACID,就像MySQL支持它一样。事务支持原子性,支持以下级别:
- SINGLE:禁止多db事务。
- MULTI:尽最大努力提交的多数据库事务。
- TWOPC:具有2PC提交的多数据库事务
4). 高可用性
Vitess与Orchestrator集成,Orchestrator能够在故障检测后几秒钟内执行到新主服务器的故障转移。这对于大多数应用程序来说通常已经足够了。
原文链接:https://mp.weixin.qq.com/s/yTmJKALlE-ai-kJN_voC4g
1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。