偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

全面Docker化之后,京東彈性數(shù)據(jù)庫(kù)的最新實(shí)踐與突破!

數(shù)據(jù)庫(kù)
京東彈性數(shù)據(jù)庫(kù)不是一個(gè)單一的產(chǎn)品,而是京東在對(duì)數(shù)據(jù)庫(kù)的使用、運(yùn)維和開(kāi)發(fā)過(guò)程中遇到的一系列問(wèn)題的解決方案,和運(yùn)維經(jīng)驗(yàn)的總結(jié)升華進(jìn)而形成的一套產(chǎn)品系列。

京東彈性數(shù)據(jù)庫(kù)不是一個(gè)單一的產(chǎn)品,而是京東在對(duì)數(shù)據(jù)庫(kù)的使用、運(yùn)維和開(kāi)發(fā)過(guò)程中遇到的一系列問(wèn)題的解決方案,和運(yùn)維經(jīng)驗(yàn)的總結(jié)升華進(jìn)而形成的一套產(chǎn)品系列,主要包括三大功能模塊:

  1. 核心功能模塊:JED,提供數(shù)據(jù)查詢和寫入的自動(dòng)路由、自動(dòng)彈性伸縮、自動(dòng)FailOver、自動(dòng)負(fù)載調(diào)度和數(shù)據(jù)庫(kù)服務(wù)智能自治的功能。
  2. 實(shí)時(shí)數(shù)據(jù)發(fā)布與訂閱模塊: BinLake,完全自助、無(wú)狀態(tài)、自動(dòng)負(fù)載、完全自治、可橫向擴(kuò)展的集群化Binlog采集和訂閱服務(wù)。
  3. 自動(dòng)化運(yùn)維模塊:DBS,實(shí)現(xiàn)了京東線上所有數(shù)據(jù)庫(kù)服務(wù)申請(qǐng)、DDL/DML上線、數(shù)據(jù)抽取等的流程化和自動(dòng)化。

分享大綱:

1、發(fā)展歷程

2、功能特性

3、整體架構(gòu)

4、實(shí)現(xiàn)細(xì)節(jié)

5、使用情況

一、發(fā)展歷程

在我2011年加入京東之初,京東的數(shù)據(jù)庫(kù)正是處于諸侯混戰(zhàn)的階段,各種數(shù)據(jù)庫(kù)都有,包括:MySQL、PostGre、Oracle、SQL Sever,在2011年之后,開(kāi)始去IOE,到了2014年,京東基本上完成了去IOE,所有的業(yè)務(wù)系統(tǒng)都遷移到了MySQL上。

在大規(guī)模使用MySQL的過(guò)程中,我們發(fā)現(xiàn),隨著業(yè)務(wù)數(shù)據(jù)量的增長(zhǎng),很多業(yè)務(wù)開(kāi)始了漫長(zhǎng)的分庫(kù)、分表之旅,起初各個(gè)業(yè)務(wù)系統(tǒng)在自己的業(yè)務(wù)代碼中維護(hù)分庫(kù)分表的路由規(guī)則,而且各個(gè)業(yè)務(wù)系統(tǒng)的路由規(guī)則和整體設(shè)計(jì)都不一樣,后來(lái)由于人員更迭以至于業(yè)務(wù)代碼無(wú)法維護(hù),不同業(yè)務(wù)使用的數(shù)據(jù)庫(kù)分庫(kù)分表模式不盡相同,導(dǎo)致數(shù)據(jù)庫(kù)的維護(hù)工作也難如登天。這時(shí)我們開(kāi)始重新思考應(yīng)該提供什么樣的數(shù)據(jù)庫(kù)服務(wù),得出了以下幾點(diǎn):

  • 統(tǒng)一分庫(kù)分表標(biāo)準(zhǔn)
  • 路由針對(duì)業(yè)務(wù)透明
  • 數(shù)據(jù)庫(kù)服務(wù)伸縮無(wú)感知
  • 統(tǒng)一數(shù)據(jù)服務(wù)
  • 業(yè)務(wù)研發(fā)自助申請(qǐng)服務(wù)
  • 數(shù)據(jù)庫(kù)運(yùn)維工作自動(dòng)化

為了實(shí)現(xiàn)上述功能特點(diǎn),我們分為兩步走:第一步是優(yōu)先解決業(yè)務(wù)和運(yùn)維窘境,從而爭(zhēng)取足夠的時(shí)間和技術(shù)buffer進(jìn)一步完善產(chǎn)品,第二步是最終完美形態(tài)的產(chǎn)品研發(fā)。

因此,我們首先在2015年開(kāi)發(fā)了JProxy,優(yōu)先解決緊急的業(yè)務(wù)和運(yùn)維難題:分庫(kù)分表規(guī)則統(tǒng)一化和路由透明化。在拿到充分的時(shí)間buffer后,我們從2016年開(kāi)始以匠人的精神精雕細(xì)琢京東彈性數(shù)據(jù)庫(kù)。

二、功能特性

如前面所說(shuō):京東彈性數(shù)據(jù)庫(kù)是一個(gè)產(chǎn)品系列,主要是解決數(shù)據(jù)庫(kù)的運(yùn)維、使用和研發(fā)過(guò)程中的問(wèn)題,具備動(dòng)態(tài)伸縮、高可用、查詢透明路由、集群化日志服務(wù)和自動(dòng)化運(yùn)維等功能。

本章將就京東彈性數(shù)據(jù)庫(kù)三個(gè)核心模塊的功能進(jìn)行詳細(xì)說(shuō)明。

1、JED(JD Elastic DataBase)

JED是JProxy功能的父集,它除了具備透明路由、統(tǒng)一分庫(kù)分表標(biāo)準(zhǔn)之外,還提供了五大功能:

(1)在線動(dòng)態(tài)擴(kuò)容

