一、簡介
Atlas是由 Qihoo 360公司Web平臺部基礎架構團隊開發維護的一個基於MySQL協議的資料中間層專案。它在MySQL官方推出的MySQL-Proxy 0.8.2版本的基礎上,修改了大量bug,新增了很多功能特性。目前該專案在360公司內部得到了廣泛應用,很多MySQL業務已經接入了Atlas平臺,每天承載的讀寫請求數達幾十億條。
主要功能:
| 1.讀寫分離 2.從庫負載均衡 3.IP過濾 4.自動分表 5.DBA可平滑上下線DB 6.自動摘除當機的DB |
二、Atlas相對於官方MySQL-Proxy的優勢
|
1.將主流程中所有Lua程式碼用C重寫,Lua僅用於管理介面
2.重寫網路模型、執行緒模型
3.實現了真正意義上的連線池
4.優化了鎖機制,效能提高數十倍
|
三、Atlas詳細說明
| 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
|
八、啟動關閉重啟:
| # /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基準測試模擬了一個簡單的的事務處理系統的工作負載。下面的例子使用的是一張百萬行記錄的表,第一步先生成這張表:
| # 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壓測:
| 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目前是比較穩定的,但是效能不作過多評價!有時面面俱到真是難!多一層代理,效能肯定會下降,如果程式端能實現讀寫分離,直連叢集或主備,那樣的效能應該是最好的。
[參考資料]採用Atlas+Keepalived實現MySQL讀寫分離、讀負載均衡 - http://sofar.blog.51cto.com/353572/1601552/