1. 程式人生 > >網際網路金融公司在分散式資料庫的運維實踐

網際網路金融公司在分散式資料庫的運維實踐

網際網路金融

講師介紹

賀春暘,《MySQL 管理之道:效能調優、高可用與監控》第一、二版一書作者,從事資料庫管理工作多年,曾經任職於中國移動飛信,安卓機鋒網,凡普金科(愛錢進),致力於MariaDB、MongoDB等開源技術的研究,主要負責資料庫效能調優、監控和架構設計。

大家好,我是2015年7月份入職凡普金科(原普惠金融)愛錢進,公司核心資料庫在我入職第二週,從最原始的MySQL 5.5.30社群版全部升級到MariaDB 10.0.21企業版,隨後面的機房遷移,版本再次升級為MariaDB 10.0.30企業版。

為什麼選擇了MariaDB?

告別MySQL移步MariaDB的原因

1、 業務上子查詢SQL過多,需要大量改寫為join關聯查詢語句,開發需要
更改程式碼

在MariaDB 5.3版本里,就已經對子查詢進行了優化,並採用semi join半連線方式將SQL改寫為了表關聯join,從而提高了查詢速度。

通常情況下,我們希望由內到外,即先完成內表裡的查詢結果,然後驅動外查詢的表,完成最終查詢,但是MySQL 5.5會先掃描外表中的所有資料,每條資料將會傳到內表中與之關聯,如果外表很大的話,那麼效能上將會很差。

MariaDB

案例: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再匯入,耗費過多的時間。

MySQL

以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

在處理內部的臨時表,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記憶體管理器效能

上圖是官方的壓力測試報告,可以看出Jemalloc記憶體管理器的效能是最好的。

這是之前我給MariaDB作者寫的一封信,他回答,升級到MariaDB是沒有問題的,現在很多大公司都用MariaDB,例如Google、Wikipedia。主要原因我總結如下:

在Oracle控制下的MySQL有兩個問題:

  1. MySQL核心開發團隊是封閉的,完全沒有Oracle之外的成員參加。很多高手即使有心做貢獻,也沒辦法做到。

  2. 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執行緒實現。

Slave

上述cid為630的事務有2個,表示組提交時提交了2個事務,假如設定slave_parallel_threads =24(並行複製執行緒數,根據CPU核數設定),那麼這2個事務在slave從庫上通過24個sql_thread執行緒進行並行恢復。只有那些被自動確認為不會引起衝突的事務才會被並行執行,以確保從庫上事務提交和主庫上事務提交順序一致。這些操作完全是透明的,無須DBA干涉。

如果想控制binlog組提交數量,可以通過下圖兩個引數設定。

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技術架構

Columnstore技術架構

  • UM模組:SQL協議介面,接收客戶端連線訪問,推送SQL請求給PM效能模組代為執行,最後收集效能模組的處理結果做資料彙總,並返回給客戶端最終查詢結果。
  • PM模組:負責資料的列式儲存,處理查詢請求,將資料提取到記憶體中計算。

6、審計日誌Audit Log

網際網路金融公司對資料很敏感,業務從庫提供給開發等人員使用。DBA通過審計日誌記錄他們操作的結果。

安裝審計Audit Plugin外掛:

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展示出來分析。

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整體架構圖如下:

Galera Cluster

信任Percona專業團隊的選擇

生產資料庫HA架構

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節點上補齊。下面通過一幅圖來了解它的工作原理。

MHA架構

我們可以看到,當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 );

——————————————————————————-

資料庫架構演進

隨著網站壯大,資料庫架構一般會經歷如下演進:

資料庫架構

為什麼要分庫分表?(效能+儲存擴容)

  1. 單個庫資料容量太大,單個DB儲存空間不夠
  2. 單個庫表太多,查詢的時候,開啟表操作也消耗系統資源
  3. 單個表容量太大,查詢的時候,掃描行數過多,磁碟IO大,查詢緩慢
  4. 單個庫能承載的訪問量有限,再高的訪問量只能通過分庫分表實現

針對爬蟲業務,併發讀寫頻率很高且對事務要求性不高,沒有聯表關聯查詢,那麼就不需要考慮放入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

MongoDB

通過檢視當前操作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 分庫分表中介軟體選擇

MariaDB Spider分庫分表儲存引擎

https://mariadb.com/kb/en/mariadb/spider-storage-engine-overview/

MySQL

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物理節點通訊,每個物理節點包含一個或者多個儲存。

特點

  1. 在原有NoSQL資料庫(Facebook RocksDB)基礎上,增加了分散式事務,解決了資料強一致性。
  2. 支援傳統SQL語法,封裝了一層PostgreSQL協議。
  3. 採用MongoDB的Raft協議做故障切換(大多數投票機制),預設3個節點掛1個節點不影響業務讀寫。
  4. 節點動態熱擴容,節點間的資料自動遷移。
  5. 內部自動分裂資料塊(達到64M),自動balance均衡(資料遷移)。
  6. 全同步機制(強一致性),資料寫入必須至少2個副本(預設3個副本)落地,客戶端才可以返回提交成功請求。
  7. 任意一個節點支援讀寫操作。

使用場景

這個是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年取得重大進展。

  1. 不能用於OLAP 和重度資料分析
  2. JOIN關聯查詢效能較差
  3. 比較適合的場景,就是訂單歷史流水錶,物流歷史表,論壇帖子歷史表這種,低併發簡單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

由於採用PostgreSQL協議,MySQL表結構語法會報錯,需要微調。
  • 不支援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社群