起初某個(gè)業(yè)務(wù)可能申請(qǐng)了4個(gè)分庫(kù),后面隨著業(yè)務(wù)的發(fā)展,數(shù)據(jù)量越來(lái)越大,可能需要擴(kuò)容到 8個(gè)分庫(kù),一般的數(shù)據(jù)庫(kù)中間件在擴(kuò)容時(shí),需要與業(yè)務(wù)研發(fā)部門協(xié)商一個(gè)業(yè)務(wù)低谷期停業(yè)務(wù),然后進(jìn)行擴(kuò)容,擴(kuò)容完畢后重新啟動(dòng)業(yè)務(wù)。為了解決這個(gè)問(wèn)題,JED提供了在線動(dòng)態(tài)擴(kuò)容功能,擴(kuò)容只會(huì)對(duì)業(yè)務(wù)造成秒級(jí)影響,且無(wú)需人工介入。我們現(xiàn)在可以觸發(fā)自動(dòng)擴(kuò)容,設(shè)置的策略是當(dāng)磁盤的使用率達(dá)到80%,就自動(dòng)進(jìn)行擴(kuò)容。

(2)自動(dòng)Failover

Master一旦出現(xiàn)宕機(jī),哨兵檢測(cè)系統(tǒng)就會(huì)第一時(shí)間檢測(cè)到,會(huì)自動(dòng)觸發(fā)注冊(cè)在哨兵檢測(cè)系統(tǒng)中的Hook程序,Hook程序就會(huì)選擇一個(gè)最新的Slave替換Master,然后更新ETCD中的元數(shù)據(jù)信息,業(yè)務(wù)方的下一次請(qǐng)求就會(huì)發(fā)送新的Master上。

(3)兼容MySQL協(xié)議

JED是完全兼容MySQL協(xié)議的,即通過(guò)MySQL的Client端或者標(biāo)準(zhǔn)的JDBC Driver都可以連接到JED的Gate層,然后進(jìn)行查詢和計(jì)算。

(4)多源數(shù)據(jù)遷移

我們基于ghost進(jìn)行改造,開(kāi)發(fā)了京東的數(shù)據(jù)傳輸和接入工具: JTransfer,實(shí)現(xiàn)了業(yè)務(wù)數(shù)據(jù)的動(dòng)態(tài)遷移。如果以前你的業(yè)務(wù)是運(yùn)行在MySQL上的,現(xiàn)在要遷到JED上,你不需要停止任何業(yè)務(wù),直接啟動(dòng)JTransfer的數(shù)據(jù)遷移服務(wù),就可以在后臺(tái)自動(dòng)完成數(shù)據(jù)的同步和遷移。遷移完畢后,JTransfer會(huì)自行比對(duì)JED上的數(shù)據(jù)與原來(lái)數(shù)據(jù)的一致性和lag計(jì)算,當(dāng)數(shù)據(jù)完全一致,且lag小于5秒時(shí),就會(huì)郵件通知業(yè)務(wù)方進(jìn)行復(fù)驗(yàn),復(fù)驗(yàn)沒(méi)有問(wèn)題,業(yè)務(wù)方直接將數(shù)據(jù)庫(kù)連接指向到JED就可以正常提供服務(wù)了。

(5) 數(shù)據(jù)庫(kù)審計(jì)

JED具有數(shù)據(jù)庫(kù)審計(jì)的功能,該功能實(shí)現(xiàn)在Gate層,在Gate層我們會(huì)得到應(yīng)用發(fā)送給JED的所有SQL,然后將SQL語(yǔ)句或者SQL模板發(fā)送給MQ。由于是在Gate層實(shí)現(xiàn)的,而Gate層與MySQL服務(wù)不在一個(gè)容器上,因此對(duì)MySQL服務(wù)不會(huì)產(chǎn)生任何的負(fù)面影響。

2、BinLake

BinLake只做一樣工作:集群化Binlog的采集和訂閱服務(wù)。BinLake之前,我們使用Canal進(jìn)行binlog采集,但我們發(fā)現(xiàn)存在資源浪費(fèi)等問(wèn)題:若一個(gè)業(yè)務(wù)需要采集MySQL Binlog,并且還需要HA保證的話,我們至少需要兩臺(tái)服務(wù)器。那多個(gè)業(yè)務(wù)怎么辦?于是我們開(kāi)發(fā)了BinLake,其功能特性如下:

(1)  無(wú)狀態(tài)集群化BinLog采集

BinLake是一個(gè)集群化的BinLog采集和訂閱服務(wù),并且與常規(guī)意義上的集群不一樣,我們的集群是沒(méi)有master節(jié)點(diǎn)的,而且集群中的所有工作節(jié)點(diǎn)都是完全平等的,這也就意味著,只要集群中的節(jié)點(diǎn)沒(méi)有全部宕機(jī),BinLake集群可以一直提供服務(wù)。

(2)  高可用與自動(dòng)故障轉(zhuǎn)移

針對(duì)于某個(gè)Mya實(shí)例的采集instance(每個(gè)instance代表一個(gè)線程)一旦掛掉,會(huì)在集群中的負(fù)載最低的工作節(jié)點(diǎn)上重新啟動(dòng)一個(gè)instance,繼續(xù)從上次掛掉的Offset進(jìn)行采集,不會(huì)造成Binlog的丟失和重復(fù)。

(3)  負(fù)載自動(dòng)均衡

假設(shè)所有Binlog的集群有八個(gè)節(jié)點(diǎn),其中有七個(gè)節(jié)點(diǎn)的負(fù)載比較高,當(dāng)你在接入Binlog時(shí),在沒(méi)有人工介入的衡量下,整個(gè)集群會(huì)將以新接入的一個(gè)Instance采集實(shí)例,自動(dòng)選擇一個(gè)健康度最高的Wave服務(wù),然后啟動(dòng)Binlog采集。

(4)  支持多種MQ

BinLake采集到的所有binlog的event會(huì)被封裝成Message發(fā)送給MQ,目前我們支持JMQ和Kafka兩種MQ產(chǎn)品。

(5)  支持集群橫向擴(kuò)容

當(dāng)BinLake集群的服務(wù)能力達(dá)到了瓶頸,我們可以簡(jiǎn)單地將新的工作節(jié)點(diǎn)啟動(dòng),只需要在新的工作節(jié)點(diǎn)配置文件中配置上與線上的工作節(jié)點(diǎn)相同的ZooKeeper路徑,新的工作節(jié)點(diǎn)就會(huì)自動(dòng)加入到已存在的BinLake集群中。

3、DBS

DBS主要完成自動(dòng)化運(yùn)維的工作。它可以完成數(shù)據(jù)庫(kù)服務(wù)的自動(dòng)化交付、數(shù)據(jù)庫(kù)操作的流程化管理、數(shù)據(jù)庫(kù)健康指數(shù)全面監(jiān)控、數(shù)據(jù)庫(kù)自動(dòng)備份及結(jié)轉(zhuǎn),以及調(diào)度作業(yè)的多樣化調(diào)度(包括定時(shí)、依賴以及觸發(fā)三種調(diào)度模式)。

三、整體架構(gòu)

這是京東數(shù)據(jù)庫(kù)的一個(gè)整體架構(gòu)圖。可以看到,最底層是JDOS2.0,JDOS 2.0是京東新一代的容器技術(shù),是Docker的管理平臺(tái),實(shí)際上京東所有的數(shù)據(jù)庫(kù)服務(wù)現(xiàn)在已經(jīng)完全運(yùn)行在Docker之上了,這一點(diǎn)是讓我們比較引以為豪的工作成績(jī),而這些都離不開(kāi)京東JDOS的底層支持。

JED包括六大組件:

  • JED-Gate:實(shí)現(xiàn)分庫(kù)分表的透明化路由和審計(jì)功能。
  • JED-Ctl:命令行控制工具。
  • JED-Ctld:也提供集群控制功能,但是它是以服務(wù)的方式提供API接口。
  • Topology:是整個(gè)JED的元數(shù)據(jù)管理中心,所有的元數(shù)據(jù)是通過(guò)Topology進(jìn)行管理的。
  • JED –Tablet:是每一個(gè)MySQL前端的Proxy,提供MySQL查詢緩存和流復(fù)制等。
  • JTransfer:在線數(shù)據(jù)遷移和接入工具。

BinLake的服務(wù)角色比較簡(jiǎn)單,只有兩種服務(wù):Wave和Tower。

BinLake整個(gè)集群是完全無(wú)狀態(tài)的。我們所知道的大部分集群化服務(wù)都是有狀態(tài)集群和不對(duì)等集群。所謂不對(duì)等集群就是集群里要有Master服務(wù)角色,負(fù)責(zé)整個(gè)集群的管理;還要有Worker服務(wù)角色,負(fù)責(zé)實(shí)際任務(wù)的執(zhí)行。但整個(gè)BinLake是沒(méi)有任何Master的,只有一種服務(wù)角色:Wave,就是你的工作節(jié)點(diǎn)。Tower只是一個(gè)可以與集群進(jìn)行交互式操作的HTTP服務(wù)。Tower與傳統(tǒng)Master節(jié)點(diǎn)的不同之處在于:它不負(fù)責(zé)任何元數(shù)據(jù)的管理,它只是向Topology服務(wù)發(fā)送命令,更新或者獲取存儲(chǔ)在ETCD或ZooKeeper中的元數(shù)據(jù)信息。

DBS是構(gòu)建于我們的API Platform之上的,API Platform是我們自己開(kāi)發(fā)的一個(gè)簡(jiǎn)單的Faas平臺(tái),有了API Platform,在京東只要是會(huì)寫代碼的人,不管你用何種開(kāi)發(fā)語(yǔ)言,只要是滿足Restful協(xié)議的服務(wù),都可以注冊(cè)到API Platform中,并不斷豐富DBS。 

DBS包括幾個(gè)核心模塊:

  • JGurd 是一個(gè)分布式檢測(cè)系統(tǒng),它提供了對(duì)MySQL服務(wù)的完全分布式檢測(cè),避免了因?yàn)榫W(wǎng)絡(luò)抖動(dòng)而產(chǎn)生對(duì)MySQL健康狀況的誤判。
  • Scheduler是調(diào)度平臺(tái),是基于Oozie改造開(kāi)發(fā)的集群調(diào)度平臺(tái)。
  • JProcess Maker是DBS的流程引擎。
  • DBS-Tools是我們?cè)跀?shù)據(jù)庫(kù)運(yùn)維過(guò)程中需要用到的一些數(shù)據(jù)庫(kù)工具,比如說(shuō)AWS報(bào)告、監(jiān)控工具、Master切換工具、域名漂移工具等。
  • Authentication是京東內(nèi)部的身份認(rèn)證和權(quán)限控制組件。

下面我們針對(duì)JED、BinLake和DBS的架構(gòu)進(jìn)行詳細(xì)講解。

1、JED

JED的前端是AppServer,從整體架構(gòu)上,JED和Appserver直接打交道的只有一個(gè)角色,就是JED-Gate,JED-Gate完全兼容MySQL協(xié)議,AppServer可以一些查詢語(yǔ)句發(fā)送給JED-Gate,JED-Gate層對(duì)所有查詢的查詢執(zhí)行計(jì)劃都會(huì)做緩存,并且根據(jù)查詢執(zhí)行計(jì)劃,通過(guò)Topology服務(wù)獲得查詢所涉及表的路由源數(shù)據(jù)信息,根據(jù)元數(shù)據(jù)信息將查詢語(yǔ)句改寫或者拆分發(fā)送到底層的Shard上去。目前JED已經(jīng)滿足了廣域分布架構(gòu),實(shí)現(xiàn)了異地多活。

2、BinLake

針對(duì)上圖的BinLake架構(gòu)圖,可以看到BinLake集群中的每個(gè)工作節(jié)點(diǎn)叫做Wave,每個(gè)Wave節(jié)點(diǎn)上有多個(gè)instance,這個(gè)instance就是針對(duì)于每個(gè)MySQL實(shí)例的Binlog采集線程,在同一個(gè)Wave實(shí)例上的多個(gè)instance實(shí)例通過(guò)Epoll模型實(shí)現(xiàn)高效網(wǎng)絡(luò)監(jiān)聽(tīng)和通訊。當(dāng)用戶新采集一個(gè)MySQL的Binlog或者某個(gè)instance線程掛掉了,會(huì)根據(jù)當(dāng)前集群中各個(gè)Wave服務(wù)的健康狀況選擇一個(gè)健康度最高的Wave實(shí)例,去實(shí)例化這個(gè)新的instance線程。而每個(gè)Wave實(shí)例上的健康度是根據(jù)Zabbix的監(jiān)控?cái)?shù)據(jù)進(jìn)行動(dòng)態(tài)計(jì)算的。

從圖中可以看到,Tower服務(wù)其實(shí)沒(méi)有跟Wave服務(wù)做任何直接的通訊或者聯(lián)系,Tower只會(huì)跟ZK或ETCD集群直接做交互,它對(duì)ZK或者ETCD集群任何元數(shù)據(jù)的更改都被Wave服務(wù)及時(shí)發(fā)現(xiàn),發(fā)現(xiàn)之后,Wave服務(wù)會(huì)采取一系列相應(yīng)的措施,來(lái)對(duì)元數(shù)據(jù)的更改進(jìn)行響應(yīng)。

3、DBS

DBS依賴于兩個(gè)基礎(chǔ)的服務(wù)進(jìn)行構(gòu)建,第一個(gè)是API Platform,第二個(gè)是JDOS, 通過(guò)API Platform實(shí)現(xiàn)DBS整個(gè)系統(tǒng)所有功能模塊的完全解耦,因?yàn)樗械牡讓硬僮鞫际菃为?dú)開(kāi)發(fā)的符合Restful標(biāo)準(zhǔn)的HTTP服務(wù),并通過(guò)API Platform暴露出來(lái)。不管是研發(fā)人員還是DBA,無(wú)論使用什么樣的開(kāi)發(fā)語(yǔ)言,只要能夠開(kāi)發(fā)出符合Restful的HTTP服務(wù),就可以將其注冊(cè)到API Platform上,并實(shí)現(xiàn)DBS系統(tǒng)中特定的功能。

其實(shí)無(wú)論是JGuard、JProcessMaker、DBS-Tools還是Scheduler,它們做的所有工作都只有一樣:調(diào)用API Platform上所暴露的接口。API Platform會(huì)根據(jù)你的注冊(cè)信息,去調(diào)用Tower暴露的API接口,或者是調(diào)用MHA的一些腳本或者其它接口。

另外,不管是DBS的應(yīng)用服務(wù)器、MySQL服務(wù)器、API Platform,后端寫的所有接口,我們都會(huì)采集這些服務(wù)上的所有日志,采集了之后接入到Unilog Platform,用于后續(xù)的日志的審計(jì)和檢查。

四、實(shí)現(xiàn)細(xì)節(jié)

由于京東彈性數(shù)據(jù)庫(kù)包含的功能和組件很多,下面我選出幾個(gè)特定的功能,在實(shí)現(xiàn)細(xì)節(jié)上詳細(xì)說(shuō)明。

1、動(dòng)態(tài)在線擴(kuò)容

Step1:創(chuàng)建兩個(gè)目標(biāo)Shard

假設(shè)某個(gè)業(yè)務(wù)方在JED中起初申請(qǐng)了一個(gè)Shard,這個(gè)Shard大家可以把它簡(jiǎn)單地想象成是一套MySQL集群,這時(shí)我要將它擴(kuò)容成兩個(gè)Shard。

假設(shè)現(xiàn)在有一萬(wàn)條記錄,要擴(kuò)成兩個(gè)Shard,那么每個(gè)目標(biāo)Shard里面就有5000條。在JED里,在觸發(fā)擴(kuò)容這個(gè)動(dòng)作時(shí),首先會(huì)通過(guò) JDOS接口,將目標(biāo)Shard的所有POD都創(chuàng)建并啟動(dòng)起來(lái),如果每個(gè)目標(biāo)Shard都是1主2從,總共會(huì)啟動(dòng)6個(gè)POD,12個(gè)Container(一個(gè)POD中有2兩個(gè)Container,1個(gè)Container中是Tablet服務(wù),1個(gè)Container是MySQL服務(wù)),然后每個(gè)POD都是 Not Sevring狀態(tài),其中每三個(gè)POD實(shí)例組成一個(gè)Target shard??梢钥吹?,Source Shard中的sharding key對(duì)應(yīng)的key range是:0x00-OxFF,這里的 KeyRange也就是你的sharding key經(jīng)過(guò)哈希之后能夠落到多大的范圍,現(xiàn)在要將一個(gè)Source Shard分為兩個(gè)Target Shard,所以Source Target對(duì)應(yīng)的Key Range也要就要一分為二,可以看到兩個(gè)Target Shard 對(duì)應(yīng)的KeyRange是0x00-Ox80,Ox80-Oxff,并且是Not Serving狀態(tài)。

Step2:全量數(shù)據(jù)過(guò)濾克隆

兩個(gè)Target Shard建立之后,會(huì)根據(jù)ETCD里的默認(rèn)配置針對(duì)每個(gè)Target Shard建立MySQL的復(fù)制關(guān)系,比如一主兩從:一個(gè)Master,一個(gè)Replication,一個(gè)ReadOnly;一主三從,一個(gè)Master,兩個(gè)Replication,一個(gè)Readonly;一主四從,一個(gè)Master,兩個(gè)Replication和兩個(gè)ReadOnly。

建立完復(fù)制關(guān)系之后,首先會(huì)通過(guò)JED-Worker將Source Shard中的Schema信息復(fù)制到兩個(gè)TargetShard中,然后將Source Shard中的ReadOnly Pod從MySQL復(fù)制關(guān)系中摘除下來(lái),最后通過(guò)JED-Worker將ReadOnly中的數(shù)據(jù)過(guò)濾拷貝到兩個(gè)TargetShard中。

