[置顶] MySQL集群



组建MySQL集群的几种方案
LVS+Keepalived+MySQL(有脑裂问题?但似乎很多人推荐这个)
DRBD+Heartbeat+MySQL(有一台机器空余?Heartbeat切换时间较长?有脑裂问题?)
MySQL Proxy(不够成熟与稳定?使用了Lua?是不是用了他做分表则可以不用更改客户端逻辑?)
MySQL Cluster (社区版不支持INNODB引擎?商用案例不足?)
MySQL + MHA (如果配上异步复制,似乎是不错的选择,又和问题?)
MySQL + MMM (似乎反映有很多问题,未实践过,谁能给个说法)

回答:

不管哪种方案都是有其场景限制 或说 规模限制,以及优缺点的。

1. 首先反对大家做读写分离,关于这方面的原因解释太多次数(增加技术复杂度、可能导致读到落后的数据等),只说一点:99.8%的业务场景没有必要做读写分离,只要做好数据库设计优化 和配置合适正确的主机即可。

2.Keepalived+MySQL --确实有脑裂的问题,还无法做到准确判断mysqld是否HANG的情况;

3.DRBD+Heartbeat+MySQL --同样有脑裂的问题,还无法做到准确判断mysqld是否HANG的情况,且DRDB是不需要的,增加反而会出问题;

3.MySQL Proxy -- 不错的项目,可惜官方半途夭折了,不建议用,无法高可用,是一个写分离;

4.MySQL Cluster -- 社区版本不支持NDB是错误的言论,商用案例确实不多,主要是跟其业务场景要求有关系、这几年发展有点乱不过现在已经上正规了、对网络要求高;

5.MySQL + MHA -- 可以解决脑裂的问题,需要的IP多,小集群是可以的,但是管理大的就麻烦,其次MySQL + MMM 的话且坑很多,有MHA就没必要采用MMM


建议:
1.若是双主复制的模式,不用做数据拆分,那么就可以选择MHA或 Keepalive 或 heartbeat
2.若是双主复制,还做了数据的拆分,则可以考虑采用Cobar;
3.若是双主复制+Slave,还做了数据的拆分,需要读写分类,可以考虑Amoeba;

上述所有的内容都要依据公司内部的业务场景、数据量、访问量、并发量、高可用的要求、DBA人群的数量等 综合权衡,

先介绍几种方案
  • 主从复制,包括一拖一的主从和一拖多的主从

高可用性 :比较高

高可扩展性 :无

高一致性 :比较高

延迟性 :比较小

并发性 :无

事务性 :无

吞吐率 :比较高

数据丢失 :不丢失

可切换 :可以切换


  • 环形复制,包括两个节点和多个节点形成的环形

高可用性 :比较高

高可扩展性 :无

高一致性 :比较高

延迟性 :比较小

并发性 :无

事务性 :无

吞吐率 :比较高

数据丢失 :不丢失

可切换 :可以切换


  • 2PC:

高可用性 : 很高

高可扩展性 : 可扩展,不能大规模扩展,也无需大规模扩展

高一致性 : 比较高

延迟性 : 比较大

并发性 : 比较小

事务性 : 有

吞吐率 : 比较小

数据丢失 : 不丢失

可切换 : 无关


  • Paxos:元数据的高可用,并发度不高

高可用性 : 很高

高可扩展性 : 无关 可扩展,不能大规模扩展,也无需大规模扩展

高一致性 : 很高

延迟性 : 比较大

并发性 : 比较小

事务性 : 有

吞吐率 : 比较小

数据丢失 : 不丢失

可切换 : 无关



以上纯属个人理解,如有异议,也是没问题的;

另外按照master是否服务具体业务来分分布式可以分为两类:

  1. master管理系统,并且所有请求通过master,很明显master存在性能瓶颈
  2. master管理系统,实际请求不通过master,请求分散均匀了


肯定选方案2




基于这些方案的特点,如何设计一个牛逼滴分布式系统 ?


这里的牛逼包括

  • 可大规模扩展:要求像hadoop那样,至少几百条台没问题
  • 高可用:master需要高可用,节点也需要高可用,也就是说任何一个组件的一个实例或者部分实例挂了,都不会影响整个系统
  • 高并发:普通机器单节点至少要支持几千的并发度吧,如果扩展解决了,整个系统的并发其实也扩展的
  • 数据一致性:分布式系统,一致性可难了,尽量保证吧,比如主从同步实现一致 ,或者使用两阶段2pc同时写多个节点,或者使用像paxos一致性协议算法实现哈
  • 事务性:分布式系统,绝对的事务很难吧,哎,我们就用2pc,3pc吧,尽量保证哈
  • 自动切换 : 首先你得想自动切换的条件如何呢? 比如主从同步,主挂了,我可以自动切换到从,可是如果从数据和主不同步,但是业务要求很高,不允许这种情况出现,那也只好停服维护啦。

好了 你可以开始喷了 , 怎么可能。


paxos一致性协议,可用性很高,一致性很高,事务性很不错 , 那么涉及到各种服务都可以用他,非常好。

master和metadata元数据采用paxos一致性协议,所有节点也采用paxos一致性协议 , 客户端保持这些信息。架构如下所示 ,master, metadata, node 都实现了paxos协议,也即通过paxos接口访问

<img src="https://pic3.zhimg.com/v2-a937e63906ed893b25f1f8bc8ac3350a_b.png" data-rawwidth="897" data-rawheight="488" class="origin_image zh-lightbox-thumb" width="897" data-original="https://pic3.zhimg.com/v2-a937e63906ed893b25f1f8bc8ac3350a_r.png">

分布式数据库就是一个例子,貌似目前流行的数据库都还没有支持paxos协议的,有谁可以开发下。节点采用paxos的话,有个问题没想清楚,paxos如何sql结合使用?另外节点的性能会受一点影响。降低一点要求吧,节点采用主主复制,或者环形复制吧。master检查节点存活,并且做切换,通知客户端。

架构如下所示 ,master, metadata,实现了paxos协议,也即通过paxos接口访问;node的各个节点是复制关系,服务节点挂掉的时候,需要master检测,并且做切换处理。


<img src="https://pic1.zhimg.com/v2-fdae1029fdf2555204b48cb63cf13ea0_b.png" data-rawwidth="890" data-rawheight="493" class="origin_image zh-lightbox-thumb" width="890" data-original="https://pic1.zhimg.com/v2-fdae1029fdf2555204b48cb63cf13ea0_r.png">

如果是分布式系统,比如文件系统,或者自己开发的系统, 那节点可以考虑用paxos协议哦。 每个节点采用3个实例,或者你有资源,采用5个实例。



分布式数据库的sql实现

也是一个难点,即一个复杂的sql,如何实现?


•使用分库分表的思想实现数据存储
•使用mapred的思想实现sql计算


•将输入sql经过词法,语法,语义分析,集合表结构信息和数据分布信息,生成包含多个阶段(简称stage)的执行计划,这些阶段具有一定的依赖关系,形成多输入单输出的任务树;
•每个阶段包括两种sql,称为mapsql和redsql,另外每个阶段包括三个操作,map,数据洗牌和red;map和red分别执行mapsql和redsql;


子句的处理逻辑和处理顺序:


1.union:分解每个子句,单独解析,形成平行关系
2.from:选择表,可以是选择多张表,也可是join的情况
3.join:from中如果包含join,就要考虑join的各种问题
4.where:单表,多表,join之后的where过滤条件
5.group:分组
6.select:选择的列
7.distinct:去掉重复的行
8.having:聚合之后的过滤
9.order:将结果排序
10.limit offset:获取最终结果的某些记录
11.子查询:遇到子查询独立解析,跟上层建立依赖关系

连接,包括内连接,左连接,右连接,半连接,外连接

以如下sql为例:

某一注册时间范围内的用户的所有登录信息

selectt1.u_id,t1.u_name,t2.login_product

from tab_user_info t1 jointab_login_info t2

on (t1.u_id=t2.u_id andt1.u_reg_dt>=? and t1.u_reg_dt<=?)


生成的执行计划为:

由于是join,所有的表都要进行查询操作,并且为每张表打上自己的标签,具体实施的时候可以加个表名字字段,在所有存储节点上执行

select u_id,u_name from tab_user_info t whereu_reg_dt>=? and t1.u_reg_dt<=?

select u_id, login_product from tab_login_info t

执行完成之后,这种情况下由于需要按照u_id进行数据洗牌,考虑到u_id的唯一值比较多,所以各个存储节点上需要按照u_id进行划分,

例如有N个计算节点,那么按照(最大u_id-最小u_id)/N平均划分,将不同存储节点上的同一范围的u_id,划分到同一个计算节点上


然后在计算节点上执行如下操作

selectt1.u_id,t1.u_name,t2.login_product

from tab_user_info t1 jointab_login_info t2

on (t1.u_id=t2.u_id)


关于分布式sql如何实现的问题,有很多未尽事宜。有兴趣的可以相互讨论


你可能感兴趣的:(数据库)