Atlas 是由 Qihoo 360公司Web平台部基础架构团队开发维护的一个基于MySQL协议的数据中间层项目。它在MySQL官方推出的MySQL-Proxy 0.8.2版本的基础上,修改了大量bug,添加了很多功能特性。目前该项目在360公司内部得到了广泛应用,很多MySQL业务已经接入了Atlas平台,每天承载的读写请求数达几十亿条。同时,有超过50家公司在生产环境中部署了Atlas,超过800人已加入了我们的开发者交流群,并且这些数字还在不断增加。
主要功能:
1.读写分离
2.从库负载均衡
3.IP过滤
4.自动分表
5.DBA可平滑上下线DB
6.自动摘除宕机的DB
Atlas Sharding 简介
Atlas Sharding是Atlas最近重点开发的一个功能, 此功能增加了Mysql的横向扩展性跟容量, 可以满足大部分企业的需求. 目前已经在github上以Sharding分支发布.
Sharding 的基本思想就是把一个数据表中的数据切分成多个部分, 存放到区别的主机上去(切分的策略有多种), 从而缓解单台机器的性能跟容量的问题. sharding是一种水平切分, 适用于单表数据庞大的情景. 目前atlas支持静态的sharding方案, 暂时不支持数据的自动迁移.
Atlas以表为单位sharding, 同一个数据库内可以同时共有sharding的表与不sharding的表, 不sharding的表数据存在未sharding的数据库组中.
目前Atlas sharding支持insert, delete, select, update语句, 支持不跨shard的事务.
当然, 由于Mysql分布式的局限性, Atlas Sharding对于SQL的特性支持也是有限的, 但是应付日常的需求, 已经足够了.
和Mysql replication的不同
MySQL主从复制就是将一个MySQL实例(Master)中的数据实时复制到另一个MySQL实例(slave)中,这个复制是一个异步复制的过程。
数据复制有以下一些特点:
数据分布
负载平衡(需要借助Atlas或者其他proxy中间件)
备份
高可用性(high availability)与容错
复制的局限性很明显, 当数据库写入频繁, 但读取操作少的场景下, 复制就不适合了, 当写入过于频繁,很难由一台主机支撑的时候,我们还是会面临到扩展瓶颈。换句话说就是复制只能扩展读性能, 但是对于写性能的扩展是无能为力的.
数据切分(sharding): 通过某种特定的条件,将我们存放在同一个数据库中的数据分散存放到多个数据库(主机)上面,以达到分散单台设备负载的效果。这样当写入的时候, IO就被各个shard所分担了. 同时, 在每一个Shard上也是可以有复制存在的, 借助Atlas还是能在Shard上做读分离, 所以复制跟Sharding完全是互相补充, 不排斥的.
Sharding 架构
Atlas是无状态的, 对于后端的多个组, 可以配置任意多个Atlas实例, 这一点和MongoDB的mongos类似.
Sharding数据库组
在Atlas中, 将一个组看做是数据存储的单位, 一个组由一台master, 零台或者多台slave组成(mysql主从同步需要由用户自己配置). 每个组之间的数据独立, 没关于系, 表的数据的各个部分存储在各个组中.
组内读写分离
Atlas sharding也支持组内的读写分离, 也就是说Atlas在命中了某个组之后, 还是会对这个组内的master与slave执行读写分离(读发送到slave, 写发送到master).
Sharding 数据切分策略
shard key
每一个shard table都有一个shard key, 其可以是主键, 也可以是非主键, 但是这个列必须是一个整数. Atlas会利用这个shard key来判断应该把这条记录存放到哪一个数据库组中.
现在Atlas Shardingh支持两种类型的数据切分: Range方式与Hash方式.
Range 方式
如上图中, shard Key范围在0-1000的数据存放在DbGroup0中, 范围在1000-2000的数据存放在DbGroup1中, 2000-MaxInt 的数据存放在DbGroup2 中. 这些范围的大小不需要相同.比如id为shard key的话, sql: "select * from test where id = 1500;", Atlas会将此语句发往DbGroup1. 暂时Atlas的range是静态的, 不支持动态的增加范围.
优点:
对于range的sql查询如(where id > 100 or id < 1000), range方式的sharding可以精确的命中后端的数据组, 不需要将sql发到各个mysql去请求数据, 节约了网络传输的消耗.
缺点
如果shard key是递增的, 那么可能会在一段时间内的所有sql都命中到同一个数据组, 没有体现出sharding的优势, range不适用于这种场景.
适用场景
range适用于对范围查询有大量需求, 并且shard key相对离散插入的情景
hash 方式
目前Atlas使用取模的方式实现Hash, 也就是说Hash(id) = id % dbgroup_count, 如id = 10, id % 3 = 1, 所以会命中到DbGroup1中.
优缺点
hash跟range方式是恰好相反的, hash 可以应对数据递增的情景, 即使是在递增的情况下, sharding的数据也是均匀分布在各个数据组内的, 但是其缺点就是对于范围的查询通常都需要查询所有的dbgroup, 网络的消耗比较大.
适用场景
hash 适用于shard key顺序增长, 并对范围查询的需求比较小的情景
有关支持的语句
Atlas sharding只对sql语句提供有限的支持, 目前支持基本的Select, insert/replace, delete, update语句, 支持全部的Where语法, 但是对于以下语句, 如果语句命中了多台dbgroup, Atlas均未做支持(如果语句只命中了一个dbgroup, 如select count(*) from test where id < 1000, 其中dbgroup0范围是0 - 1000, 那么这些特性都是支持的)
Limit Offset(支持Limit)
Order by
Group by
Join
ON
Count, Max, Min等函数
这些语句Atlas会返回"ERROR 1105 (HY000): Proxy Warning - Sharing Hit Multi Dbgroup Not Support SQL"错误. 请不要在Sharding的表上使用这些特性, 如果对这种特性有需求请不要让此表sharding.
注意:
子查询在Sharding中可能会返回不正确的结果, 也请不要使用子查询. 请把语句拆分成多句执行
对于写操作, 如果写操作命中了多个数据库组, 由于部分成功(某个组执行失败)需要回滚的问题, 暂时不支持写操作命中多个数据组的语句.请拆分成多个sql语句执行.
Atlas可能会在接下来的版本中对其中的一些特性中做出支持.
有关事务支持
新闻热点
疑难解答