Atlas是由 Qihoo 360公司Web平台部基础架构团队开发维护的一个基于MySQL协议的数据中间层项目。它在MySQL官方推出的MySQL-Proxy 0.8.2版本的基础上,修改了大量bug,添加了很多功能特性。目前该项目在360公司内部得到了广泛应用,很多MySQL业务已经接入了Atlas平台,每天承载的读写请求数达几十亿条。
Atlas主要功能: 1.读写分离
2.从库负载均衡
3.IP过滤 4.自动分表
5.DBA可平滑上下线DB
6.自动摘除宕机的DB
Atlas是一个位于应用程序与MySQL之间中间件。在后端DB看来, Atlas相当于连接它的客户端,在前端应用看来, Atlas相当于一个DB。 Atlas作为服务端与应用程序通讯,它实现了MySQL的客户端和服务端协议,同时作为客户端与MySQL通讯。它对应用程序屏蔽了DB的细节,同时为了降低MySQL负担,它还维护了连接池
Atlas相对于官方MySQL-Proxy的优势
1.将主流程中所有Lua代码用C重写,Lua仅用于管理接口
2.重写网络模型、线程模型
3.实现了真正意义上的连接池
4.优化了锁机制,性能提高数十倍
注: Atlas只能安装运行在64位的系统上。后端mysql版本应大于5.1,建议使用Mysql 5.6 及以上
运行Atlas
进入/usr/local/mysql-proxy/bin目录,执行下面的命令启动、重启或停止Atlas。
(1). sudo ./mysql-proxyd test start,启动Atlas。
(2). sudo ./mysql-proxyd test restart,重启Atlas。
(3). sudo ./mysql-proxyd test stop,停止Atlas。
执行命令:mysql -h127.0.0.1 -P1234 -u用户名 -p密码,如果能连上则证明Atlas初步
测试正常,可以再尝试发几条SQL语句看看执行结果是否正确。
Atlas后端连接的MySQL主库的IP和端口,可设置多项,用逗号分隔
例如
proxy-backend-addresses = 192.168.237.128:3308
Atlas后端连接的MySQL从库的IP和端口,@后面的数字代表权重,用来作负载均衡,若省略则默认为1,可设置多项,用逗号分隔
proxy-read-only-backend-addresses = 192.168.237.130:3308@1
关闭主备库复制关系,在主库上查看
当MySQL主库关闭的情况下,写操作失败,读操作依然可以执行
当MySQL仅有的一个从库关闭的情况下,写操作成功,读操作也漂移到主库上执行
当有多个从库的情况下
Atlas后端连接的MySQL主库的IP和端口,可设置多项,用逗号分隔
proxy-backend-addresses = 192.168.237.128:3308
Atlas后端连接的MySQL从库的IP和端口,@后面的数字代表权重(数字越大读取的机会更高),用来作负载均衡,若省略则默认为1,可设置多项,用逗号分隔
例如:
当第一个从库崩溃时执行查询语句,语句都在第二个节点查询
当有多个读节点时,权重越大,被读取的可能性就越高
Atlas后端连接的MySQL从库的IP和端口, @后面的数字代表权重,用来作负载均衡,若省略则默认为1,
可设置多项,用逗号分隔
例:
proxy-read-only-backend-addresses = 192.168.237.130:3308@1,192.168.237.131:3308@2
自动读写分离挺好,但有时候写完马上就想读,万一主从同步延迟怎么办?
SQL语句前增加 /*master*/ 就可以将读请求强制发往主库。在mysql命令行测试该功能时,需要加-c选项,以防mysql客户端过滤掉注释信息。
主库宕机,读操作受影响么?
在Atlas中读操作不受影响,Atlas会将读请求转发到其他还存活的从库上。但此时写请求将会失败,因为主库宕机了。
Altas支持多个主库的运行模式吗?
官网:目前还未对于Atlas后面挂接多个主库的情形进行测试过,不建议这样使用
。建议使用一主一从或一主多从的模式。
可以做双主,在proxy-backend-addresses = ip1,ip2 但是不建议使用
类似在一个库,创建了多个子表
使用Atlas的分表功能时,首先需要在配置文件(test.cnf)设置tables参数。
tables参数设置格式:数据库名.表名.分表字段.子表数量,比如你的数据库名叫school,表名叫stu,分表字段叫id,总共分为100张表,那么就写为school.stu.id.100,如果还有其他的分表,以逗号分隔即可。用户 需要在数据库手动建立100张子表(stu_0,stu_1,…stu_99,注意子表序号是从0开始的)。 且所有的子表必须在DB的同一个database里·
分表的效果是:
当通过Atlas执行(SELECT、 DELETE、 UPDATE、 INSERT、 REPLACE)操作时, Atlas会根据分表字段结果(id%100=k),定位到相应的子表(stu_k)
。
例如,执行
select * from stu where >
但如果执行SQL语句(select * from stu;)时不带上id,则会提示执行stu 表不存在。
Atlas暂不支持自动建表和跨库分表的功能
Atlas目前支持分表的语句有SELECT、 DELETE、 UPDATE、 INSERT、 REPLACE
需要安装非shard版本,sharding版本不支持分表功能
分表设置,此例中person为库名,mt为表名,id为分表字段,3为子表数量,可设置多项,以逗号分隔,若不分表则不需要设置该项
局限性:
应用程序连接atlas分表的时候,查询必须要加where 条件 ,分表字段=
不能用范围查询>,<,或者between and ,不支持全表查询。
例:
Sharding当前是Atlas的分布式分支,
是Atlas最近重点开发的功能. Sharding的基本思想
就是把一个数据表中的数据切分成多个部分, 存放到不同的主机上去(切分的策略有多种),
从而缓解单台机器的性能跟容量的问题. sharding是一种水平切分, 适用于单表数据庞大的情景
Atlas以表为单位sharding
, 同一个数据库内可以同时共有sharding的表和不sharding的表, 不sharding的表数据存在未sharding的数据库组中.
目前Atlas sharding支持insert, delete, select, update语句, 所有的写操作如insert,delete, update只能一次命中一个组, 否则会报”ERROR 1105 (HY000):write operationis only allow to one dbgroup!”错误.
在Atlas中, 将一个组看做是数据存储的单位,一个组由一台master, 零台或者多台slave组成
(mysql主从同步需要由用户自己配置). 每个组之间的数据独立, 没有关系, 表的数据的各个部分存储在各个组中.
与非sharding的方案一样,Atlas sharding也支持组内的读写分离
, 也就是说Atlas在命中了某个组之后, 还是会对这个组内的master和slave执行读写分离(读发送到slave, 写发送到master)
Range 方式
范围数据切分方式,比如
shard Key范围在0-1000的数据存放在Group0中,
范围在1000-2000的数据存放在Group1中,
2000-MaxInt 的数据存放在Group2 中.
这些范围的大小不需要相同.比如id为shard key的话, sql: “select * from test where id = 1500;”,
Atlas会将此语句发往Group1. 暂时Atlas的range是静态的, 不支持动态的增加范围
hash 方式
目前Atlas使用取模的方式实现Hash, 也就是说Hash(id) = id % group_count, 如id =10, id % 3 = 1, 所以会命中到DbGroup1中.
Atlas sharding部分新增配置项,包含两个部分:
shardrule. 一个shardrule对应一个分表规则,不同的shardrule通过下划线后面的数字区分
。
例如shardrule-0, shardrule-1….。
一个shardrule里面有以下几项:
[shardrule-0]
table = test.sharding_test #分表名,由数据库+表名组成
type = range #sharding类型:range 或 hash
shard-key = id #sharding 字段
groups = 0:0-999,1:1000-1999 #分片的group,
如果是range类型的sharding,则groups的格式是:group_id:id范围。
如果是hash类型的sharding,则groups的格式是:group_id。例如groups = 0, 1
group. 一个group一般包含一主多从,由master(proxy-backend-addresses)和
slave(proxy-read-only-backend-addresses)组成。 group之间的区别也是通过下
划线后面的数字区分。
假设我们有以下一个sharding的表, 建表语句如下:
有两个dbgroup(数据库组), 每个dbgroup有一个master, sharding_test使用range的方
式, 以id作为shard key, 属于test数据库, dbgroup0属于范围0 - 999, dbgroup1 属于
范围 1000 - 1999
dbgroup0 有一主, 192.168.237.130:3308
dbgroup1 有一主, 192.168.237.131:3308
运行Atlas
进入/usr/local/mysql-proxy/bin目录,执行下面的命令启动、重启或停止Atlas。
(1). sudo ./mysql-proxyd test start,启动Atlas。
(2). sudo ./mysql-proxyd test restart,重启Atlas。
(3). sudo ./mysql-proxyd test stop,停止Atlas
执行命令: mysql -h 127.0.0.1 -P 1234 -u 用户名 -p,如果能连上则证明Atlas初步
测试正常,可以再尝试发几条SQL语句看看执行结果是否正确。
Atlas sharding只对sql语句提供有限的支持, 目前支持基本的Select, insert/replace, delete, update语句,
支持全部的Where语法(SQL-92标准), 不支持DDL(create drop alter)以及一些管理语句
, DDL请直连MYSQL执行, 请只在Atlas上执行Select, insert, delete, update(CRUD)语句
对于以下语句, 如果语句命中了多台dbgroup, Atlas均未做支持
(如果语句只命中了一个dbgroup, 如select count(*) from test where id < 1000, 其中dbgroup0范围是0 - 1000, 那么这些特性都是支持的)
Limit Offset (支持Limit 同一个dbgroup)
Order by
Group by
Join
count, Max, Min等函数不支持
子查询在Sharding中可能会返回不正确的结果, 也请不要使用子查询. 请把语句拆分成多句执行
对于写操作, 如果写操作命中了多个数据库组, 由于部分成功(某个组执行失败)需要回滚的问题, 暂时不支持写操作命中多个数据组的语句.请拆分成多个sql语句执行
Atlas可能会在接下来的版本中对其中的一些特性中做出支持.
例用Atlas插入几条数据,做一下测试:
以上几条数据都插入到了dbgroup0, 请注意第二条多值插入的语句, 因为50和999都命中了dbgroup0, 所以其执行成功, 但是如果执行以下的语句:
mysql> insert into sharding_test(id, name, age) values(100, 'test', 0), (1500, 'test',
0);
ERROR 1105 (HY000): Proxy Warning - write operation is only allow to one
dbgroup! 在sharding的表中, 这是不允许的, 因为id为100命中了dbgroup0, 而id为1500 命中了dbgroup1, 由于分布式的多值插入可能导致部分成功, 需要回滚, 这个Atlas暂不支持. update, delete, replace同理.
再插几条数据到dbgroup1:
mysql> insert into sharding_test(id, name, age) values(1000, 'test', 0), (1999,
'test', 0);
Query OK, 2 rows affected (0.00 sec)
mysql> select * from sharding_test;
+------+------+------+----------+----------+
| id | name | age | birthday | nickname |
+------+------+------+----------+----------+
| 1 | test | 0 | NULL | NULL |
| 50 | test | 0 | NULL | NULL |
| 999 | test | 0 | NULL | NULL |
| 1000 | test | 0 | NULL | NULL |
| 1999 | test | 0 | NULL | NULL |
mysql> select * from sharding_test where id>50;
+------+------+------+----------+----------+
| id | name | age | birthday | nickname |
+------+------+------+----------+----------+
| 999 | test | 0 | NULL | NULL |
| 1000 | test | 0 | NULL | NULL |
| 1999 | test | 0 | NULL | NULL |
#JOIN操作,不支持
mysql> select * from sharding_test a,test.temp b on a.>ERROR 1105 (sqlst): Proxy Warning - Sharing Hit Multi Dbgroup Not Support
SQL
#update操作
mysql> update sharding_test set name='test2';
ERROR 1105 (HY000): Proxy Warning - Syntax Forbidden!
mysql> update sharding_test set name='test2' where id<2000;
ERROR 1105 (sqlst): Proxy Warning - write operation is only allow to one
dbgroup!
mysql> update sharding_test set name='test2' where id<999;
Query OK, 2 rows affected (0.01 sec)
#delete操作
mysql> delete from sharding_test;
ERROR 1105 (HY000): Proxy Warning - Syntax Forbidden!
mysql> delete from sharding_test where id<2000;
ERROR 1105 (sqlst): Proxy Warning - write operation is only allow to one
dbgroup!
mysql> delete from sharding_test where id>1900;
Query OK, 1 row affected (0.01 sec)
更多的看看官方文档:https://github.com/Qihoo360/Atlas/wiki
Linux公社的RSS地址:https://www.linuxidc.com/rssFeed.aspx
本文永久更新链接地址:https://www.linuxidc.com/Linux/2019-01/156361.htm
本栏最新