Step3:增量數(shù)據(jù)過(guò)濾到兩個(gè)目標(biāo)Shard

現(xiàn)在我們以最簡(jiǎn)單的一拖二的方式來(lái)講述。當(dāng)你的兩個(gè)TargetShard建立完成后,你要做的就是先把你的這一萬(wàn)行記錄拷到兩個(gè)shard上,拷完之后去建立過(guò)濾復(fù)制。

完成了Step2的過(guò)濾拷貝之后,將ReadOnly重新掛到Source Shard上,然后JED-Worker通過(guò)Replication中的接口創(chuàng)建binlog的過(guò)濾復(fù)制,會(huì)在Replication上啟動(dòng)兩個(gè)協(xié)程,并根據(jù)Target Shard的Key Range分別將binlog復(fù)制到對(duì)應(yīng)的TargetShard上。

Step4:數(shù)據(jù)一致性校驗(yàn)

當(dāng)TargetShard中的binglog與SourceShard中的binlog的lag小于5秒的時(shí)候,會(huì)啟動(dòng)數(shù)據(jù)的一致性校驗(yàn),該過(guò)程是在JED-Worker上完成的。過(guò)程很簡(jiǎn)單,就是通過(guò)大量的后臺(tái)協(xié)程Target和Source上去取出數(shù)據(jù)一條一條對(duì)比,如果數(shù)據(jù)的一致性校驗(yàn)通過(guò),就開(kāi)始進(jìn)行Shard切換。

Step5:切Shard

首先將SourceShard中Slave的Serving狀態(tài)切換成Not Serving,同事將TargetShard中Slave的Not Serving狀態(tài)更改為Serving,最后將Source中的Master停寫,等Target中的Master與Source中的Master無(wú)復(fù)制延時(shí)后,將Source Master停寫,通過(guò)JED-Worker將過(guò)濾復(fù)制斷掉,然后將Target的Master置為Serving狀態(tài),并接受寫入。

上述的所有Serving與NotServing狀態(tài)的改變均是通過(guò)改變etcd中的元數(shù)據(jù)來(lái)完成的。當(dāng)前端性業(yè)務(wù)再發(fā)送新的查詢過(guò)來(lái)時(shí),Gate就會(huì)根據(jù)最新的元數(shù)據(jù)信息,將你的這條SQL發(fā)送到最新的Target Shard。

2、自動(dòng)FailOver

以1主3從的MySQL主從架構(gòu)對(duì)JED的自動(dòng)FailOver機(jī)制進(jìn)行說(shuō)明。

如果Master發(fā)生異常,JGuard會(huì)通過(guò)分布式檢測(cè)(JGuard是通過(guò)ORC改造之后形成了一個(gè)分支檢測(cè)服務(wù))檢測(cè)異常,檢測(cè)到異常之后會(huì)通過(guò)郵件和短信通知業(yè)務(wù)接口人,通知完之后,不會(huì)等業(yè)務(wù)接口人進(jìn)行處理,直接從當(dāng)前整個(gè)MySQL集群當(dāng)中選擇一個(gè)GTID最大的一個(gè)MySQL實(shí)例,將這個(gè)MySQL實(shí)例切成Master,并根據(jù)新的Master重建新MySQL主從復(fù)制關(guān)系,將剩余的Replication和ReadOnly重新掛載到新的Master上,再調(diào)用JED-Ctrld服務(wù)的接口更新ETCD中的元數(shù)據(jù),這樣后續(xù)的DDL/DML就會(huì)發(fā)到最新的Master之上。最后缺失的一個(gè)Tablet需要人工補(bǔ)入。

3、Streaming Process

JED實(shí)現(xiàn)了查詢的流式處理,以查詢語(yǔ)句select table_a.age from table_a order by table_a.age為例說(shuō)明流式處理的過(guò)程。JED-Gate接收到該查詢語(yǔ)句之后,會(huì)根據(jù)ETCD中的分片元數(shù)據(jù),將該語(yǔ)句分發(fā)到三個(gè)Shard中,各個(gè)Shard返回給JED-Gate數(shù)據(jù)本身就是有序的,在JED-Gate中針對(duì)每個(gè)Shard都會(huì)有一個(gè)buffer與之對(duì)應(yīng),每個(gè)buffer用來(lái)流式的接收每個(gè)Shard返回的排序完畢的數(shù)據(jù),因此該buffer中的數(shù)據(jù)也是有序的。然后將每個(gè)buffer的首地址存儲(chǔ)到一個(gè)PriorityQueue里面, PriorityQueue是一個(gè)堆排序的優(yōu)先級(jí)隊(duì)列,會(huì)根據(jù)每個(gè)buffer中的首元素不斷的進(jìn)行排序。每從PriorityQueue中取出一個(gè)元素,PriorityQueue都會(huì)調(diào)整Buffer的先后順序,JED-Gate會(huì)將元數(shù)一個(gè)一個(gè)地取出來(lái),以流式的方式發(fā)給前端,從而實(shí)現(xiàn)整體流式排序。

4、Join處理

現(xiàn)在我們看下如何在JED上執(zhí)行Join查詢的,在下面所有的說(shuō)明中,我們都有一個(gè)假設(shè)條件,就是所有的表的sharding key都是ID。

對(duì)Join查詢的處理,要分情況:

第一種情況:Join Key與Sharding Key相同。這種情況下由于Join Key 和 Sharding  Key是完全相同的,因此是可以將Join查詢語(yǔ)句直接發(fā)送到下面的每個(gè)shard,在JED-Gate匯聚各個(gè)shard的部分查詢結(jié)果,并返回給前端應(yīng)用。

第二種情況:Join Key與Sharding Key相同。如上圖所示,比如Select a.col,b.col.from a join b on b.id_2=a.id where a.id=0。針對(duì)該查詢語(yǔ)句,JED-Gate首先對(duì)其進(jìn)行SQL語(yǔ)句改寫,改寫為兩條語(yǔ)句:select a.col,a.id from a where a.id=0和select b.col from b where b.id_2=a.id。在第二個(gè)查詢語(yǔ)句中的a.id是綁定變量。JED-Gate會(huì)首先根據(jù)select a.col,a.id from a where a.id=0,定位到該SQL需要定位到哪個(gè)shard,然后將SQL發(fā)送到相應(yīng)的Shard執(zhí)行,并流式的獲取其結(jié)果,然后將結(jié)果中的a.id字段的值取出,并將值賦給select b.col from b where b.id_2=a.id語(yǔ)句中的綁定變量a.id,然后將復(fù)制后的第二條SQL語(yǔ)句依次發(fā)送給所有的shard,并將結(jié)果與第一條SQL語(yǔ)句中的結(jié)果組合,流式地返回給前端。

當(dāng)多級(jí)Join的時(shí)候,也是相同的思路,這里不再贅述。

5、BinLake元數(shù)據(jù)架構(gòu)圖

前面已經(jīng)提到BinLake有一個(gè)很大的特點(diǎn):一個(gè)完全無(wú)狀態(tài)的集群,沒(méi)有Master管理節(jié)點(diǎn)。而要實(shí)現(xiàn)這個(gè)特性最重要的就是要有合理的元數(shù)據(jù)設(shè)計(jì)。之所以沒(méi)有Master節(jié)點(diǎn),是因?yàn)榘袽aster節(jié)點(diǎn)的功能委托給了ZooKeeper或ETCD。通過(guò)借助ZooKeeper中的ephemeral znode實(shí)現(xiàn)了Wave服務(wù)乃至instance的自動(dòng)發(fā)現(xiàn)和HA,并最終實(shí)現(xiàn)了無(wú)Master,無(wú)狀態(tài)的完全對(duì)等集群。

根據(jù)上面的元數(shù)據(jù)架構(gòu)我們對(duì)BinLake的所有元數(shù)據(jù)進(jìn)行詳細(xì)說(shuō)明。

一個(gè)BinLake集群的root znode是一個(gè)名為wave的znode,在wave之下是一系列的形式為:“MySQL域名命名:port”的znode。這樣的每個(gè)znode都對(duì)應(yīng)了一個(gè)MySQL實(shí)例。而在每個(gè)MySQL實(shí)例對(duì)應(yīng)的znode下面是該MySQL實(shí)例的管理、信息保存和選舉znode。其中counter節(jié)點(diǎn)中記錄了當(dāng)前MySQL實(shí)例對(duì)應(yīng)的instanc重啟了幾次,若連續(xù)重啟超過(guò)7次,就會(huì)發(fā)出報(bào)警信息。而dynamic節(jié)點(diǎn)則記錄了每個(gè)MySQL實(shí)例對(duì)應(yīng)的Binlog采集線程對(duì)應(yīng)的快照信息,包括:當(dāng)前采集到的Binlog文件、Offset、Timestamp、GTID、最近的10個(gè)時(shí)間點(diǎn)Binglog位置和Filter Rules等,從而保證instance重啟后,可以利用這些信息繼續(xù)進(jìn)行Binlog采集。后面的sequencenumber對(duì)應(yīng)的一系列znode是由Curator自動(dòng)創(chuàng)建的znode,來(lái)保證選舉的正確性和防止羊群效應(yīng)。而“Bingdleader:wavehost”對(duì)應(yīng)的znode,主要用于人工介入binlake,從而指定讓下次instance leader選舉的時(shí)候,固定在wavehost對(duì)應(yīng)的Wave節(jié)點(diǎn)上。

如果我某個(gè)MySQL采集的Instance掛了,Curator就會(huì)在后面的第一個(gè)znode對(duì)應(yīng)的wave服務(wù)上首先進(jìn)行l(wèi)eader選舉,若成功選舉,就接入,否則依次對(duì)后面對(duì)應(yīng)的每個(gè)Wave實(shí)例進(jìn)行選舉,直到成功選舉出leader。選舉出新的leader之后,就會(huì)在對(duì)應(yīng)的Wave服務(wù)上重啟Binlog采集的instance線程,該instance就會(huì)根據(jù)dynamic znode中存儲(chǔ)的快照信息重建MySQL的復(fù)制關(guān)系,繼續(xù)進(jìn)行Binlog采集。

6、集群化Binlog訂閱

BinLake中的Binlog采集方式有兩種:時(shí)序和亂序。

時(shí)序:通過(guò)NIO實(shí)現(xiàn)的類似Epoll的網(wǎng)絡(luò)模型監(jiān)聽(tīng)所有與MySQL之間的鏈接的網(wǎng)絡(luò)事件等檢測(cè)到與某個(gè)MySQL之間的連接有byte流到達(dá)時(shí),就會(huì)盡量多的讀取所有的byte流,將其全部放到一個(gè)Byte Buffer里,然后通過(guò)Worker Thread對(duì)ByteBuffer中的Byte進(jìn)行Decode,并解析成一個(gè)個(gè)的EventMsg,進(jìn)而將EventMsg也放到一個(gè)MessageBuffer中,在MessageBuffer后面有一個(gè)Handler線程,這個(gè)Handler線程會(huì)根據(jù)ZooKeeper里的一些元數(shù)據(jù)信息(比如:Topics、FilterRules、MQ類型和地址等)對(duì)EventMessage進(jìn)行處理,然后使用protobuff進(jìn)行序列化后發(fā)送到正確MQ中的特定的Topic里。這里的處理包括:根據(jù)庫(kù)表類型過(guò)濾、列過(guò)濾、事務(wù)頭Event和尾Event過(guò)濾等。

亂序:同從上圖中可以看出亂序處理與時(shí)序處理的前半部分是相同的,只是在EventMessage Buffer后面是通過(guò)線程池進(jìn)行并發(fā)處理的,測(cè)試結(jié)果表明亂序處理的性能是時(shí)序處理性能的10倍。

五、落地使用

