expdp导出表结构_超强技术案例!86万张表迁移的优化历程
本文轉(zhuǎn)載自:華為云社區(qū)
86萬張表遷移的優(yōu)化歷程問題背景:2019年12月份的時(shí)候DRS項(xiàng)目組接到了一個(gè)線上問題:XX客戶將mysql數(shù)據(jù)庫從友商遷移至華為云的時(shí)候性能很慢,而且出現(xiàn)報(bào)錯(cuò)。運(yùn)維同學(xué)定位發(fā)現(xiàn)用戶的某幾個(gè)實(shí)例存在大約2000個(gè)庫,86萬張表,而出錯(cuò)的原因是查詢?cè)磶鞌?shù)據(jù)庫超時(shí)。和開發(fā)同學(xué)聯(lián)系后得到了第一個(gè)解決方案:增大和源庫的socketTimeout值,保證查詢不超時(shí)。然而,運(yùn)維同學(xué)在后續(xù)保障的過程中發(fā)現(xiàn)……01
86萬張表遷移的優(yōu)化歷程
問題背景
2019年12月份的時(shí)候DRS項(xiàng)目組接到了一個(gè)線上問題:XX客戶將mysql數(shù)據(jù)庫從友商遷移至華為云的時(shí)候性能很慢,而且出現(xiàn)報(bào)錯(cuò)。運(yùn)維同學(xué)定位發(fā)現(xiàn)用戶的某幾個(gè)實(shí)例存在大約2000個(gè)庫,86萬張表,而出錯(cuò)的原因是查詢?cè)磶鞌?shù)據(jù)庫超時(shí)。和開發(fā)同學(xué)聯(lián)系后得到了第一個(gè)解決方案:增大和源庫的socketTimeout值,保證查詢不超時(shí)。然而,運(yùn)維同學(xué)在后續(xù)保障的過程中發(fā)現(xiàn)超時(shí)問題得以解決但是性能無法保證,而且容易出現(xiàn)OOM問題。客戶要求在一天內(nèi)要完成割接,然而我們目前的遷移時(shí)間遠(yuǎn)超24個(gè)小時(shí),由于項(xiàng)目的進(jìn)度問題,留給DRS的時(shí)間只剩一個(gè)周末。
02
問題定位過程
問題定位
飯要一口口吃,問題也得一個(gè)個(gè)定位,回到最初的超時(shí)問題,我們首先找到了出現(xiàn)超時(shí)的sql語句:
SELECT?TRIGGER_NAME?FROM?information_schema.TRIGGERS?WHERE?TRIGGER_SCHEMA?=?'****';
這個(gè)sql用于查詢每個(gè)庫下面的所有觸發(fā)器(其他對(duì)象的查詢sql也有這個(gè)問題),我們發(fā)現(xiàn)這個(gè)sql執(zhí)行了超過5分鐘,這個(gè)結(jié)果令我們很意外。因?yàn)槔碚撋隙灾徊樵円粋€(gè)庫下面的所有觸發(fā)器,怎么會(huì)這么慢呢?explain這個(gè)sql我們發(fā)現(xiàn):Extra中表示Scanned all databases!!!這意味著雖然我們只是在查詢一個(gè)庫下面的觸發(fā)器,但是其實(shí)它會(huì)掃描所有庫對(duì)應(yīng)的frm文件。DEBUG了一下mysql的源碼,我們發(fā)現(xiàn)雖然只是查詢了一個(gè)庫下面的trigger,但是由于information_schema.triggers表里面并不是一張物理表,導(dǎo)致每次查詢都會(huì)去打開所有的frm文件,我們知道frm文件是用來存放mysql元數(shù)據(jù)信息的物理文件,對(duì)于用戶這個(gè)表數(shù)量,可想而知這個(gè)會(huì)對(duì)用戶的源庫IO造成多大的影響,即使有buffer pool也扛不住這么多表的緩存。更關(guān)鍵的是,用戶有2000個(gè)庫,也就是說單就查詢trigger這一個(gè)對(duì)象,我們就需要耗費(fèi)2000*5=10000分鐘的時(shí)間,遷移性能可想而知。
優(yōu)化思路
有了上面的結(jié)果,其實(shí)采取的優(yōu)化方式很簡單了。首先,我們根據(jù)對(duì)象的類型來區(qū)分查詢所有對(duì)象的方式,對(duì)于表,我們可以使用逐庫查詢,因?yàn)椴樵儽淼牟僮鞑粫?huì)Scanned all databases;對(duì)于其他對(duì)象,我們使用只查詢一次的sql:
SELECT?TRIGGER_SCHEMA,?TRIGGER_NAME?FROM?information_schema.TRIGGERS?WHERE?TRIGGER_SCHEMA?NOT?in('mysql','information_schema','sys',?'performance_schema');
這樣我們的查詢時(shí)間大大縮短!
然而,現(xiàn)實(shí)是殘酷的,雖然我們縮短了從源庫查詢對(duì)象列表的時(shí)間,但是導(dǎo)出對(duì)象到回放對(duì)象的性能還是不夠出色,不能滿足用戶的12小時(shí)時(shí)間限制,此外偶發(fā)的OOM問題也隨之沒有解決。
03
OOM問題
問題定位
用MAT分析了heap堆存儲(chǔ)后發(fā)現(xiàn),heap里面存在大量的DbSqlData類的對(duì)象,正是大量的這種對(duì)象導(dǎo)致堆內(nèi)存溢出。結(jié)合我們的架構(gòu)可以發(fā)現(xiàn),我們?cè)趯?dǎo)出表結(jié)構(gòu)的時(shí)候會(huì)先把所有對(duì)象結(jié)構(gòu)分類型存儲(chǔ)在ehcache中,然后在讀取的時(shí)候又會(huì)把數(shù)據(jù)按類型導(dǎo)出到內(nèi)存中。針對(duì)用戶的場(chǎng)景,我們可以計(jì)算出(用戶的表結(jié)構(gòu)平均占用堆內(nèi)存4000Byte)86萬張表總共需要3.44G,而我們的永久代內(nèi)存只配置了2G,OOM問題可想而知。
if?[?-z?"$REPLICATOR_HEAP_SIZE"?];?then
??REPLICATOR_HEAP_SIZE="-Xms3072m?-Xmx3072m?-XX:NewRatio=3?-XX:MetaspaceSize=128m?-XX:MaxMetaspaceSize=256m"
fi
優(yōu)化思路
其實(shí)這一切的問題來源都是因?yàn)槲覀儼磳?duì)象類型對(duì)ehcache進(jìn)行存取,這種方式不是流式進(jìn)行的,很有可能發(fā)生OOM問題。因此,解決的思路就是我們按照單個(gè)對(duì)象的粒度進(jìn)行存取,并且使用內(nèi)存控制的方式控制讀到堆內(nèi)的對(duì)象數(shù)目,保證流式結(jié)構(gòu)的回放,如何進(jìn)行流式結(jié)構(gòu)的回放將會(huì)在下面介紹。
04
性能問題
問題定位
為了滿足客戶的遷移時(shí)間需求,我們統(tǒng)計(jì)了各個(gè)階段DRS內(nèi)核的工作時(shí)間,大致分為下面幾個(gè)階段:
這三個(gè)階段的執(zhí)行順序是串行執(zhí)行的,其中查詢對(duì)象列表花了共計(jì)1個(gè)小時(shí),導(dǎo)出對(duì)象結(jié)構(gòu)共計(jì)10個(gè)小時(shí),回放共計(jì)8個(gè)小時(shí),總計(jì)19個(gè)小時(shí)。這個(gè)結(jié)果遠(yuǎn)遠(yuǎn)超出了客戶的預(yù)期,為了解決這個(gè)問題,我們對(duì)整個(gè)遷移流程進(jìn)行了重新梳理,發(fā)現(xiàn)有以下2個(gè)改進(jìn)點(diǎn):
1.查詢對(duì)象列表的同時(shí)可以將已查詢對(duì)象列表的結(jié)構(gòu)導(dǎo)出2.導(dǎo)出對(duì)象結(jié)構(gòu)可以由單線程導(dǎo)出演進(jìn)為多線程并發(fā)導(dǎo)出按照上述優(yōu)化流程,假定查詢對(duì)象列表時(shí)間為A,單線程導(dǎo)出結(jié)構(gòu)所需時(shí)間為B,根據(jù)CPU核數(shù)/IO線程比我們?cè)O(shè)定導(dǎo)出結(jié)構(gòu)的線程數(shù)為8,在源庫性能足夠的情形下,查詢對(duì)象列表+導(dǎo)出對(duì)象結(jié)構(gòu)的時(shí)間應(yīng)該等于
CostTime(hour)=max(A,?B/8)?——?約等于2
這樣我們的總時(shí)間為2 + 8 = 10小時(shí),滿足客戶的需求!
優(yōu)化思路
有了上面的分析,結(jié)合OOM問題和查詢時(shí)間優(yōu)化的思路,我們有了以下的設(shè)計(jì):
上面圖略去了數(shù)據(jù)的回放模型,主要突出了結(jié)構(gòu)的回放,同時(shí)在兩個(gè)store中加入了內(nèi)存控制,防止出現(xiàn)OOM問題。
05
優(yōu)化結(jié)果
在通宵達(dá)旦的開發(fā)和驗(yàn)證后,我們終于構(gòu)建了以上的框架,并且成功將86萬張表的總時(shí)長優(yōu)化到了10小時(shí)以內(nèi),更為可喜的是整個(gè)流程中的full gc次數(shù)為0,最終客戶的需求得以實(shí)現(xiàn),技術(shù)人員也從中學(xué)習(xí)到了新的知識(shí)。
思考
優(yōu)化是無止境的,其實(shí)上述的架構(gòu)還存在優(yōu)化空間,比如以下的兩點(diǎn):
1.結(jié)構(gòu)的導(dǎo)入和數(shù)據(jù)的回放可以并行執(zhí)行,針對(duì)用戶表多數(shù)據(jù)少的場(chǎng)景,統(tǒng)計(jì)發(fā)現(xiàn)表結(jié)構(gòu)的導(dǎo)入花了4個(gè)小時(shí)而數(shù)據(jù)的導(dǎo)入也只花了4個(gè)小時(shí),這一個(gè)階段可以優(yōu)化(DRS已經(jīng)做了這個(gè)優(yōu)化,會(huì)在后續(xù)的博客中給大家科普實(shí)現(xiàn)方式)2.結(jié)構(gòu)的導(dǎo)出和結(jié)構(gòu)回放是否可以并行執(zhí)行,他們之間的限制關(guān)系是什么?如果有小伙伴對(duì)我們的架構(gòu)有看法也可以積極留言,我們會(huì)去認(rèn)真觀摩!
↓點(diǎn)擊
總結(jié)
以上是生活随笔為你收集整理的expdp导出表结构_超强技术案例!86万张表迁移的优化历程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python 只取年月日 字符串_Pyt
- 下一篇: 东方卫视演得泰坦机器人_机器人“舞林大会