这篇是基于上一篇,的续篇,深度对sharing 的问题做分析
在上一个内容中,我们讨论了关于MYSQL INSTANCE 针对大量数据的对策,以及基本的策略,
1 优化数据存储类型
2 删除无用的索引
3 让主键足够的小
4 归档数据
最后在这些方法都穷尽了,我提出了通过水平分割的方式来让MYSQL 实例在一个可以被接受的SIZE范围内。当与我内部的团队进行讨论后,这里有一些反馈关于分片的更多的详细内容。这篇主要的目标是给出更多的理论和思考并且通过proxysql来实现简单的部署实例。
1 What is Sharding ?
Sharing 是一个使用频率较高的词汇,但经常被误会实际的意思,常用的方式是垂直scaling,提供更高的硬件资源来满足更多的数据存储和数据处理。水平的scaling 是分割你的数据,让你的数据存储进独立的更小的单元。
基于分布式的环境中的MYSQL应该有超过一个或这更多的MYSQL 服务器并且这些服务器是独立的。具体的实现细节,因部署的方式有别,但这里有一些建议:
1 shard 的节点应该是独立的SERVER 或者 冗余复制集合
2 每个shard 有独立的架构,可以独立运行执行的查询并获得结果
3 通过定义好的identifier 标识后的数据只能属于某一个分片
2 Sharding Considerations and challenges
虽然分片常常成为管理爆炸式数据的唯一方法,但大多数专家和架构师建议尽可能延迟分片。如果这是处理数据的好方法,为什么呢? 最主要的原因是复杂性。虽然垂直扩展是微不足道的(只添加更多硬件,不做其他更改),但分片需要大量的思考和计划。主要的挑战分为几个主要方面:
1 数据如何进行分割
2 跨越分片的数据查询
3 数据在存储是并不属于任何一个分片?
基于这些问题,sharding 后的系统是具有复杂性,并且每个节点都可能是这个复杂性的制造者。
How Do I split My data ?
选择分片键是Sharding最重要的一件事情,主要的概念就是挑选一个合适的分片键,如客户的ID ,游湖的ID 等等,通常是要你的分片键要最小化,同时也会依据你数据的聚合需求,是否能选择好一个分片键是对分片系统的一个关键,如果选择的分片键不足以将数据分割到不同的数据存储节点,那这就是一个缺陷。但反过来如果分的太细,那么本可以在一个单元进行计算的数据就会分割到多个存储节点,这又是一个问题。
(个人觉得这段说出了分片系统的软肋和性能在逻辑层面的好坏的关键)
what if mysql data spans shards ?
这个问题实际上是你是否使用分片方式的一个重要的因素,将数据拆分到不同的数据节点,而数据查询是从某一个节点来获得,这对于分片是简单的。可在很多其他的工作负载中,都是通过在不同节点收集数据并汇聚后给出结果。下面有一个简单的查询
SELECT user_id, date_created FROM users ORDER BY date_created DESC LIMIT 10;
当所有用户都存储在一个服务器上时,这个查询就不重要了。然而,当数据被分割到多个分片时,我们现在需要一种方法来聚合这些数据。执行这一方法超出了本文的范围,但总体方法如下:
1 查询分发到分片节点
2 收集每个分片查询后的结果并聚合
3 过滤或合并结果并输出
如果在查询中非常依赖聚合查询,那么数据聚合就比较重要了,这也是影响到是否采用sharding方式的一个重要的因素。在理想的场景中,活动OLTP工作负载可以包含在各个分片中。报告和数据仓库需要实现分布式查询,这些查询可以通过不同的系统进行管理,或者通过使用多源MySQL异步复制的自定义聚合进行管理。
How Do I find My data ?
在确认了分片键后,数据存储后,在查询中需要明确和解决的两个问题是
1 确认那些节点掌握数据
2 应用如何访问这些分散的数据
这里最基本的例子是在2个分片上通过userID进行分片。偶数用户id将在分片0上,奇数用户id将在分片1上。虽然非常简单,但当2个shard不够时,我该怎么办?这种架构的目标是在单个分片变得太大时添加更多分片。所以现在,当我添加新的分片时,分片的数量会增加,因此shardID可能会改变许多记录。
或者可以通过设置一个中转系统,来记录分片和数据之间的对应关系,通过这样的分片数据map 来提高数据在分片之间移动的灵活性,当然这不非要在MYSQL 内部在操作,可以独立出来一个系统,但反过来会提高系统的延迟。
Connecting to the shard
在我们定了shardID 和shard ID 的规则后, 我们需要连接到数据库来访问这些数据就成为一个问题,可以将这个问题推到应用程序端,通过应用程序来访问对应的数据,或者我们需要一个代理层来完成这个功能。
显而易见应用层是不愿意来为这个买单的,开发人员也不想知道这么乱的连接访问方式,所以代理层来确保应用可以路由的访问这些数据,作为第7层服务,ProxySQL能够检查查询本身,并根据定义的规则做出决定。虽然这肯定不是唯一的方法,但让我们来看一个示例ProxySQL实现,它使用查询注释路由到正确的分片。
(以下不是翻译,实际上原文中提出的问题是在没有类似MYSQL CAT 或者DBLE 中间件的模式下,手动进行数据分片并通过PROXYSQL 中间件定义数据分片访问的方式来达到 sharding 的数据访问,虽然这很笨)
文字下面是基于proxysql 如何进行数据分片的访问,这里就不在翻译了,去用MYCAT 或者 DBLE 是一件明智的事情。
注:本文中个人觉得关于分片,还是需要理解业务,并且根据业务来进行数据分片的划分,即使是通过Postgres-xl 方式的分布式数据库,在这方面也需要考虑那些使用复制表 ,哪些使用分布式表来操作查询数据,提供好的性能。
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
机房租用,北京机房租用,IDC机房托管, http://www.fwqtg.net
相关推荐: Go 开源库运行时依赖注入框架 Dependency injection
Dependency injection 一个Go编程语言的运行依赖注入库。依赖注入是更广泛的控制反转技术的一种形式。它用于增加程序的模块化并使其具有可扩展性。 实例展示(High API): type A struct { Name string } fun…