從上圖可以看出,JED數(shù)據(jù)庫(kù)中間件服務(wù)通過(guò)JTransfer來(lái)實(shí)現(xiàn)MySQL和JED之間的數(shù)據(jù)正反向同步和傳輸?,F(xiàn)在JED可以實(shí)現(xiàn)MySQL向Oracle、Postgres等多種數(shù)據(jù)庫(kù)的實(shí)時(shí)數(shù)據(jù)同步和傳輸。BinLake可以對(duì)MySQL和JED中的Binlog進(jìn)行采集,并發(fā)送到JMQ或者Kafka,在MQ后端有兩種使用方式:

通過(guò)Spark Streaming把它同步到HBase里,目前京東內(nèi)部實(shí)際上是有一個(gè)項(xiàng)目叫做實(shí)時(shí)數(shù)據(jù)快照,就是通過(guò)這種方式,實(shí)現(xiàn)了HBase中的數(shù)據(jù)與線上MySQL實(shí)例中的數(shù)據(jù)的完全實(shí)時(shí)同步更新。

下游各個(gè)業(yè)務(wù)部門各自通過(guò)Consumer消費(fèi),進(jìn)而進(jìn)行訂單積壓監(jiān)控、智能報(bào)表以及營(yíng)銷實(shí)時(shí)推薦等。當(dāng)然JED以及BinLake、Jtransfer都是通過(guò)DBS進(jìn)行自動(dòng)化運(yùn)維、調(diào)度和管理的。

京東彈性數(shù)據(jù)庫(kù)落地狀況

這些是在9月份從DBS系統(tǒng)里面拿到的,服務(wù)線上業(yè)務(wù)是指上線項(xiàng)目的個(gè)數(shù),目前京東彈性數(shù)據(jù)庫(kù)服務(wù)了線上3122個(gè)項(xiàng)目,管理的MySQL實(shí)例個(gè)數(shù)有將近兩萬(wàn)個(gè),管理的Table就比較多了,有660多萬(wàn)個(gè),并且完成了自動(dòng)在線切換2700余次,自動(dòng)化上線有27000余次。現(xiàn)在京東有一般的業(yè)務(wù)都遷到了JED上,當(dāng)然還有一半的業(yè)務(wù)正在容器化的MySQL服務(wù)上并逐步地進(jìn)行遷移。

分片數(shù)與OPS、延時(shí)的關(guān)系情況

上圖是JED的分片數(shù)與OPS以及分片數(shù)延時(shí)的一些關(guān)系。從圖中可以看出,隨著分片數(shù)的增加JED的服務(wù)能力也出現(xiàn)線性增長(zhǎng)的趨勢(shì)。而隨著分片數(shù)的增加延時(shí)幾乎沒(méi)有變化(延時(shí)的單位是毫秒)。

Gate數(shù)與OPS、延時(shí)的關(guān)系情況

上圖是Gate數(shù)目與OPS以及Gate數(shù)目與延時(shí)的關(guān)系。從圖中可以看出,通過(guò)簡(jiǎn)單的增加Gate的數(shù)目而實(shí)現(xiàn)JED數(shù)據(jù)庫(kù)服務(wù)能力的橫向擴(kuò)展,不會(huì)導(dǎo)致明顯的延時(shí)增加。

問(wèn)答環(huán)節(jié)  

【問(wèn)題1】想咨詢一下咱們的JED做故障切換之后,如果存在數(shù)據(jù)的復(fù)制延遲,這時(shí)直接把它切為Read  Write狀態(tài),有部分的Binlog數(shù)據(jù)還沒(méi)追上來(lái),臟數(shù)據(jù)怎么辦?這部分臟數(shù)據(jù)是人工介入進(jìn)行處理,還是有什么其它方案來(lái)把它自動(dòng)處理?

答:JED在做Master FailOver時(shí),實(shí)際就是你在后端做分片的時(shí)候,看MySQL的復(fù)制模式是半同步還是異步,如果是半同步,一旦發(fā)現(xiàn)你的Master Fail Over,不會(huì)出現(xiàn)所有Slave都lag Master的Binlog。

追問(wèn):就是說(shuō)在Binlog追上之前還是ReadOnly狀態(tài),binlog完全追上之后,才切換為ReadWrite嗎?

答:舉個(gè)例子,比如說(shuō)你后端Master下掛了兩個(gè)Slave或者是多個(gè)Slave,因?yàn)槟銌⒂玫氖前胪?,那么只要你里面沒(méi)有任何一個(gè)追上Master(相當(dāng)于是你的Master都是 ReadOnly狀態(tài)),這個(gè)并不是說(shuō)在Failover里存在這個(gè)問(wèn)題,而是即使單純的MySQL服務(wù)啟用的若是半同步,當(dāng)沒(méi)有任何一個(gè)Slave追上Mater的時(shí)候,Master肯定是ReadOnly。    

【問(wèn)題2】老師好,因?yàn)閯偛盼衣?tīng)了JED,想問(wèn)一下JED里有沒(méi)有異構(gòu)數(shù)據(jù)庫(kù)?比如說(shuō),如果我要像你說(shuō)到的有互相轉(zhuǎn)這種情況,那么我要同時(shí)轉(zhuǎn)幾個(gè)表,在不同的異構(gòu)數(shù)據(jù)庫(kù)里面,我要如何保證它的查詢速率?比如說(shuō)各個(gè)表,我同事要加一個(gè)索引,我有沒(méi)有統(tǒng)一配置的情況,還是集群里的每個(gè)庫(kù)都要重新再各配一次?

答:說(shuō)實(shí)話,沒(méi)聽(tīng)太清楚你說(shuō)什么,就說(shuō)一個(gè)實(shí)際的例子吧,你的意思就是說(shuō)JED里面有一個(gè)庫(kù),實(shí)際上就叫KeySpace,下面有四個(gè)分庫(kù)或者四個(gè)分表你現(xiàn)在要統(tǒng)一對(duì)KeySpace中的所有分庫(kù)或者分表加索引,它怎么去做,是嗎?

