作者:賀磊
我先說(shuō)幾個(gè)最讓你興奮和開(kāi)心的點(diǎn)吧:
在 TiDB 里搞动,你完全不用擔(dān)心磁盤容量的問(wèn)題。
在 TiDB 里渣刷,原生支持 Online DDL鹦肿,你完全不用擔(dān)心第三方改表工具改表出現(xiàn)各種 Bug 的問(wèn)題,相信用開(kāi)源工具改過(guò)上 T 級(jí)別表的同學(xué)都遇到過(guò)或多或少的各類 error辅柴。
在 TiDB 里箩溃,加列瞭吃,主鍵擴(kuò)容字段都是秒級(jí)的,比如我剛剛就剛對(duì)一張 19 億的表加完了字段涣旨,1 秒完事歪架,這在 MySQL 里要 8.0 才可以,而且還要求列在最后才行开泽。
在 TiDB 里牡拇,你會(huì)發(fā)現(xiàn) count() 驚人的快魁瞪,一張近 20 億的表 coun() 大概在 1 分鐘完事兒穆律,當(dāng)然,這取決于你的 KV 數(shù)量和磁盤性能导俘。
在 TiDB 里峦耘,從 MySQL 遷移將變得簡(jiǎn)單,圖形化一鍵遷移旅薄,爽不爽辅髓?
在 TiDB 里,絕大多數(shù)情況你會(huì)發(fā)現(xiàn)比單機(jī) MySQL 有更好的性能少梁,當(dāng)然也不排除一些例外洛口,例如 enum 這樣奇葩的字段類型。
在 TiDB 里凯沪,......第焰,您且往下看,我慢慢和您說(shuō)妨马。
使用背景
360 云平臺(tái)對(duì) 360 集團(tuán)各大業(yè)務(wù)線均有提供服務(wù)支持挺举,涉及的數(shù)據(jù)庫(kù)支持方案有:MySQL、Redis烘跺、MongoDB湘纵、ES、GP滤淳、PiKA梧喷。其中 MySQL 至今已有過(guò)萬(wàn)的實(shí)例,目前脖咐,對(duì)于一些寫入量大的業(yè)務(wù)伤柄,已經(jīng)出現(xiàn)瓶頸。例如磁盤空間文搂,雖然我們可以通過(guò)分庫(kù)分表的方式适刀,拆分出來(lái),但這對(duì)業(yè)務(wù)和 DBA 來(lái)說(shuō)都是不小的工作量煤蹭,最痛苦的無(wú)異于這些大表的改表笔喉。無(wú)論是單表上 T取视,還是分庫(kù)分表,對(duì)一張大表執(zhí)行 DDL 的代價(jià)是非常大的常挚。針對(duì)業(yè)務(wù)爆發(fā)式增長(zhǎng)的數(shù)據(jù)量作谭,我們開(kāi)始調(diào)研選型是否有其他數(shù)據(jù)庫(kù)可以代替?zhèn)鹘y(tǒng)的 MySQL。通過(guò)調(diào)研我們了解到 TiDB奄毡,遷移平滑折欠,基本上無(wú)需業(yè)務(wù)變動(dòng)代碼,完全的事務(wù) ACID 支持吼过,分布式的架構(gòu)锐秦,自帶高可用、Online DDL盗忱。截止目前酱床,360 云平臺(tái)這邊有三套 TiDB 集群,總節(jié)點(diǎn)數(shù)在 50+趟佃。有 9 個(gè)業(yè)務(wù)線接入使用扇谣,有過(guò)百億級(jí)表 Online 加索引的案例,總數(shù)據(jù)量目前在 80T闲昭。版本上罐寨,我們從 3.0.1 一路跟隨到 3.0.5,DM 版本從內(nèi)測(cè)到 1.0.2 GA 版本序矩,共計(jì)提出 9 個(gè) Bug 或改進(jìn)項(xiàng)反饋鸯绿。后續(xù)我們計(jì)劃將 TiDB 上到 360 HULK 云平臺(tái)上,并定制化開(kāi)發(fā)一些功能為業(yè)務(wù)提供可視化的服務(wù)贮泞,以便讓 360 集團(tuán)更多的業(yè)務(wù)線接觸到 TiDB楞慈、使用 TiDB。版本的選擇我們之所以從大版本 3 開(kāi)始啃擦,也是看到了一些 2.X 版本的社區(qū)反饋囊蓝,尤其是索引執(zhí)行計(jì)劃這塊,3.X 版本較之前的版本會(huì)好很多令蛉。DM 版本我們是直接選取的最新版聚霜,后一路跟隨新版本升級(jí)。
集群架構(gòu)
整體架構(gòu)上珠叔,我們除了 TiDB 集群外蝎宇,還用到了 DM 和 Pump、Drainer 套件祷安。這塊主要是由于我們使用 TiDB 的業(yè)務(wù)有兩種:①老的 MySQL 業(yè)務(wù)姥芥,因單機(jī)磁盤受限仍稀,導(dǎo)致單實(shí)例磁盤無(wú)法支撐爆炸式增長(zhǎng)的數(shù)據(jù)量狂魔,數(shù)據(jù)比較重要,需要備份和支持 7*24 小時(shí)的恢復(fù)。這類業(yè)務(wù)我們用到 DM 套件來(lái)實(shí)現(xiàn)無(wú)障礙遷移摆霉,1TB 的導(dǎo)入時(shí)間在 16 小時(shí)淘邻,這里如果是比較大的數(shù)據(jù)源菠隆,且 TiDB 是全新集群譬重,可以使用 TiDB-Lightning,速度可以更快簿训。Lightning 的實(shí)測(cè)導(dǎo)入速度咱娶,37 分鐘,導(dǎo)完 2 張大表共計(jì) 54G 的數(shù)據(jù)强品,符合 100G/H 預(yù)估膘侮,是 loader 的 3 倍速度,loader 用時(shí) 2 小時(shí) 4 分鐘择懂。
說(shuō)起 DM 使用這塊文章后面會(huì)單獨(dú)分享下這塊需要注意的問(wèn)題喻喳,如下圖所示:
②全新的業(yè)務(wù)另玖,或由業(yè)務(wù)自行導(dǎo)入到 TiDB 集群中困曙,這種業(yè)務(wù)數(shù)據(jù)量一般都會(huì)比較大,也是看中了 TiDB 支持 ACID 和分布式的特點(diǎn)谦去。目前網(wǎng)盾業(yè)務(wù)有多張表都過(guò) 10 億級(jí)別慷丽,其中有張表到達(dá)了 100 億+,建索引花了近 10 天(這塊其實(shí)我們應(yīng)當(dāng)注意鳄哭,不是分布式就一張表就完事兒了要糊,因?yàn)楸砹考?jí)過(guò)大,清理老舊數(shù)據(jù)都是個(gè)問(wèn)題)妆丘。TiDB 現(xiàn)在支持分區(qū)表锄俄,但我們?cè)谑褂眠^(guò)程中發(fā)現(xiàn)性能上和普通表有差距,期待后續(xù)版本能夠讓分區(qū)表功能和性能更加的完善勺拣。
TiDB 在 360 云平臺(tái)的使用情況
對(duì)于這一全新的數(shù)據(jù)庫(kù)奶赠,我們本著大膽用,不拘泥于傳統(tǒng)的態(tài)度進(jìn)行使用药有。我們的 MySQL 現(xiàn)在也正在適配 8.0 版本毅戈,MongoDB、ES 也都是時(shí)刻關(guān)注著新版本情況來(lái)評(píng)估是否適合云平臺(tái)愤惰。因此 TiDB 的上線也是從離線業(yè)務(wù)→邊緣業(yè)務(wù)→核心業(yè)務(wù)來(lái)過(guò)渡的苇经。經(jīng)過(guò)大量的測(cè)試、也參考了其他公司的使用情況宦言,我們計(jì)劃將 TiDB 納入 360 HULK 云平臺(tái)扇单,并計(jì)劃后期對(duì)其不斷完善在云平臺(tái)中的功能,對(duì)全公司業(yè)務(wù)線開(kāi)放使用奠旺。定制化開(kāi)發(fā)一些 MySQL 已經(jīng)具備的蜘澜,例如 SQL 審核阻桅、慢查統(tǒng)計(jì)、冗余索引檢測(cè)兼都、自增索引閾值等各項(xiàng)基礎(chǔ)功能等等嫂沉。雖然在使用過(guò)程中遇到了一些小問(wèn)題,例如索引的選取扮碧、參數(shù)的調(diào)優(yōu)趟章,因?yàn)橐恍┡渲脤?dǎo)致的性能抖動(dòng),但都得到了 PingCAP 同學(xué)快速的響應(yīng)和回復(fù)慎王,這對(duì)我們推進(jìn) TiDB 有重大的幫助蚓土。
一鍵遷移工具 DM 干貨分享
DM 使用經(jīng)驗(yàn)如下:
①權(quán)限
官網(wǎng)手冊(cè)上只說(shuō)明需要如下權(quán)限:TiDB Lightning 需要以下權(quán)限:
SELECT
UPDATE
ALTER
CREATE
DROP
存儲(chǔ)斷點(diǎn)的數(shù)據(jù)庫(kù)額外需要以下權(quán)限:
INSERT
DELETE
但實(shí)測(cè)過(guò)程中發(fā)現(xiàn)還需要如下權(quán)限:
上游 (REPLICATION SLAVE 權(quán)限必須具備,要不增量同步會(huì) access deny)赖淤。
下游 (不加 super 會(huì)導(dǎo)致 checksum table 無(wú)法執(zhí)行)蜀漆。
②TiKV Region Score
PD 監(jiān)控中 -Statistics-balance 中,有 Store-region-score 監(jiān)控項(xiàng)咱旱,這里記錄的是各個(gè)節(jié)點(diǎn)的 Score 得分确丢,正常情況下,我們期望的結(jié)果是得分接近的吐限,這說(shuō)明無(wú)需進(jìn)行 Region 大規(guī)模遷移鲜侥。③PD 調(diào)度原理Region 負(fù)載均衡調(diào)度主要依賴 balance-leader 和 balance-region 兩個(gè)調(diào)度器。二者的調(diào)度目標(biāo)是將 Region 均勻地分散在集群中的所有 Store 上诸典,但它們各有側(cè)重:
balance-leader 關(guān)注 Region 的 Leader描函,目的是分散處理客戶端請(qǐng)求的壓力。
balance-region 關(guān)注 Region 的各個(gè) Peer狐粱,目的是分散存儲(chǔ)的壓力舀寓,同時(shí)避免出現(xiàn)爆盤等狀況。
我們這里重點(diǎn)關(guān)注的是 balance-region肌蜻,當(dāng)它出現(xiàn)不均衡的時(shí)候互墓,我們可以直接在監(jiān)控中看到類似下圖所示:
調(diào)度期間,不可避免的會(huì)出現(xiàn) IO 爭(zhēng)用宋欺、磁盤的 lantency轰豆,都會(huì)出現(xiàn)不同程度的上漲,從業(yè)務(wù)上的反饋看齿诞,就會(huì)出現(xiàn)積壓酸休,響應(yīng)不及時(shí)等等。而當(dāng) Region Balance 完成后祷杈, Duration 等都會(huì)恢復(fù)正常水平斑司。因此,我們要關(guān)注的地方有兩點(diǎn):
如何控制或減小 Region Balance 大規(guī)模遷移時(shí)對(duì)業(yè)務(wù)的影響;
如何提前規(guī)避因磁盤導(dǎo)致的大規(guī)模 Region Balance宿刮。
對(duì)于第一點(diǎn)互站,我們遷移的時(shí)候是有參數(shù)可以控制的。這里無(wú)論是磁盤空間閾值僵缺,還是 Region Balance 調(diào)度速度胡桃,或者 Drop 大量表后調(diào)整空 Region Merge 的速度,其實(shí)都是可以通過(guò) pd-ctl 的 config set 命令來(lái)實(shí)時(shí)調(diào)節(jié)磕潮。例如:
high-space-ratio 0.7 #設(shè)置空間充裕閾值為 0.7翠胰。當(dāng)節(jié)點(diǎn)的空間占用比例小于指定值時(shí),PD 調(diào)度時(shí)會(huì)忽略剩余空間這個(gè)指標(biāo)自脯,主要針對(duì)實(shí)際數(shù)據(jù)量進(jìn)行均衡之景。
region-schedule-limit 8 #最多同時(shí)進(jìn)行 8 個(gè) Region 調(diào)度。這個(gè)值主要影響 Region Balance 的速度膏潮,值越大調(diào)度得越快锻狗,設(shè)置為 0 則關(guān)閉調(diào)度。Region 調(diào)度的開(kāi)銷較大焕参,所以這個(gè)值不宜調(diào)得太大轻纪。也可以通過(guò)減小該值來(lái)限制調(diào)度region對(duì)集群產(chǎn)生的影響。
merge-schedule-limit 12 #最多同時(shí)進(jìn)行 12 個(gè) merge 調(diào)度龟糕。設(shè)置為 0 則關(guān)閉 Region Merge桐磁。Merge 調(diào)度的開(kāi)銷較大悔耘,所以這個(gè)值不宜調(diào)得過(guò)大讲岁。
leader-schedule-limit 8 #最多同時(shí)進(jìn)行 8 個(gè) leader 調(diào)度。這個(gè)值主要影響 Leader Balance 的速度衬以,值越大調(diào)度得越快缓艳,設(shè)置為 0 則關(guān)閉調(diào)度。Leader 調(diào)度的開(kāi)銷較小看峻,需要的時(shí)候可以適當(dāng)調(diào)大阶淘。
max-merge-region-keys 50000 #設(shè)置 Region Merge 的 keyCount 上限為 50k。當(dāng) Region KeyCount 大于指定值時(shí) PD 不會(huì)將其與相鄰的 Region 合并互妓。
max-merge-region-size 16 #設(shè)置 Region Merge 的 size 上限為 16M溪窒。當(dāng) Region Size 大于指定值時(shí) PD 不會(huì)將其與相鄰的 Region 合并。設(shè)置為 0 表示不開(kāi)啟 Region Merge 功能冯勉。
TIPS:理解了作用和原理澈蚌,上述參數(shù)都可以根據(jù)需求自行控制。
例如當(dāng)我們?cè)?Drop 大量的表后灼狰,會(huì)產(chǎn)生很多的空 Region宛瞄。在 Region 數(shù)量較多的情況下,Raftstore 需要花費(fèi)一些時(shí)間去處理大量 Region 的心跳交胚,從而帶來(lái)一些延遲份汗,導(dǎo)致某些讀寫請(qǐng)求得不到及時(shí)處理盈电。
如果讀寫壓力較大,Raftstore 線程的 CPU 使用率容易達(dá)到瓶頸杯活,導(dǎo)致延遲進(jìn)一步增加匆帚,進(jìn)而影響性能表現(xiàn)。
因此我們會(huì)希望盡快的進(jìn)行 Region Merge旁钧,來(lái)避免過(guò)多的 Region 對(duì)集群造成性能損耗時(shí)卷扮,我們可以同時(shí)調(diào)小 max-merge-region-keys、max-merge-region-size均践,來(lái)讓其更快的觸發(fā) Merge 操作晤锹,同時(shí)調(diào)大 merge-schedule-limit 提高并發(fā)度。
例如當(dāng)我們發(fā)現(xiàn)某臺(tái) KV 磁盤空間剩余 40% 開(kāi)始大量調(diào)度時(shí)彤委,我們可以將 high-space-ratio 調(diào)整到 0.7鞭铆,以臨時(shí)避免調(diào)度對(duì)業(yè)務(wù)產(chǎn)生的影響。
我們也可以控制調(diào)度的并發(fā)度焦影,來(lái)減少對(duì)業(yè)務(wù)產(chǎn)生的影響车遂,實(shí)測(cè)這都是立竿見(jiàn)影的參數(shù),大家如果遇到這些問(wèn)題可供參考斯辰。
對(duì)于第二點(diǎn)舶担,尤其是使用 DM 期間,將 DM-worker 和 TiKV 混合部署的情況下彬呻,要注意清理全量備份留下的文件和 Relaylog衣陶。
默認(rèn)調(diào)度策略是當(dāng)磁盤剩余的有效空間不足 40%,處于中間態(tài)時(shí)則同時(shí)考慮數(shù)據(jù)量和剩余空間兩個(gè)因素做加權(quán)和當(dāng)作得分闸氮,當(dāng)?shù)梅殖霈F(xiàn)比較大的差異時(shí)剪况,就會(huì)開(kāi)始調(diào)度。所以 DM 導(dǎo)入完成后蒲跨,要記得刪除全量備份译断。就是 dumped_data.task_xxx 文件夾,這個(gè)全量備份一般都會(huì)比較大或悲,如果 dm-worker 和 TiKV 混部孙咪,就會(huì)出現(xiàn)某個(gè) TiKV 節(jié)點(diǎn)磁盤已使用率高于其他。
這時(shí) PD 的 store region score 就會(huì)相比其他節(jié)點(diǎn)出現(xiàn)異常巡语,引起性能抖動(dòng)和 Duration 升高翎蹈。
一直等待其追上后,才會(huì)像下圖這樣:
此時(shí)捌臊,balancer 已達(dá)平衡狀態(tài):
Duration 恢復(fù)正常水平杨蛋,如下圖 16:54 分時(shí)的情況:
QPS 也不再積壓,恢復(fù)正常水準(zhǔn):
關(guān)于 relay-log,默認(rèn)是不清理的逞力,就和 MySQL 的 expire_logs_days 一樣曙寡,這塊可以通過(guò) dm-worker 的配置文件來(lái)進(jìn)行配置。
例如將 Expires 配置為 7寇荧,代表 7 天后刪除:
[purge]
interval = 3600
expires = 7
remain-space = 15
Expires 來(lái)控制保留天數(shù)举庶。默認(rèn) expires=0,即沒(méi)有過(guò)期時(shí)間揩抡,而 remain-space=15 意思是當(dāng)磁盤只剩于 15G 的時(shí)候開(kāi)始嘗試清理户侥,這種情況我們極少會(huì)碰到,因此這個(gè)清理方式其實(shí)基本上是用不到的峦嗤。所以建議有需要?jiǎng)h除過(guò)期 relay-log 的小伙伴蕊唐,直接配置 Expires 保留天數(shù)就可以了。DM 導(dǎo)入完成后烁设,應(yīng)該提供是否在完成后自動(dòng)刪除全備文件的選項(xiàng)替梨,可以默認(rèn)不刪,由使用者決定是否刪除装黑。從使用者角度來(lái)說(shuō)副瀑,全量備份目錄無(wú)論是全量一次性導(dǎo)入還是 all 增量同步,后續(xù)都不會(huì)再使用到恋谭。如果 dm-worker 和 TiKV 混部糠睡,會(huì)導(dǎo)致全備文件占據(jù)大量磁盤空間,引起 TiKV Region 評(píng)分出現(xiàn)異常疚颊,導(dǎo)致性能下降狈孔,已轉(zhuǎn)化為 PRM 產(chǎn)品需求。
④關(guān)于 DM 使用期間出現(xiàn)數(shù)據(jù)丟失的問(wèn)題
在早期還沒(méi)有 dm-portal 自動(dòng)化生成 task 時(shí)串稀,我們都是自行編寫 DM 的 task 同步文件除抛。后來(lái)有了 dm-portal 自動(dòng)化生成工具,只要圖形頁(yè)面點(diǎn)點(diǎn)點(diǎn)就可以了母截。
但該工具目前有一個(gè)問(wèn)題是,沒(méi)有全庫(kù)正則匹配橄教,即便你只勾選一個(gè)庫(kù)清寇,他底層是默認(rèn)把每張表都給你配置一遍。這就會(huì)出現(xiàn)當(dāng)上層 MySQL 新創(chuàng)建某張表的時(shí)候护蝶,下游會(huì)被忽略掉华烟,例如當(dāng)你使用改表工具 gh-ost 或者 pt-online-schema-change,你的臨時(shí)表都會(huì)被當(dāng)做為不在白名單內(nèi)而被忽略持灰,這個(gè)問(wèn)題使用者需要注意盔夜。
我們也已經(jīng)反饋給了官方。未來(lái)不久的版本估計(jì)就可以修復(fù)。
["skip event"] [task=task_20357] [unit="binlog replication"] [event=query] [statement="ALTER TABLE `360`.`_data_201910_gho` ADD COLUMN `raw_url_md5` CHAR(32) NOT NULL DEFAULT '' COMMENT 'raw_url md5'"]
["skip event"] [task=task_20357] [unit="binlog replication"] [event=query] [statement="ALTER TABLE `360`.`_data_201910_gho` ADD INDEX `idx_rawurl_md5`(`raw_url_md5`)"] [schema=flow]
["skip event"] [task=task_20357] [unit="binlog replication"] [event=query] [statement="ALTER TABLE `360`.`_data_201910_gho` DROP INDEX `idx_raw_url`"] [schema=flow]
這里日志可以看到 event 被 skip 了喂链。
⑤關(guān)于 DM 使用期間偶發(fā)性 1062 主鍵沖突的問(wèn)題
query-error task 能看到具體的報(bào)錯(cuò)信息返十,下游看都沒(méi)有該值:
mysql> select * from client where clientid='82b51e6f6eb64955487f978dd94a2c81e492f6170xxxxxxxxxxxxxxxxxxxxxxxxx';
Empty set (0.00 sec)
再去上游看,結(jié)果發(fā)現(xiàn)也沒(méi)有值椭微,業(yè)務(wù)邏輯應(yīng)該是后來(lái) delete 了:
mysql> select * from client where clientid='82b51e6f6eb64955487f978dd94a2c81e492f6170xxxxxxxxxxxxxxxxxxxxxxxxx';
Empty set (0.00 sec)
因?yàn)樯嫌我矝](méi)有值洞坑,去上游看 Binlog 后分析如下:是先寫入,再刪除蝇率,所以上游沒(méi)值是可以預(yù)期的迟杂,但是下游還沒(méi)有同步到這塊,此時(shí)也是沒(méi)有值的本慕,不應(yīng)該存在 1062 的問(wèn)題排拷。當(dāng)集群有大規(guī)模 kv:1062 報(bào)錯(cuò)時(shí),或者集群寫入壓力大時(shí)锅尘,DM 從結(jié)果看無(wú)法保證 Binlog 的有序落盤攻泼,需確認(rèn) DM能不能保證 LVS 下的多個(gè) TiDB Binlog 的每一個(gè) Event 是有序執(zhí)行的。只從現(xiàn)象看鉴象,只要集群沒(méi)有大量的 1062 報(bào)錯(cuò)忙菠,PD 相關(guān)的監(jiān)控值都比較低,DM 也不會(huì)出現(xiàn)任何同步報(bào)錯(cuò)纺弊,反之就出現(xiàn)牛欢。從 Binlog 看就像是第一條 Insert了,還沒(méi)來(lái)得及 Delete淆游,直接 Insert 產(chǎn)生的報(bào)錯(cuò)傍睹,但報(bào)錯(cuò)后那個(gè) Delete 的也完成了,所以這時(shí)候我再怎么快也快不到毫秒級(jí)犹菱,下游看不到所有記錄拾稳。解決的辦法是將 1062 大量沖突的業(yè)務(wù)拆分出集群,或 DM 直接寫 TiDB 的真實(shí) IP 而不是 LVS腊脱。⑥D(zhuǎn)M 同步異常有業(yè)務(wù)反饋 Drop 分區(qū)和 Drop 列時(shí)出現(xiàn)同步異常访得。補(bǔ)充下分區(qū)表相關(guān)的測(cè)試的結(jié)果,DM 更多的無(wú)法拆分的情況還是在 Drop 這塊陕凹,普通的 add悍抑,modify 沒(méi)問(wèn)題的。一次刪除多個(gè)分區(qū)的操作則會(huì)報(bào)錯(cuò):
alter table dsp_group_media_report drop partition p202006 ,p202007 ;
Drop 含有索引的列操作會(huì)報(bào)錯(cuò):
Alter table dsp_group drop column test_column;
40 億表添加 DDL 添加索引導(dǎo)致的 Duration 升高:
定位到是:
mysql> show global variables like 'tidb_ddl_reorg_worker_cnt';
+---------------------------+-------+
| Variable_name | Value |
+---------------------------+-------+
| tidb_ddl_reorg_worker_cnt | 16 |
+---------------------------+-------+
1 row in set (0.11 sec)
mysql> show global variables like 'tidb_ddl_reorg_batch_size';
+---------------------------+-------+
| Variable_name | Value |
+---------------------------+-------+
| tidb_ddl_reorg_batch_size | 1024 |
+---------------------------+-------+
上述兩個(gè)參數(shù)對(duì)已有非 pcie 集群壓力比較大導(dǎo)致杜耙。通過(guò) set global 調(diào)節(jié)(3.0.3 后搜骡,默認(rèn)從 256 漲到了 1000 和 16):
tidb_ddl_reorg_batch_size 1000-256
tidb_ddl_reorg_worker_cnt 16-4
同時(shí),提高 Compaction 相關(guān):
max-background-jobs: 8-10-12
max-sub-compactions: 1-2-4
defaultcf.compression-per-level: ["lz4", "lz4", "lz4", "lz4", "lz4", "zstd", "zstd"]
writecf.compression-per-level: ["lz4", "lz4", "lz4", "lz4", "lz4", "zstd", "zstd"]
最終的優(yōu)化結(jié)果是佑女,QPS 穩(wěn)定在 3K 左右:
⑦靜默 Region 開(kāi)啟在實(shí)際情況中记靡,讀寫請(qǐng)求并不會(huì)均勻分布到每個(gè) Region 上谈竿,而是集中在少數(shù)的 Region 上。那么可以盡量減少暫時(shí)空閑的 Region 的消息數(shù)量摸吠,這也就是 Hibernate Region 的功能空凸。無(wú)必要時(shí)可不進(jìn)行 raft-base-tick,即不驅(qū)動(dòng)空閑 Region 的 Raft 狀態(tài)機(jī)蜕便,那么就不會(huì)觸發(fā)這些 Region 的 Raft 產(chǎn)生心跳信息劫恒,極大地減小了 Raftstore 的工作負(fù)擔(dān)。截至 TiDB v3.0.5轿腺,Hibernate Region 仍是一個(gè)實(shí)驗(yàn)功能两嘴,在 TiKV master 分支上已經(jīng)默認(rèn)開(kāi)啟∽蹇牵可根據(jù)實(shí)際情況和需求來(lái)開(kāi)啟該功能憔辫。
參數(shù)如下:
raftstore.hibernate-regions: true
⑧DM 導(dǎo)入期間 Duration 升高
在 DM 導(dǎo)入集群期間,確實(shí)會(huì)因?yàn)閷憻狳c(diǎn)的問(wèn)題導(dǎo)致集群整體 Duration 更高仿荆,因?yàn)?IO 爭(zhēng)用會(huì)更明顯贰您。這里其實(shí)也是可以通過(guò)一些參數(shù)來(lái)讓集群運(yùn)行的更快的。
如下參數(shù)從原值調(diào)到-新值:
raftstore:
apply-pool-size: 3-4
store-pool-size: 3-4
storage:
scheduler-worker-pool-size: 4-6
server:
grpc-concurrency: 4-6
rocksdb:
max-background-jobs: 8-10
max-sub-compactions: 1-2
可以看到效果如下:QPS 不再抖動(dòng)拢操,Duration 也恢復(fù)到正常的水平锦亦。
⑨DM Debug 相關(guān)DM 還有個(gè)注意點(diǎn)就是 dm-worker.toml 配置文件里的配置 log-level=“debug” 是不生效的,啟動(dòng)的時(shí)候默認(rèn)有個(gè) -L=info 選項(xiàng)令境,會(huì)覆蓋掉配置文件里的杠园,默認(rèn) -L 優(yōu)先級(jí)高于配置文件,人工排查時(shí)自行啟動(dòng)舔庶。也就是說(shuō)當(dāng)需要對(duì) dm-worker 開(kāi)啟 debug 模式抛蚁,要人工拉起進(jìn)程并指定 -L 選項(xiàng)=debug。⑩TiDB load data 速度不理想TiDB 目前 load data 的導(dǎo)入速度不及 MySQL惕橙,如果依賴 load data 的話瞧甩,這塊可以調(diào)優(yōu)一下參數(shù)。
我們的場(chǎng)景是 TiKV 上沒(méi)有明顯的瓶頸弥鹦,主要慢在了 scheduler latch wait duration肚逸,可以調(diào)下參數(shù)看看:
storage:
scheduler-concurrency: 204800000
raftstore:
raft-max-inflight-msgs: 4096
調(diào)優(yōu)完成后是有提升,但提升不大惶凝,我們得知新版本的 TiDB 在 Load data 這塊又有速度提升吼虎,比較期待新版本。
其他干貨打包分享
①TiDB 列數(shù)超限MySQL 是 1024苍鲜,TiDB 目前限制是 512 列。如果你的表有非常多的列玷犹,那么這塊要提前注意下是不是可以拆分出去混滔。②GC can not workGC 的數(shù)據(jù)包括兩部分洒疚,一部分是 DML 和 DDL ,DDL 的 GC 的對(duì)象信息包含在 mysql.gc_delete_range 和 mysql.gc_delete_range_done 坯屿,分別記錄的是待 GC 的對(duì)象以及已經(jīng) GC 的對(duì)象油湖。mysql.gc_delete_range_done表里面沒(méi)有數(shù)據(jù)不代表 GC 異常。
官方建議更換規(guī)則:
sum(increase(tikv_gcworker_gc_tasks_vec{task="gc"}[1d]))
③TiDB or 條件優(yōu)化
在 TiDB 中领跛,如下查詢是不能用到索引的:
select * from manual_domain where host_md5 = '55fbea39965484a61xxxxxxxxxx' or domain_md5 = '55fbea39965484a61xxxxxxxxxx';
MySQL 中用到了 index_merge乏德,TiDB 計(jì)劃 4.0 支持,可以先用 union all 來(lái)處理這種 a or b吠昭。④Coprocessor CPU 消耗過(guò)大
業(yè)務(wù)反饋查詢變慢喊括,發(fā)現(xiàn)是另外一個(gè)業(yè)務(wù)全表掃 insert into select 導(dǎo)數(shù)據(jù)導(dǎo)致的。
去 CPU 占用率高的這臺(tái)機(jī)器上搜索對(duì)應(yīng)的 log矢棚,關(guān)鍵字 slow郑什,發(fā)現(xiàn)如下情況:
[2019/09/18 10:04:37.339 +08:00] [INFO] [tracker.rs:150] [slow-query] [internal_key_skipped_count=46649] [internal_delete_skipped_count=0] [block_cache_hit_count=1596] [block_read_count=9] [block_read_byte=31933] [scan_first_range="Some(start: 7480000000000002285F72800000000021E9BD end: 7480000000000002285F72800000000024199A)"] [scan_ranges=1] [scan_iter_processed=46650] [scan_iter_ops=46652] [scan_is_desc=false] [tag=select] [table_id=552] [txn_start_ts=411244239493267464] [wait_time=2ms] [total_process_time=1.41s] [peer_id=ipv4:192.168.1.248:45686] [region_id=835437]
根據(jù) table_id 去通過(guò) information_schema.tables 表查一下,可以通過(guò)上述方式來(lái)定位到是哪張表導(dǎo)致的問(wèn)題蒲肋。TiDB enum 導(dǎo)致的性能問(wèn)題:
enum 在 TiDB 3.0.2 進(jìn)行 where 條件查找時(shí)蘑拯,發(fā)現(xiàn)不能下推到 TiKV。官方說(shuō)4.0GA 修復(fù)兜粘。臨時(shí)辦法是修改到其他類型申窘。
enum modify 為 tinyint 發(fā)現(xiàn)內(nèi)容出現(xiàn)變化,原本的’'變成了 default 值孔轴,‘1’ 變成了 2剃法,經(jīng)測(cè)試 varchar 正常,因此不要嘗試去變更 DM 備份出來(lái)的 Schema 文件來(lái)實(shí)現(xiàn)表結(jié)構(gòu)變更距糖,應(yīng)該從上游 MySQL 解決玄窝。
⑤分區(qū)表元數(shù)據(jù)無(wú)法獲取沒(méi)有視圖可以查詢當(dāng)前已建分區(qū)信息。在 TiDB 中目前沒(méi)有視圖支持查詢分區(qū)表已建分區(qū)信息悍引,那么用戶那邊沒(méi)有辦法直觀的判斷當(dāng)前已建的分區(qū)恩脂,以及當(dāng)前是否需要及時(shí)的添加新分區(qū)。目前已轉(zhuǎn)化為 PRM 產(chǎn)品需求趣斤,相信新版本不久會(huì)實(shí)現(xiàn)俩块。分區(qū)表 - 部分分區(qū) - limit 未下推:分區(qū)表出現(xiàn) limit 未下推的現(xiàn)象,表 content_info_p 其中只有分區(qū) p201911 有數(shù)據(jù)浓领。該問(wèn)題已在 3.0.6 版本修復(fù)玉凯。mysql.tidb 表權(quán)限異常:使用 use db_name 或者 mysql 客戶端指定 DB name 后,可以對(duì)該表進(jìn)行查詢或更新操作联贩。計(jì)劃 3.1 版本修復(fù)漫仆。事物的限制:單個(gè)事物的 SQL statement 不超過(guò) 5000(stmt-count-limit 參數(shù)可調(diào));每個(gè)鍵值對(duì)不超過(guò) 6M泪幌;鍵值對(duì)的總數(shù)不超過(guò) 300000盲厌;鍵值對(duì)的總大小不超過(guò) 100M署照。注:鍵值對(duì)是指一張表里有 2 個(gè)索引,那么一共就是數(shù)值 +2 個(gè)索引吗浩,總共 3 個(gè)鍵值對(duì)建芙,那么每個(gè)鍵值對(duì)的總是不能超過(guò) 30 萬(wàn)/3=10 萬(wàn)。一行數(shù)據(jù)會(huì)映射為一個(gè) KV entry懂扼,每多一個(gè)索引禁荸,也會(huì)增加一個(gè) KV entry,所以這個(gè)限制反映在 SQL 層面是:總的行數(shù)*(1+索引個(gè)數(shù))<30w阀湿。官方提供內(nèi)部 batch 的方法赶熟,來(lái)繞過(guò)大事務(wù)的限制,分別由三個(gè)參數(shù)來(lái)控制:
tidb_batch_insert
tidb_batch_delete
tidb_dml_batch_size
寫熱點(diǎn)的處理:如果可以去掉 MySQL 自增主鍵炕倘,就可以通過(guò)建表時(shí)指定 SHARD_ROW_ID_BITS钧大、PRE_SPLIT_REGION 來(lái)實(shí)現(xiàn)預(yù)切分,避免單調(diào)自增引發(fā)的只往某個(gè) KV 上寫數(shù)據(jù)引起的熱點(diǎn)問(wèn)題罩旋。詳情可參考官網(wǎng) TiDB 專用系統(tǒng)變量和語(yǔ)法中 SHARD_ROW_ID_BITS 的介紹啊央。⑥TiDB 監(jiān)控和 DM 監(jiān)控 Ansible 部署數(shù)據(jù)沖突這塊可以通過(guò)將 TiDB 和 DM 監(jiān)控部署到不同的機(jī)器上來(lái)繞過(guò)解決,否則就會(huì)出現(xiàn)通過(guò) Ansible 安裝后涨醋,ansible-playbook rolling_update_monitor.yml --tags=prometheus 時(shí)瓜饥,兩者只有一個(gè)是正常的。磁盤已使用不建議超過(guò) 50%:數(shù)據(jù)量太多 LSM 過(guò)大浴骂, compaction 成本會(huì)很高乓土,并且內(nèi)存命中率下降,同時(shí)單機(jī)恢復(fù)時(shí)間很長(zhǎng)溯警,50% 左右最好趣苏,使用率太高,如果突然寫入爆增梯轻,region 來(lái)不及調(diào)度會(huì)寫滿磁盤食磕,有風(fēng)險(xiǎn)。因此建議 SSD 不要使用超過(guò) 2T 的喳挑,采用更多的機(jī)器會(huì)有更好的性能彬伦。⑦M(jìn)ydumper 導(dǎo)致的內(nèi)存和網(wǎng)卡打滿
在使用 Mydumper 備份大時(shí),會(huì)打滿 TiDB 網(wǎng)卡伊诵,同時(shí)會(huì)消耗 TiDB单绑、TiKV 更多的內(nèi)存。
【TiDB ERR】[emergency]TiDB_schema_error:192.168.1.1:10080,[add_dba_mysql]【360】
【TiDB ERR】[critical]NODE_memory_used_more_than_80%:192.168.1.2:9100,[add_dba_mysql]【360】
去抓取慢日志會(huì)看到如下內(nèi)容:
grep Query_time tidb_slow_query-2019-12-24T04-53-14.111.log|awk -F : '$2>10'
# Time: 2019-12-24T03:18:49.685904971+08:00
# Txn_start_ts: 413433784152621060
# User: backup@192.168.1.3
# Conn_ID: 4803611
# Query_time: 4002.295099802
SELECT /*!40001 SQL_NO_CACHE */ * FROM `360`.`t_d` ;
期待后續(xù)的版本物理備份曹宴,邏輯備份看起來(lái)目前是可以備份搂橙,但會(huì)比較消耗資源,同時(shí)恢復(fù)時(shí)間也會(huì)更久笛坦。
展望
從 TiDB 2.x 開(kāi)始我們就已經(jīng)開(kāi)始進(jìn)行測(cè)試了份氧,最終選擇的版本是 3.0.2唯袄,后續(xù)升級(jí)到 3.0.5弯屈。上述文章總結(jié)和一些案例希望能夠幫助到已使用或打算使用 TiDB 的朋友蜗帜。360 云平臺(tái) DBA 團(tuán)隊(duì)也計(jì)劃將 TiDB 推上 360 HULK 云平臺(tái),為 360 集團(tuán)更多的業(yè)務(wù)線提供豐富多彩和穩(wěn)定可靠的數(shù)據(jù)庫(kù)服務(wù)资厉。在這里首先要感謝 PingCAP 同學(xué)及時(shí)的技術(shù)支持厅缺,幫助我們盡快的解決了一些技術(shù)問(wèn)題。同時(shí)宴偿,我自己也通讀了 TiDB 的官方手冊(cè)湘捎。從 Ansible 部署、二進(jìn)制部署窄刘、升級(jí)窥妇、DM、Lighting娩践、Pump活翩、Drainer、調(diào)優(yōu)翻伺、排障材泄、遷移、備份吨岭,這一路打怪下來(lái)拉宗,切身感受到了 TiDB 越來(lái)越好的過(guò)程。我相信未來(lái)隨著 3.1 和 4.0 版本的推出辣辫,有更多人加入使用 TiDB 的這個(gè)隊(duì)伍中來(lái)旦事。從業(yè)務(wù)給我們的反饋也是對(duì) TiDB 的使用情況表示滿意,我們相信急灭,TiDB 會(huì)在大家共同的努力下姐浮,越來(lái)越好。作者:賀磊
簡(jiǎn)介:360 數(shù)據(jù)庫(kù)運(yùn)維資深工程師化戳,《MongoDB 運(yùn)維實(shí)戰(zhàn)作者》单料,知名論壇 MySQL 版主,51CTO 博客之星点楼,閑暇之余扫尖,喜歡將部分案例寫成博客,累計(jì)訪問(wèn)量過(guò)百萬(wàn)掠廓。
原文: