網際網路金融公司在分散式資料庫的運維實踐
講師介紹
賀春暘,《MySQL 管理之道:效能調優、高可用與監控》第一、二版一書作者,從事資料庫管理工作多年,曾經任職於中國移動飛信,安卓機鋒網,凡普金科(愛錢進),致力於MariaDB、MongoDB等開源技術的研究,主要負責資料庫效能調優、監控和架構設計。
大家好,我是2015年7月份入職凡普金科(原普惠金融)愛錢進,公司核心資料庫在我入職第二週,從最原始的MySQL 5.5.30社群版全部升級到MariaDB 10.0.21企業版,隨後面的機房遷移,版本再次升級為MariaDB 10.0.30企業版。
為什麼選擇了MariaDB?
告別MySQL移步MariaDB的原因
在MariaDB 5.3版本里,就已經對子查詢進行了優化,並採用semi join半連線方式將SQL改寫為了表關聯join,從而提高了查詢速度。
通常情況下,我們希望由內到外,即先完成內表裡的查詢結果,然後驅動外查詢的表,完成最終查詢,但是MySQL 5.5會先掃描外表中的所有資料,每條資料將會傳到內表中與之關聯,如果外表很大的話,那麼效能上將會很差。
案例:MySQL 5.5的子查詢執行計劃,是將in重寫為exists
我們看一下這兩個執行計劃,當外表比較大時,第一行會掃描5000071行,改為exists寫法,它的執行計劃和in是完全一樣的。如果你外表比較大的話,查詢效能會是非常差的。
案例:MariaDB 10.0的子查詢執行計劃,是將in/exists重寫為join
MariaDB 10.0相當於MySQL5.6版本,這裡In和exists,它會直接重寫為join關聯查詢,這裡有三個不同的寫法,執行計劃是完全一樣的。改寫join以後是由小表關聯大表,可以看下掃描的行數為10行,執行效率就是非常快的。
2、由於資料量上TB,直接升級MySQL5.6,不能平滑升級,需要進行一次mysqldump再匯入,耗費過多的時間。
以MySQL5.5版本為例,若要升級到MySQL5.6,需要進行一次全庫mysqldump匯出再匯入,當資料庫很大時,比如100GB,升級起來會非常困難。但如果升級為MariaDB10,會非常輕鬆,按照官方文件闡述,只需把MySQL解除安裝掉,並用MariaDB啟動,然後通過mysql_upgrade命令升級即可完成。
MariaDB跟MySQL在絕大多數方面是相容的,對於前端應用(比如PHP、Perl、Python、Java、.NET、MyODBC、Ruby、MySQL C connector)來說,幾乎感覺不到任何不同。
升級到MariaDB10注意事項
在處理內部的臨時表,MariaDB 5.5/10.0用Aria引擎代替了MyISAM引擎,這將使某些GROUP BY和DISTINCT請求速度更快,因為Aria有比MyISAM更好的快取機制。如果你的臨時表很多的話,要增加aria_pagecache_buffer_size引數的值(快取資料和索引),預設是128MB( 而不是tmp_table_size 引數)。如果你沒有MyISAM表的話,建議把key_buffer_size調低,例如64KB,僅僅提供給MySQL庫裡面的系統表使用。
官方推薦使用jemalloc記憶體管理器獲取更好的效能。
Jemalloc記憶體管理器效能
上圖是官方的壓力測試報告,可以看出Jemalloc記憶體管理器的效能是最好的。
這是之前我給MariaDB作者寫的一封信,他回答,升級到MariaDB是沒有問題的,現在很多大公司都用MariaDB,例如Google、Wikipedia。主要原因我總結如下:
在Oracle控制下的MySQL有兩個問題:
-
MySQL核心開發團隊是封閉的,完全沒有Oracle之外的成員參加。很多高手即使有心做貢獻,也沒辦法做到。
-
MySQL新版本的釋出速度,在Oracle收購Sun之後大為減緩。
這裡再說一下MariaDB企業版和社群版的區別:
企業版更注重bug的修復,社群版則對新功能更新比較快。MariaDB社群版和企業版的原始碼都是開源的,並且所有功能都是免費開放,不用擔心功能上有閹割,但甲骨文MySQL企業版延伸套件採取封閉原始碼且需要付費。
此外,MariaDB相比MySQL擁有更多的功能、更快、更穩定、BUG修復更快。
3、解決複製延遲,開啟多執行緒並行複製(MariaDB 10.0.X基於表)
金融公司對資料一致性要求較高,主從同步延遲問題是不能接受的。MySQL5.6由於是基於庫級別的並行複製,在實際生產中用處並不大,而只有5.7才支援基於表的並行複製。MariaDB的並行複製有兩種實現模式:
-
第一種:Conservative mode of in-order parallel replication(保守模式的順序並行複製)
MariaDB 10 通過基於表的多執行緒並行複製技術,如果主庫上1秒內有10個事務,那麼合併一個IO提交一次,並在binlog裡增加一個cid = XX 標記,當cid的值是一樣的話,Slave就可以進行並行複製,通過設定多個sql_thread執行緒實現。
上述cid為630的事務有2個,表示組提交時提交了2個事務,假如設定slave_parallel_threads =24(並行複製執行緒數,根據CPU核數設定),那麼這2個事務在slave從庫上通過24個sql_thread執行緒進行並行恢復。只有那些被自動確認為不會引起衝突的事務才會被並行執行,以確保從庫上事務提交和主庫上事務提交順序一致。這些操作完全是透明的,無須DBA干涉。
如果想控制binlog組提交數量,可以通過下圖兩個引數設定。
第二種模式:Out-of-order parallel replication(無序並行複製)
設定SET SESSION gtid_domain_id=99具有不同gtid_domain_id域識別符可並行複製,生產使用場景通常是用在增加索引、增加欄位上。
實現無序並行複製,需要把GTID開啟才可以實現,執行上圖所示的命令。
多執行緒並行複製—壓力測試
我們可以看到,隨著並行複製執行緒的增加,slave從庫的TPS每秒寫入速度接近主庫。
4、前期公司大資料部門剛起步,未成熟,需要藉助多源複製技術(彙總前面多個業務庫),提供給BI部門、產品PO、金融分析師BA/MA進行分析。
(注:這個功能只有MySQL5.7才有,2015年7月未GA)
適用場景:實現資料分析部門的需求,將多個系統的資料匯聚到一臺伺服器上進行OLAP分析計算。
MariaDB10多源複製的搭建方法如下。
https://mariadb.com/kb/en/mariadb/multi-source-replication/
① 建立通道
SET @@default_master_connection = ${connect_name};
② 建立同步複製
CHANGE MASTER ${connect_name} TO
MASTER_HOST=’192.168.1.10′,MASTER_USER=’repl’,MASTER_PASSWORD=’repl’,MASTER_PORT=3306,MASTER_LOG_FILE==’mysql-bin.000001′,MASTER_LOG_POS=4,MASTER_CONNECT_RETRY=10;
③ 啟動
START SLAVE ${connect_name};
START ALL SLAVES;
④ 停止
STOP SLAVE ${connect_name};
STOP ALL SLAVES;
⑤ 檢視狀態
SHOW SLAVE ${connect_name} STATUS;
SHOW ALL SLAVES STATUS;
⑥ 清空同步資訊和日誌
RESET SLAVE ${connect_name} ALL;
⑦ 重新整理Relay logs
FLUSH RELAY LOGS ${connect_name};
5、MariaDB ColumnStore(InfiniDB 4.6.2)資料倉庫,用於大資料離線分析計算
第五個原因就是資料量逐日增長,在InnoDB裡進行復雜SQL查詢分析是一件非常痛苦的事情,後來我選擇了MariaDB ColumnStore資料倉庫,專為分散式大規模並行處理Massively Parallel Processing(MPP)設計的列式儲存引擎,用它做大資料離線分析OLAP系統,藉助ETL工具canal,實現抽取binlog並解析為原生態SQL檔案入庫到Columnstore裡。
Columnstore技術特性
- 標準SQL協議支援Navicat/SQLyog/WebSQL等客戶端工具
- 資料分散式儲存(本地化)Shard Nothing架構
- 分散式平行計算任務並行執行
- 橫向擴充套件
Columnstore技術架構
- UM模組:SQL協議介面,接收客戶端連線訪問,推送SQL請求給PM效能模組代為執行,最後收集效能模組的處理結果做資料彙總,並返回給客戶端最終查詢結果。
- PM模組:負責資料的列式儲存,處理查詢請求,將資料提取到記憶體中計算。
6、審計日誌Audit Log
網際網路金融公司對資料很敏感,業務從庫提供給開發等人員使用。DBA通過審計日誌記錄他們操作的結果。
安裝審計Audit Plugin外掛:
MariaDB審計日誌引數:
server_audit_events = ‘CONNECT,QUERY,TABLE’
server_audit_logging = ON
server_audit_incl_users = ‘hechunyang’
server_audit_excl_users = ‘sys_pmm,nagios’
server_audit_file_rotate_size = 10G
server_audit_file_rotations = 500
server_audit_file_path = /data/audit/server_audit.log
將審計日誌抽到表裡,用PHP展示出來分析。
本節小結
由於MySQL功能上迭代速度太慢,移步MariaDB後,撐過了業務發展高峰期2015-2016年。
藉助《高效能三》一書的原話:
MariaDB和Percona有什麼不同?
高可用架構當時選型有兩個方案,一個是MHA,一個是PXC,為什麼沒有選擇PXC呢?有以下幾個不可抗力因素:
(1)網路抖動或者機房被ARP攻擊,導致NODE節點失聯,出現了腦裂,怎麼處理?最悲劇的是三份節點都同時寫,而且還沒複製過來,到底以哪份資料為準?
(2)硬碟壞了一塊,導致RAID10效能下降,會導致叢集限流,限流的引數是wsrep_provider_options=gcs.fc_limit:待執行佇列長度超過該值時,flow control被觸發,預設是16。此時正處於促銷活動情形,由於PXC的效能取決於最弱的一個NODE節點,資料庫連線數很容易被打滿,直接掛了。
(3)業務如果有大事務,超過了wsrep_max_ws_rows、wsrep_max_ws_size這兩個值,節點之間無法複製,造成資料不一致,怎麼辦?
由於叢集是樂觀鎖併發控制,事務衝突的情況會在commit階段發生。如果有兩個事務在叢集中不同的節點上對同一行寫入並提交,失敗的節點將回滾,應用端JAVA/PHP返回報錯,直接影響使用者體驗。
可參考Percona之前分享的PPT——巨大的潛力在PXC架構,貌似解決了一致性的問題,但距離成熟還有一段距離。
下圖是Group Replication以及Galera Cluster叢集觸發限流後,效能影響甚大。
在沒有流量控制的情況下,Writer會在有限的時間內處理大量行(來自8個客戶端,8個執行緒,50個併發批量插入)。隨著流量控制,情況急劇變化。Writer需要很長時間才能處理明顯更小的行數/秒。總之,效能顯著下降。
(4)最主要的因素——效能問題
由於PXC/MariaDB Galera Cluster自身不支援VIP功能,MariaDB的解決方案是用MaxScale做七層負載均衡Proxy,由於本身效能就不如主從複製,再過一層代理,效能就更差。可參考下圖官方的解決方案。
Galera Cluster整體架構圖如下:
信任Percona專業團隊的選擇
生產資料庫HA架構
MHA管理多組叢集(多例項)
我們公司目前為一主帶三從(其中一個從庫是做的延遲複製12小時,用pt-slave-delay工具實現),高可用架構採用開源MHA+半同步複製semi replication。
延遲複製的目的怕萬一開發手抖,或者程式碼寫了一個BUG,或者把一個表給刪了,通過延遲還能回來。
上面是一個監控圖,報錯的就是延時複製從庫。
生產庫MariaDB開啟的引數
-
sync_binlog = 1
-
innodb_flush_log_at_trx_commit = 1
-
innodb_support_xa = 1 (事務的兩階段提交)
MHA架構和MMM架構有什麼區別呢?最大的區別在於:MHA會把丟失的資料,在每個Slave節點上補齊。下面通過一幅圖來了解它的工作原理。
我們可以看到,當master宕機時,MHA管理機會試圖scp丟失的那一部分binlog,然後把該binlog拷貝到最新的slave機器上,補齊差異的binlog並應用。當最新的slave補齊資料後,把它的relay-log拷貝到其他的slave上,識別差異並應用。至此,整個恢復過程結束,從而保證切換後的資料是一致的。
再通過下圖,可以更容易去理解整個恢復過程。
MHA架構注意事項
1、防止網路抖動誤切換,造成資料不一致
其實現原理為:投票機制,當監控管理機無法ping通和無法連線MySQL主庫,會試圖從監控備機上去ping和連線MySQL主庫,只有雙方都連線失敗,才認定MySQL主庫宕機。假如有一方可以連線MySQL主庫,都不會切換。
引數:
secondary_check_script=/usr/local/bin/masterha_secondary_check
-s 192.168.111.76 -s 192.168.111.79 –user=root
–master_host=QCZJ-dbm
–master_ip=192.168.111.77 –master_port=3306
從切換日誌裡看,它先試圖用從庫111.76和111.79,去同時ping 111.77主庫,兩個都ping不通的話,才認定主庫宕機,此時才可以進行故障切換。如果有一個從庫能ping通主庫都不會進行故障切換。
需要留意的地方:由於masterha_secondary_check指令碼寫死了埠,所以要手工修改ssh埠
$ssh_user = “root” unless ($ssh_user);
$ssh_port = 62222 unless ($ssh_port);
$master_port = 3306 unless ($master_port);
2、VIP沒有采用keepalived,就是怕網路抖動問題。
這裡我修改了以下兩個指令碼,自帶VIP,大家可以下載試用。
master_ip_failover_script=/usr/local/bin/master_ip_failover
master_ip_online_change_script=/usr/local/bin/master_ip_online_change
紅色的部分是修改的地方。
——————————————————————————-# Hardcode stuff now until the next MHA release passes SSH info in here
MHA::ManagerUtil::exec_ssh_cmd( $new_master_ip, ‘62222’, “ip addr add 192.168.111.83/32 dev em2;arping -q -c 2 -U -I em2 192.168.111.83”, undef );
——————————————————————————-
資料庫架構演進
隨著網站壯大,資料庫架構一般會經歷如下演進:
為什麼要分庫分表?(效能+儲存擴容)
- 單個庫資料容量太大,單個DB儲存空間不夠
- 單個庫表太多,查詢的時候,開啟表操作也消耗系統資源
- 單個表容量太大,查詢的時候,掃描行數過多,磁碟IO大,查詢緩慢
- 單個庫能承載的訪問量有限,再高的訪問量只能通過分庫分表實現
針對爬蟲業務,併發讀寫頻率很高且對事務要求性不高,沒有聯表關聯查詢,那麼就不需要考慮放入MySQL裡,直接存入NOSQL——MongoDB裡更適合。
利用MongoDB自身的Auto-Sharding分片技術實現,通過這種技術可以使我們非常方便的擴充套件資料,從而不用讓開發更改一行程式碼即可輕鬆實現資料拆分。
我們這裡做了分散式,叢集總共是9臺機器分兩組Shard,兩個Shard組來做的。通過這個自動分片,解決了開發不用改變原始碼了,減少日常工作。
片鍵的選擇
Hash based partitioning可以確保資料平均分佈,但是這樣會導致經過雜湊處理的值在各個資料塊和shard上隨機分佈,進而使制定的範圍查詢range query不能定位到某些shard而是在每個shard上進行遍歷查詢。鑑於業務的實際情況,沒有範圍查詢,我們是以userId(查詢最頻繁的)欄位做的Hash拆分。
再說說片鍵的注意事項。
- 第一,在對文件個別欄位update時,如果query部分沒有帶上shard key,效能會很差,因為mongos需要把這條update語句派發給所有的shard 例項,跨多個網路效能就會下降。
- 第二,當update 的upsert引數為true時,query部分必須帶上 shard key,否則語句執行出錯。例:db.t1.update({},{cid:7,name:”D”},{upsert:1})
- 第三,shard key的值不能被更改。
最後再說一下資料均衡Balance注意事項。
內部分裂並自動balance,一旦發生資料遷移會造成整個系統的吞吐量急劇下降。為了應對Sharding遷移的不確定性,我們可以強制指定Sharding遷移的時間點,具體遷移時間點依據業務訪問的低峰期。
我們的流量低峰期是在凌晨1點到6點,那麼我們可以在這段時間內設定視窗期開啟Sharding遷移功能,允許資料的遷移,其他的時間不進行資料的遷移,從而做到對Sharding遷移的完全掌控,避免掉未知時間Sharding遷移帶來的一些風險。
設定視窗期命令:
use config
db.settings.update({ _id : “balancer” }, { $set : { activeWindow : { start : “1:00”, stop : “6:00” } } }, true )
資料均衡Balance監控圖–Percona PMM
觀察getmore黃顏色曲線,1:00-6:00點時間段正是做資料遷移。
如果不設定視窗期,以我們7200轉的sas硬碟,在早高峰做資料遷移,定將影響業務穩定。
爬蟲整體入庫架構圖
新增資料先寫入資料庫WiredTiger裡,然後馬上更新到In-Memory引擎(inMemorySizeGB = 180G),讀取時優先在In-Memory記憶體中讀取,如果資料不在則從後端WiredTiger裡取數。In-Memory中的熱資料失效時間為一天,等待下次讀取時再載入。
快取失效時間設定
在建立索引時,需要指定過期時間,參考畫紅色線部分,過期後集合裡的這個文件就會自動刪除。這裡有一個注意事項就是:欄位必須是時間型別的。
寫關注(Write Concern)
1、 MongoDB預設為非同步複製,本地寫完後即返回客戶端請求。
2、可以通過驅動設定為:
<?php
// Setting w=majority for update:
$collection->update($someDoc, $someUpdates, array(“w” =>
“majority”,”j” => true));
?>
意思為同步複製機制,主庫資料寫入記憶體後,還要確保Journal重做日誌刷入磁碟,並保證已複製到從節點後,才會返回更新成功,將請求返回給客戶端。
讀寫分離
MongoDB的Java驅動,預設讀寫是在Primary主節點上,如果想讀Secondary從節點,需要通過設定驅動實現。
節點動態擴容&一致性雜湊演算法
節點擴容過程為:資料1、2在節點A上,資料3、4在節點C上。如果增加一個節點B,資料1、2還在A上,只需要把資料3遷到B上,資料4仍在C上,所以只是部分資料遷移,並不是整體資料遷移,這樣避免了雪崩的現象。
延遲複製節點的必要性
原因:
1、開發程式碼有BUG或DBA手抖,一瞬間讓你的業務回到解放前
2、過TB資料備份恢復問題
MariaDB 10.2才支援延遲複製(MySQL5.6早已支援),固需要藉助Percona PT工具實現
shell > perl /usr/local/bin/pt-slave-delay -S /tmp/mysql.sock –user root
–password 123456 –delay 43200 –log /root/delay.log –daemonize
注:單位秒,43200秒等於12小時
MongoDB 3.2延遲複製實現
Primary > rs.add( { host:
“qianzhan_delay.mongodb.dc.puhuifinance.com:27017”, priority:0,hidden:1,slaveDelay:43200,votes:0 } )
注:
- priority權重設定為0,永遠不能切為Primary
- hidden設定為隱藏節點
- slaveDelay延遲時間,單位秒,43200秒等於12小時
- votes取消投票資格
用Percona MongoDB替換原生版——熱備份功能
Percona MongoDB3.2版本預設支援WiredTiger引擎的線上熱備份,解決了官方版只能通過mongodump邏輯備份這一缺陷。恢復很簡單,把備份目錄裡的資料檔案直接拷貝到你的dbpath下,然後啟動MongoDB即可。
參考文獻:
https://www.percona.com/doc/percona-server-for-mongodb/LATEST/hot-backup.html#hot-backup
注:Percona server Mongodb 3.2.10有一個bug
directoryperdb = true
wiredTigerDirectoryForIndexes = true
這兩個引數必須登出掉,否則備份失敗。
這是我提交的bug地址,https://jira.percona.com/browse/PSMDB-123
Percona採納了該bug,並在3.2.12版本里修復。
https://www.percona.com/doc/percona-server-for-mongodb/3.2/release_notes/3.2.12-3.2.html
Percona MongoDB3.2 HotBackup Perl Scripts
使用說明:請在本地admin資料庫,以管理員身份執行createBackup命令,並指定備份目錄。
自動備份指令碼
# perl -MCPAN -e “install MongoDB”
#!/usr/bin/perl
use MongoDB; use File::Path; use POSIX qw(strftime); my $mc = MongoDB::MongoClient->new( host => “mongodb://localhost:37019/”, username => “admin”, password => “123456”, ); my $db = $mc->get_database(“admin”); $year = strftime “%Y”,localtime; $month = strftime “%m”,localtime; $time = strftime “%Y-%m-%d-%H-%M-%S”, localtime; $BAKDB = “yourdb”; $BAKDIR = “/data/bak/hcy/$year/$month/$BAKDB_$time”; my $user = getpwnam “mongodb” or die “bad user”; my $group = getgrnam “mongodb” or die “bad group”; mkpath($BAKDIR) or die “目錄已存在. $!”; chown $user, $group, $BAKDIR; my $cmd = [ createBackup => 1, backupDir => $BAKDIR ]; $db->run_command($cmd); if($! == 0){ print “backup is success.”; }else{ print “backup is failure.”; } |
MongoDB 慢查詢郵件報警並自動KILL Perl Scripts
通過檢視當前操作db.currentOp(),大於指定執行時間,發郵件報警,並通過db.killOp(opid)殺掉程序。
Oplog蓋子集合(Capped Collections)注意事項(可以理解為MySQL Binlog)
預設剩餘空間的5%
當你搭建副本集的時候,一定要把Oplog設定得比較大,預設是剩餘磁碟空間的5%,我們線上設定為100G。Oplog跟binlog儲存方式不太一樣,binlog是寫滿一個檔案會再生成一個新的檔案繼續寫,而Oplog則是覆蓋寫。我們看上圖,從庫掛掉以後再次加入叢集時,它會先發送一個位置點給主庫,比如現在傳送一個位置點是27,主庫有的話會把27之後的資料推過來。如主庫沒有會告知從庫我這裡沒有找到,從庫會把本地資料全部刪除,從主庫上全量抽資料,學名為initial sync。
神器!MongoDB語法線上生成器
http://www.querymongo.com/可以將SQL語法轉換成MongoDB語法,例子:
MySQL 分庫分表中介軟體選擇
https://mariadb.com/kb/en/mariadb/spider-storage-engine-overview/
Spider是MariaDB內建的一個可插拔用於MariaDB/MySQL資料庫分片的儲存引擎,充當應用伺服器和遠端後端DB之間的代理(中介軟體),它可以輕鬆實現MySQL的橫向和縱向擴充套件,突破單臺MySQL的限制,支援範圍分割槽、列表分割槽、雜湊分割槽,支援XA分散式事務,支援跨庫join。通過Spider,您可以跨多個數據庫後端有效訪問資料,讓您的應用程式一行程式碼不改,即可輕鬆實現分庫分表!
- 開發無需調整程式碼,應用層跟訪問單機MySQL一樣。
- DBA部署簡單,由於MariaDB10 預設已經捆綁了Spider引擎,無需編譯安裝。
- 支援標準SQL語法,儲存過程,函式,跨庫Join,沒有Atlas那麼多的限制。
- 後端DB可以是任一版本,MySQL/MariaDB/Percona
- 無維護成本
- 生產成熟案例-騰訊公司
這個是它的整體的架構圖, 應用程式連線Spider,Spider充當中介軟體代理,將客戶端查詢的請求,按照事先定義好的分片規則,分發給後端資料庫,之後返回的資料彙總在Spider記憶體裡做聚合,最終返回客戶端請求,對於應用程式而言是透明的。
效能壓力測試sysbench
在我的壓測結果上,分表的效能會降低70%,垂直拆分效能會降低40%,效能損耗的原因是在分散式場景下,要保證2PC一致性和可用性讀寫的表現就差,另外就是跨多個網路傳輸這兩方面引起的。
在生產環境中,我通過Spider實現了表的垂直拆分,沒有做分庫分表。
使用場景介紹
(架構圖)
1、交易流水錶我是半年一切表,老表改名,再創新一張新表,然後通知開發手工改程式碼裡的SQL,用union all的方式關聯查詢。如:select * from t1 where apply_no = ‘XXXX’ union all select * from t1_20170630 where apply_no = ‘XXXX’
2、由於歷史表沒有寫操作,只有使用者的查詢,且查詢頻率並不是很高,將歷史表移到備份機,再通過spider做一個對映(軟連線)實現表的垂直拆分,解決磁碟空間擴充套件問題。
3、實施這個方案,選擇Spider引擎是有優勢的:
SQL解析和查詢優化是個非常複雜且很難做好的工作,其它替代產品都是自己實現,由於複雜性,這些產品都帶來了一些限制,比如不支援儲存過程、函式、檢視等,給使用和實施帶來了困難。而作為一個儲存引擎,這些工作都由MariaDB自身完成了,可以方便地將大表做分散式拆分,它的好處是對業務方使用是透明的,SQL語法沒有任何限制,在不改變現有DB架構的方案中,侵入性最小。
提升效能的關鍵
optimizer_switch= ‘engine_condition_pushdown=on’
引擎下推,查詢推送到後端資料庫,將查詢結果返回給Spider做聚合,類似Map-Reduce。早期的版本是從後端拉取所需的資料到本地臨時表,然後再做處理。
Spider引擎安裝
shell > mysql -uroot -p < /usr/local/mysql/share/install_spider.sql
SELECT engine, support, transactions, xa FROM
information_schema.engines;
Spider引擎使用
定義後端伺服器和資料庫名字
這個是定義後端伺服器和資料庫名字。這裡後端伺服器的名字為backend1,資料庫名字為test,主機IP地址為192.168.143.205,使用者名稱為user_readonly,密碼為123456,埠為3306。
注:如配置錯誤,可直接DROP SERVER backend1; 重新建立即可。
垂直拆分(對映、軟連線)
這個是定義垂直拆分,也就是對映和軟連線,做一個超連結。Spider自身不儲存資料,只儲存路由資訊。這裡通過設定COMMENT註釋來呼叫後端的表,然後你就可以檢視sbtest表了,是不是很簡單?
MariaDB 10.3& Spider GA
參考https://mariadb.org/embrace-community-fly-open-source-dream/
監控慢SQL—Percona Query Analytics
慢查詢監控也是用的是Percona來做,這裡是集成了視覺化平臺。
MySQL 慢查詢郵件報警並自動KILL
(Percona PT-kill精簡版)
多增加發送kill掉後的慢SQL郵件報警功能
注:官方原版預設被kill掉的SQL不會發郵件出來,這會造成不能及時通知開發,對排查問題帶來困惑。
下一代關係型資料庫NewSQL
最後說一下下一代關係型資料庫NewSQL:CockroachDB和TiDB。
CockroachDB是一個分散式SQL資料庫。其主要設計目標是擴充套件性、強一致性和生存性(CockroachDB蟑螂資料庫由此得名)。 CockroachDB的目標是容忍磁碟、機器、機架,甚至資料中心故障,在無需人工干預的情況下,最小化這些延遲中斷的影響。 CockroachDB各節點是對等的,設計目標是同質化部署(一個二進位制包),最小化配置,也不需要外部依賴項。CockroachDB叢集中的每個節點都可以扮演一個客戶端SQL閘道器角色,SQL閘道器將客戶端SQL語句轉換成KV操作,分發到所需的節點執行並返回結果給客戶端。其設計靈感,來自谷歌Spanner和F1論文。
https://github.com/cockroachdb/cockroach
https://www.cockroachlabs.com/docs/stable/
區別
TiDB的SQL解析協議是基於MySQL,而CockroachDB是基於PostgreSQL。
內部架構體系
CockroachDB採用分層架構,其最高抽像層為SQL層,CockroachDB直接通過SQL層提供熟悉的關係概念, 如:模式schema、表table、列column和索引index, 接下來SQL層依賴於分散式KV儲存,該儲存管理range處理的細節以提供一個單一全域性KV儲存的抽象。分散式KV儲存與任意數量的CockroachDB物理節點通訊,每個物理節點包含一個或者多個儲存。
特點
- 在原有NoSQL資料庫(Facebook RocksDB)基礎上,增加了分散式事務,解決了資料強一致性。
- 支援傳統SQL語法,封裝了一層PostgreSQL協議。
- 採用MongoDB的Raft協議做故障切換(大多數投票機制),預設3個節點掛1個節點不影響業務讀寫。
- 節點動態熱擴容,節點間的資料自動遷移。
- 內部自動分裂資料塊(達到64M),自動balance均衡(資料遷移)。
- 全同步機制(強一致性),資料寫入必須至少2個副本(預設3個副本)落地,客戶端才可以返回提交成功請求。
- 任意一個節點支援讀寫操作。
使用場景
這個是Percona之前在這個文章裡做的評測
效能上,不及MySQL,生產環境主庫替代MySQL為時尚早,其工業品質和MySQL尚有差距。
Both CockroachDB and TiDB, at the moment of this writing, still have rough edges and can’t be used in serious deployments (from my experience). I expect both projects will makea big progress in 2017.
譯:不能用於嚴重部署(根據我的經驗),我預計這兩個專案將在2017年取得重大進展。
- 不能用於OLAP 和重度資料分析
- JOIN關聯查詢效能較差
- 比較適合的場景,就是訂單歷史流水錶,物流歷史表,論壇帖子歷史表這種,低併發簡單SQL讀寫,通過CockroachDB自動擴容
我們公司現在把歷史表匯入到CockroachDB裡面,配合大資料部門,讓他們從這裡直接抽資料。
效能差的原因
- 一個是全同步機制,強一致性,資料至少寫入兩個節點才可以。
- 第二就是預設序列化,事務只能一個一個執行,不能並行執行。
- 第三分散式事務提交,需要跨多個網路,網路IO開銷大。
The long transactions (let’s say changing 100000 or more rows) also will
be problematic. There is just too much network round-trips and
housekeeping work on each node, making long transactions an issue for
distributed systems.
譯:大事務(例如更改10萬行或更多)也是有問題的。每個節點都有太多的網路往返,使得長時間的大事務成為分散式系統的一個瓶頸。
預設三個副本,每個節點都可以讀寫:
運維部署
引數解釋:
- –cache為記憶體快取的資料,通常為實體記憶體的70%
- –join為加入群集節點
部署非常簡單,只需要新增節點,資料會自動遷移擴容。
CockroachDB客戶端 Postico for Mac
命令列工具
# psql -h 192.168.1.1 -U dev -p 26257 –password
自帶監控 http://192.168.155.46:8080
這個是自帶的監控平臺,可以看到執行情況。
從MySQL遷移歷史資料到CockroachDB
- 不支援COMMENT註釋,需登出掉。
- AUTO_INCREMENT PRIMARY KEY主鍵自增,需改成SERIAL
- int(11)改為int,沒有tinyint,用smallint代替
- 不支援double,用decimal代替
- 不支援`反引號,需登出掉
- 建立表結構時,不支援寫二級索引,需要單獨用命令建立
- 預設UTF-8字符集
- timestamp預設UTC格林威治時間
更多請參考https://www.cockroachlabs.com/docs/stable/data-types.html
1、匯出MySQL表結構
# mysqldump –xml –compact test t1 > t1_schema.sql
2、轉成PostgreSQL表結構
# php convertor.php -i t1_schema.sql -o t1_schema.sql.pg
https://github.com/mihailShumilov/mysql2postgresql
3、匯出MySQL資料
# mysqldump –single-transaction –compact
–default-character-set=utf8 –set-charset -c -t -q –extended-insert
-uroot -p123456 –compatible=postgresql test t1 > t1.sql
4、如果SQL檔案裡有轉義符,需要進行一次格式化,PostgreSQL在反斜槓轉義符之前需要新增’E’字首。
# sed -i “s/,’/,e’/g” t1.sql
匯入到CockroachDB裡
# psql -h 192.168.155.249 -U root -p 26257 -d test < t1.sql
開啟慢查詢
# 定義慢SQL執行時間
> SET CLUSTER SETTING sql.trace.txn.enable_threshold = ‘1s’;
# 開啟慢日誌記錄
> SET CLUSTER SETTING sql.trace.log_statement_execute = true;
效果如下:
1.1新版本特性
1、支援檢視SQL執行狀態,類似MySQL show processlist命令
2、支援kill 慢SQL執行緒id,類似MySQL kill thread_id
執行時間超過10秒的select查詢全部幹掉
CANCEL QUERY (SELECT query_id FROM [SHOW CLUSTER QUERIES] WHERE start < (now() – INTERVAL ’10 seconds’) AND query ~* ‘select’);
開發手冊
1、下載PostgrepSQL驅動
https://jdbc.postgresql.org/
2、連線CockroachDB範例For JDBC
這就是我今天講的三個資料庫,謝謝大家!
原文來自微信公眾號:DBAplus社群