追問(wèn):是每個(gè)分庫(kù)都要加嗎?這樣的話是不是每個(gè)分表都要加一條索引,有沒(méi)有可以統(tǒng)一一次性配置的功能?

答:在JED里面實(shí)際上是有一個(gè)控制臺(tái)的,目前不支持直接通過(guò)Gate執(zhí)行DDL,就是說(shuō)DDL在Client或是通過(guò)JBDC Driver是不允許執(zhí)行的,直接就會(huì)報(bào)錯(cuò),你如果要執(zhí)行DDL,是通過(guò)DBS自動(dòng)化上線流程通過(guò)JED Ctld服務(wù)去執(zhí)行的,Ctld服務(wù)會(huì)找到你KeySpace下的所有Shard,然后在每個(gè)Shard里面去執(zhí)行這些DDL。        

【問(wèn)題3】有兩個(gè)問(wèn)題想請(qǐng)教一下,一是剛才演講中聽(tīng)您說(shuō)這個(gè)彈性數(shù)據(jù)庫(kù)有好和壞的東西,那我能不能單獨(dú)用一個(gè)組件一樣的東西直接移植到JED上,其它東西不用行不行?我這邊的這個(gè)數(shù)據(jù)庫(kù)是主要是可以擴(kuò)容的,但我們業(yè)務(wù)簡(jiǎn)單一點(diǎn),可能沒(méi)那么多。

答:京東彈性數(shù)據(jù)庫(kù)現(xiàn)在包括三大模塊,你可以單獨(dú)地去用JED或者BinLake,但你不能夠單獨(dú)去用DBS,因?yàn)槟闳绻麊为?dú)用JED或者BinLake,你是可以脫離京東的自動(dòng)化運(yùn)維管理系統(tǒng)的控制,后續(xù)的審批當(dāng)然是沒(méi)有了的,可你對(duì)于BinLake這個(gè)集群以及JED的管理,是完全依賴于它的API是做控制的,就是說(shuō),后續(xù)假如說(shuō)你公司有自己的一套運(yùn)維管理系統(tǒng),你可以基于BinLake或者JED的API,跟你的自動(dòng)化運(yùn)維管理系統(tǒng)集成,這個(gè)沒(méi)問(wèn)題,但你如果只用DBS就不行了,因?yàn)镈BS是完全地跟京東的JDOS耦合的,這就是為什么我們可以實(shí)現(xiàn)數(shù)據(jù)庫(kù)服務(wù)資源的一個(gè)自動(dòng)化交付和自動(dòng)化運(yùn)維,實(shí)際上是建立在這個(gè)JDOS之上的,因?yàn)榫〇|所有的數(shù)據(jù)庫(kù)都已經(jīng)上Docker了,所有的數(shù)據(jù)庫(kù)服務(wù)均運(yùn)行在Docker里,不管是JED還是傳統(tǒng)的MySQL服務(wù),都是運(yùn)行在Docker之上的,所以說(shuō)你只能夠單獨(dú)地用其中兩個(gè)組件,一個(gè)是BinLake,一個(gè)是JED。

追問(wèn):另外一個(gè)問(wèn)題就是說(shuō),因?yàn)槟阏f(shuō)的三個(gè)模板塊,那么現(xiàn)在這個(gè)彈性數(shù)據(jù)庫(kù)有沒(méi)有可能做成一個(gè)像包一樣的形式或一個(gè)統(tǒng)一的安裝軟件之類的東西,有沒(méi)有這樣的計(jì)劃呢?

答:先回答第一個(gè)問(wèn)題,三個(gè)模塊是不會(huì)合到一塊的,因?yàn)槲覀冎园阉珠_(kāi)就是為了實(shí)現(xiàn)解耦,我們現(xiàn)在正在啟動(dòng)內(nèi)部的一些私有云的數(shù)據(jù)庫(kù)服務(wù),就是說(shuō)后續(xù)對(duì)于我們京東內(nèi)部的用戶來(lái)說(shuō),你只需要申請(qǐng)就行了,有點(diǎn)像你用阿里的RDS一樣,但我們不會(huì)對(duì)外提供服務(wù),同時(shí)我們的JED和BinLake馬上就會(huì)開(kāi)源了,你馬上就可以使用到了。 

責(zé)任編輯:龐桂玉 來(lái)源: DBAplus社群
相關(guān)推薦

2018-12-13 11:00:44

阿里數(shù)據(jù)庫(kù)彈性

2017-01-17 15:14:49

MySQL數(shù)據(jù)庫(kù)自動(dòng)化

2011-07-06 14:12:20

MySQLPercona

2011-07-06 10:49:50

MySQL優(yōu)化

2023-11-17 07:30:30

線段pgvector實(shí)踐

2024-10-15 08:14:51

2017-06-08 11:06:03

數(shù)據(jù)庫(kù)架構(gòu)分組

2022-05-09 15:54:44

平安科技TiDB云原生

2017-06-10 11:13:39

數(shù)據(jù)庫(kù)架構(gòu)數(shù)據(jù)庫(kù)集群

2010-02-01 10:10:41

Oracle數(shù)據(jù)庫(kù)優(yōu)化

2022-06-30 10:56:18

字節(jié)云數(shù)據(jù)庫(kù)存儲(chǔ)

2023-02-01 18:08:55

應(yīng)用數(shù)據(jù)庫(kù)TiDB

2017-09-20 09:58:21

數(shù)據(jù)庫(kù)“狀態(tài)”字段設(shè)計(jì)

2012-07-09 15:28:53

CitusDB

2024-09-22 10:06:04

2023-11-15 09:38:49

Oracle數(shù)據(jù)庫(kù)

2017-01-10 16:04:02

容器MySQL實(shí)踐

2013-10-08 09:54:41

數(shù)據(jù)庫(kù)安全數(shù)據(jù)庫(kù)管理

2016-08-23 14:43:01

數(shù)據(jù)庫(kù)Oracle性能

2022-02-14 09:00:00

SQLNoSQL數(shù)據(jù)庫(kù)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)