一、简介
Atlas是由 Qihoo 360公司Web平台部基础架构团队开发维护的一个基于MySQL协议的数据中间层项目。它在MySQL官方推出的MySQL-Proxy 0.8.2版本的基础上,修改了大量bug,添加了很多功能特性。目前该项目在360公司内部得到了广泛应用,很多MySQL业务已经接入了Atlas平台,每天承载的读写请求数达几十亿条。
主要功能:
1 2 3 4 5 6 | 1.读写分离 2.从库负载均衡 3.IP过滤 4.自动分表 5.DBA可平滑上下线DB 6.自动摘除宕机的DB |
二、Atlas相对于官方MySQL-Proxy的优势
1
2
3
4
|
1.将主流程中所有Lua代码用C重写,Lua仅用于管理接口
2.重写网络模型、线程模型
3.实现了真正意义上的连接池
4.优化了锁机制,性能提高数十倍
|
三、Atlas详细说明
1 2 3 4 5 6 7 | 1.Atlas的安装 2.Atlas的运行及常见问题 3.Atlas的分表功能简介 4.Atla部分配置参数及原理详解 5.Atlas的架构 6.Atlas的性能测试 7.Atlas功能特点FAQ |
四、Atlas的需求及Bug反馈方式
如果用户在实际的应用场景中对Atlas有新的功能需求,或者在使用Atlas的过程中发现了bug,欢迎用户发邮件至zhuchao[AT]360.cn,与我们取得联系,我们将及时回复。另外有热心网友建立了QQ群326544838,开发者也已经加入,方便讨论。
五、名字来源
Atlas:希腊神话中双肩撑天的巨人,普罗米修斯的兄弟,最高大强壮的神之一,因反抗宙斯失败而被罚顶天。我们期望这个系统能够脚踏后端DB,为前端应用撑起一片天。
六、安装
Atlas的安装非常简单,从https://github.com/Qihoo360/Atlas/releases地址下载相应的rpm包直接安装即可,可能有一些依赖关系,yum都能解决的,就不多讲了!
七、配置文件:
配置文件位置/usr/local/mysql-proxy/config下面,就我的内网应用而言,我创建新的配置文件如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
[mysql-proxy]
#带#号的为非必需的配置项目
#管理接口的用户名
admin-username
=
admin
#管理接口的密码
admin-password
=
passw0rd
#Atlas后端连接的MySQL主库的IP和端口,可设置多项,用逗号分隔
proxy-backend-addresses
=
192.168.1.66:3306
#Atlas后端连接的MySQL从库的IP和端口,@后面的数字代表权重,用来作负载均衡,若省略则默认为1,可设置多项,用逗号分隔
proxy-read-only-backend-addresses
=
192.168.1.64:3306,192.168.1.244:3306
#用户名与其对应的加密过的MySQL密码,密码使用PREFIX/bin目录下的加密程序encrypt加密,下行的user1和user2为示例,将其替换为你的MySQL的用户名和加密密码!
#pwds = user1:+jKsgB3YAG8=, user2:GS+tr4TPgqc=
pwds
=
root:FYCDJMDki+SiquyHfJnWyQ==
#设置Atlas的运行方式,设为true时为守护进程方式,设为false时为前台方式,一般开发调试时设为false,线上运行时设为true
daemon
=
true
#设置Atlas的运行方式,设为true时Atlas会启动两个进程,一个为monitor,一个为worker,monitor在worker意外退出后会自动将其重启,设为false时只有worker,没有monitor,一般开发调试时设为false,线上运行时设为true
keepalive
=
true
#工作线程数,对Atlas的性能有很大影响,可根据情况适当设置
event-threads
=
64
#日志级别,分为message、warning、critical、error、debug五个级别
log-level
=
message
#日志存放的路径
log-path
=
/usr/local/mysql-proxy/log
#SQL日志的开关,可设置为OFF、ON、REALTIME,OFF代表不记录SQL日志,ON代表记录SQL日志,REALTIME代表记录SQL日志且实时写入磁盘,默认为OFF
#sql-log = OFF
#实例名称,用于同一台机器上多个Atlas实例间的区分
#instance = test
#Atlas监听的工作接口IP和端口
proxy-address
=
0.0.0.0:1234
#Atlas监听的管理接口IP和端口
admin-address
=
0.0.0.0:2345
#分表设置,此例中person为库名,mt为表名,id为分表字段,3为子表数量,可设置多项,以逗号分隔,若不分表则不需要设置该项
#tables = person.mt.id.3
#默认字符集,设置该项后客户端不再需要执行SET NAMES语句
#charset = utf8
#允许连接Atlas的客户端的IP,可以是精确IP,也可以是IP段,以逗号分隔,若不设置该项则允许所有IP连接,否则只允许列表中的IP连接
#client-ips = 127.0.0.1, 192.168.1
#Atlas前面挂接的LVS的物理网卡的IP(注意不是虚IP),若有LVS且设置了client-ips则此项必须设置,否则可以不设置
#lvs-ips = 192.168.1.1
|
八、启动关闭重启:
1 2 3 | # /usr/local/mysql-proxy/bin/mysql-proxyd instance start # /usr/local/mysql-proxy/bin/mysql-proxyd instance stop # /usr/local/mysql-proxy/bin/mysql-proxyd instance restart |
九、负载读写分离测试:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
[root@YQD-Intranet-DB-NO2
~]#
mysql -uroot -p***** -h192.168.1.63 -P1234
Welcome
to
the
MySQL
monitor. Commands
end
with
;
or
g.
Your
MySQL
connection
id
is
1295815494
Server
version:
5.0.81-log
Source
distribution
Copyright
(c)
2009-2013
Percona
LLC
and/or
its
affiliates
Copyright
(c)
2000,
2013,
Oracle
and/or
its
affiliates.
All
rights
reserved.
Oracle
is
a
registered
trademark
of
Oracle
Corporation
and/or
its
affiliates.
Other
names
may
be
trademarks
of
their
respective
owners.
Type
'help;'
or
'h'
for
help.
Type
'c'
to
clear
the
current
input
statement.
root@(none)
10:28:46>show
variables
like
"server_id";
+---------------+-------+
|
Variable_name
|
Value
|
+---------------+-------+
|
server_id
|
3
|
+---------------+-------+
1
row
in
set
(0.00
sec)
root@(none)
10:28:48>show
variables
like
"server_id";
+---------------+-------+
|
Variable_name
|
Value
|
+---------------+-------+
|
server_id
|
2
|
+---------------+-------+
1
row
in
set
(0.00
sec)
开启sql日志,日志显示如下:
[06/27/2014
10:36:56]
C:192.168.1.228:50179
S:192.168.1.244:3306
OK
0.419
"SHOW CREATE TABLE `t_categary`"
[06/27/2014
10:36:56]
C:192.168.1.228:50180
S:192.168.1.64:3306
OK
0.739
"SELECT * FROM `t_categary` LIMIT 0, 1000"
[06/27/2014
10:36:56]
C:192.168.1.228:50180
S:192.168.1.244:3306
OK
0.724
"SHOW COLUMNS FROM `cat_db`.`t_categary`"
|
OLTP基准测试:
OLTP基准测试模拟了一个简单的的事务处理系统的工作负载。下面的例子使用的是一张百万行记录的表,第一步先生成这张表:
1 2 3 4 5 6 7 8 9 | # time sysbench --test=oltp --db-driver=mysql --mysql-engine-trx=yes --mysql-table-engine=innodb --mysql-host=127.0.0.1 --mysql-port=1234 --mysql-user=root --mysql-password=****** --oltp-table-size=1000000 prepare sysbench 0.4.12: multi-threaded system evaluation benchmark Creating table 'sbtest'... Creating 1000000 records in table 'sbtest'... real 0m58.132s user 0m0.209s sys 0m0.036s |
接下来可以运行测试,这个例子采用了16个并发线程,只读模拟测试:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
# time sysbench --test=oltp --db-driver=mysql --mysql-engine-trx=yes
--mysql-table-engine=innodb --mysql-host=127.0.0.1 --mysql-port=1234 --oltp-read-only=on --mysql-user=root --mysql-password=****** --oltp-table-size=1000000 --num-threads=16 run
sysbench
0.4.12: multi-threaded
system
evaluation
benchmark
Running
the
test
with
following
options:
Number
of
threads:
16
Doing
OLTP
test.
Running
mixed
OLTP
test
Doing
read-only
test
Using
Special
distribution
(12
iterations, 1
pct
of
values
are
returned
in
75
pct
cases)
Using
"BEGIN"
for
starting
transactions
Using
auto_inc
on
the
id
column
Maximum
number
of
requests
for
OLTP
test
is
limited
to
10000
Threads
started!
Done.
OLTP
test
statistics:
queries
performed:
read: 140000
write:
0
other:
20000
total:
160000
transactions: 10000 (1007.89
per
sec.)
deadlocks:
0 (0.00
per
sec.)
read/write
requests:
140000
(14110.48
per
sec.)
other
operations: 20000 (2015.78
per
sec.)
Test
execution
summary:
total
time: 9.9217s
total
number
of
events: 10000
total
time
taken
by
event
execution:
158.5972
per-request
statistics:
min:
10.86ms
avg:
15.86ms
max:
25.08ms
approx. 95
percentile: 18.51ms
Threads
fairness:
events
(avg/stddev):
625.0000/4.08
execution
time
(avg/stddev):
9.9123/0.00
real
0m10.198s
user
0m1.216s
sys
0m2.583s
|
从时间上来看比之前haproxy测试要略慢,还是haproxy的性能更靠谱,但是haproxy需要在应用层实现读写分离,就是代码了
tpcc压测:
1 2 3 4 5 6 7 8 9 10 | root@(none) 10:46:19>create database tpcc5; Query OK, 1 row affected (0.54 sec) # mysql -uroot -p******* -h192.168.1.63 -P1234 tpcc5 < create_table.sql Warning: Using a password on the command line interface can be insecure. ERROR 1231 (42000) at line 140: Variable 'foreign_key_checks' can't be set to the value of 'NULL' # mysql -uroot -p******* -h192.168.1.63 -P1234 tpcc5 < add_fkey_idx.sql Warning: Using a password on the command line interface can be insecure. ERROR 1231 (42000) at line 23: Variable 'foreign_key_checks' can't be set to the value of 'NULL' |
tpcc导入表时出错了,提示变量foreign_key_checks不能设置为NULL值,暂且不管它,继续测试:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
# ./tpcc_load 192.168.1.63:1234 tpcc5 root "********" 3
*************************************
***
###easy### TPC-C Data Loader ***
*************************************
<Parameters>
[server]:
192.168.1.63
[port]:
1234
[DBname]:
tpcc5
[user]:
root
[pass]:
LVS@071103
[warehouse]:
3
TPCC
Data
Load
Started...
Loading
Item
..................................................
5000
..................................................
10000
..................................................
15000
..................................................
20000
..................................................
25000
..................................................
30000
..................................................
35000
..................................................
40000
..................................................
45000
..................................................
50000
下面省略N行.......................................
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
# ./tpcc_start -h192.168.1.63 -P1234 -dtpcc5 -uroot -p******** -w3
-c32 -r10 -l600
***************************************
***
###easy### TPC-C Load Generator ***
***************************************
中间省略N行.................................................
<Raw
Results>
[0]
sc:5059 lt:0 rt:0 fl:0
[1]
sc:5057 lt:0 rt:0 fl:0
[2]
sc:506 lt:0 rt:0 fl:0
[3]
sc:506 lt:0 rt:0 fl:0
[4]
sc:506 lt:0 rt:0 fl:0
in
600
sec.
<Raw
Results2(sum
ver.)>
[0]
sc:5059 lt:0 rt:0 fl:0
[1]
sc:5059 lt:0 rt:0 fl:0
[2]
sc:506 lt:0 rt:0 fl:0
[3]
sc:506 lt:0 rt:0 fl:0
[4]
sc:506 lt:0 rt:0 fl:0
<Constraint
Check>
(all
must
be
[OK])
[transaction
percentage]
Payment:
43.47%
(>=43.0%)
[OK]
Order-Status:
4.35%
(>=
4.0%)
[OK]
Delivery:
4.35%
(>=
4.0%)
[OK]
Stock-Level:
4.35%
(>=
4.0%)
[OK]
[response
time
(at
least
90%
passed)]
New-Order:
100.00% [OK]
Payment:
100.00% [OK]
Order-Status:
100.00% [OK]
Delivery:
100.00% [OK]
Stock-Level:
100.00% [OK]
<TpmC>
505.900
TpmC
|
经过一段时间的使用,发现atlas目前是比较稳定的,但是性能不作过多评价!有时面面俱到真是难!多一层代理,性能肯定会下降,如果程序端能实现读写分离,直连集群或主备,那样的性能应该是最好的。