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

直擊京東新一代數(shù)據(jù)庫(kù)技術(shù):如何實(shí)現(xiàn)極致彈性能力?

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

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

[[216850]]

京東彈性數(shù)據(jù)庫(kù)主要包括三大功能模塊:

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

今天分為五個(gè)部分進(jìn)行分享:

  • 發(fā)展歷程
  • 功能特性
  • 整體架構(gòu)
  • 實(shí)現(xiàn)細(xì)節(jié)
  • 使用情況

發(fā)展歷程

在 2011 年,我加入京東之初,京東的數(shù)據(jù)庫(kù)正處于諸侯混戰(zhàn)的階段,各種數(shù)據(jù)庫(kù)都有,包括:MySQL、PostGre、Oracle、SQL Sever。

在 2011 年之后,開始去 IOE,到了 2014 年,京東基本上完成了去 IOE,所有的業(yè)務(wù)系統(tǒng)都遷移到了 MySQL 上。

在大規(guī)模使用 MySQL 的過程中,我們發(fā)現(xiàn),隨著業(yè)務(wù)數(shù)據(jù)量的增長(zhǎng),很多業(yè)務(wù)開始了漫長(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í)我們開始重新思考應(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 年開發(fā)了 JProxy,優(yōu)先解決緊急的業(yè)務(wù)和運(yùn)維難題:分庫(kù)分表規(guī)則統(tǒng)一化和路由透明化。

在拿到充分的時(shí)間 buffer 后,我們從 2016 年開始以匠人的精神精雕細(xì)琢京東彈性數(shù)據(jù)庫(kù)。

功能特性

京東彈性數(shù)據(jù)庫(kù)是一個(gè)產(chǎn)品系列,主要是解決數(shù)據(jù)庫(kù)的運(yùn)維、使用和研發(fā)過程中的問題,具備動(dòng)態(tài)伸縮、高可用、查詢透明路由、集群化日志服務(wù)和自動(dòng)化運(yùn)維等功能,現(xiàn)就京東彈性數(shù)據(jù)庫(kù)三個(gè)核心模塊的功能進(jìn)行詳細(xì)說明。

JED(JD Elastic DataBase)

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

在線動(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è)問題,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ò)容。

自動(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 上。

兼容 MySQL 協(xié)議

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

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

我們基于 ghost 進(jìn)行改造,開發(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)沒有問題,業(yè)務(wù)方直接將數(shù)據(jù)庫(kù)連接指向到 JED 就可以正常提供服務(wù)了。

數(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ù)面影響。

BinLake

BinLake 只做一樣工作:集群化 Binlog 的采集和訂閱服務(wù)。

在 BinLake 之前,我們使用 Canal 進(jìn)行 Binlog 采集,但我們發(fā)現(xiàn)存在資源浪費(fèi)等問題:若一個(gè)業(yè)務(wù)需要采集 MySQL Binlog,并且還需要 HA 保證的話,我們至少需要兩臺(tái)服務(wù)器。

那多個(gè)業(yè)務(wù)怎么辦?于是我們開發(fā)了 BinLake,其功能特性如下:

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

BinLake 是一個(gè)集群化的 BinLog 采集和訂閱服務(wù),并且與常規(guī)意義上的集群不一樣,我們的集群是沒有 Master 節(jié)點(diǎn)的。

而且集群中的所有工作節(jié)點(diǎn)都是完全平等的,這也就意味著,只要集群中的節(jié)點(diǎn)沒有全部宕機(jī),BinLake 集群可以一直提供服務(wù)。

高可用與自動(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ù)。

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

假設(shè)所有 BinLog 的集群有八個(gè)節(jié)點(diǎn),其中有七個(gè)節(jié)點(diǎn)的負(fù)載比較高。

當(dāng)你在接入 BinLog 時(shí),在沒有人工介入的衡量下,整個(gè)集群將以新接入的一個(gè) instance 采集實(shí)例,自動(dòng)選擇一個(gè)健康度最高的 Wave 服務(wù),然后啟動(dòng) BinLog 采集。

支持多種 MQ

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

支持集群橫向擴(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 集群中。

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ī),而這些都離不開京東 JDOS 的底層支持。

JED 包括六大組件:

  • JED-Gate:實(shí)現(xiàn)分庫(kù)分表的透明化路由和審計(jì)功能。
  • JED-Ctl:命令行控制工具。
  • JED-Ctld:也提供集群控制功能,但是它是以服務(wù)的方式提供 API 接口。
  • Topology:是整個(gè) JED 的元數(shù)據(jù)管理中心,所有的元數(shù)據(jù)是通過 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 是沒有任何 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 是我們自己開發(fā)的一個(gè)簡(jiǎn)單 Faas 平臺(tái)。

有了 API Platform,在京東只要是會(huì)寫代碼的人,不管你用何種開發(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 改造開發(fā)的集群調(diào)度平臺(tái)。
  • JProcess Maker 是 DBS 的流程引擎。
  • DBS-Tools 是我們?cè)跀?shù)據(jù)庫(kù)運(yùn)維過程中需要用到的一些數(shù)據(jù)庫(kù)工具,比如說 AWS 報(bào)告、監(jiān)控工具、Master 切換工具、域名漂移工具等。
  • Authentication 是京東內(nèi)部的身份認(rèn)證和權(quán)限控制組件。

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

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ì)劃,通過 Topology 服務(wù)獲得查詢所涉及表的路由源數(shù)據(jù)信息,根據(jù)元數(shù)據(jù)信息將查詢語(yǔ)句改寫或者拆分發(fā)送到底層的 Shard 上去。

目前 JED 已經(jīng)滿足了廣域分布架構(gòu),實(shí)現(xiàn)了異地多活。

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í)例通過 Epoll 模型實(shí)現(xiàn)高效網(wǎng)絡(luò)監(jiān)聽和通訊。

當(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í)沒有跟 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)。

DBS

DBS 依賴于兩個(gè)基礎(chǔ)的服務(wù)進(jìn)行構(gòu)建,第一個(gè)是 API Platform,第二個(gè)是 JDOS。

通過 API Platform 實(shí)現(xiàn) DBS 整個(gè)系統(tǒng)所有功能模塊的完全解耦,因?yàn)樗械牡讓硬僮鞫际菃为?dú)開發(fā)的符合 Restful 標(biāo)準(zhǔn)的 HTTP 服務(wù),并通過 API Platform 暴露出來(lái)。

不管是研發(fā)人員還是 DBA,無(wú)論使用什么樣的開發(fā)語(yǔ)言,只要能夠開發(fā)出符合 Restful 的 HTTP 服務(wù),就可以將其注冊(cè)到 API Platform 上,并實(shí)現(xiàn) DBS 系統(tǒng)中特定的功能。

無(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ì)說明。

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

Step 1:創(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ì)通過 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)過哈希之后能夠落到多大的范圍。

現(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)。

Step 2:全量數(shù)據(jù)過濾克隆

兩個(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ì)通過 JED-Worker 將 Source Shard 中的 Schema 信息復(fù)制到兩個(gè) TargetShard 中。

然后將 Source Shard 中的 ReadOnly Pod 從 MySQL 復(fù)制關(guān)系中摘除下來(lái)。

最后通過 JED-Worker 將 ReadOnly 中的數(shù)據(jù)過濾拷貝到兩個(gè) TargetShard 中。

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

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

完成了 Step2 的過濾拷貝之后,將 ReadOnly 重新掛到 Source Shard 上。

然后 JED-Worker 通過 Replication 中的接口創(chuàng)建 Binlog 的過濾復(fù)制,會(huì)在 Replication 上啟動(dòng)兩個(gè)協(xié)程,并根據(jù) TargetShard 的 KeyRange 分別將 Binlog 復(fù)制到對(duì)應(yīng)的 TargetShard 上。

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

當(dāng) TargetShard 中的 Binglog 與 SourceShard 中的 Binlog 的 lag 小于 5 秒的時(shí)候,會(huì)啟動(dòng)數(shù)據(jù)的一致性校驗(yàn),該過程是在 JED-Worker 上完成的。

過程很簡(jiǎn)單,就是通過大量的后臺(tái)協(xié)程 Target 和 Source 上去取出數(shù)據(jù)一條一條對(duì)比,如果數(shù)據(jù)的一致性校驗(yàn)通過,就開始進(jìn)行 Shard 切換。

Step 5:切 Shard

首先將 SourceShard 中 Slave 的 Serving 狀態(tài)切換成 Not Serving,同時(shí)將 TargetShard 中 Slave 的 Not Serving 狀態(tài)更改為 Serving。

最后將 Source 中的 Master 停寫,等 Target 中的 Master 與 Source 中的 Master 無(wú)復(fù)制延時(shí)后,將 Source Master 停寫,通過 JED-Worker 將過濾復(fù)制斷掉,然后將 Target 的 Master 置為 Serving 狀態(tài),并接受寫入。

上述的所有 Serving 與 Not Serving 狀態(tài)的改變均是通過改變 ETCD 中的元數(shù)據(jù)來(lái)完成的。

當(dāng)前端性業(yè)務(wù)再發(fā)送新的查詢過來(lái)時(shí),Gate 就會(huì)根據(jù)最新的元數(shù)據(jù)信息,將你的這條 SQL 發(fā)送到最新的 TargetShard。

自動(dòng) FailOver

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

如果 Master 發(fā)生異常,JGuard 會(huì)通過分布式檢測(cè)(JGuard 是通過 ORC 改造之后形成的一個(gè)分支檢測(cè)服務(wù))檢測(cè)異常。

檢測(cè)到異常之后會(huì)通過郵件和短信通知業(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ǔ)入。

Streaming Process

JED 實(shí)現(xiàn)了查詢的流式處理,以查詢語(yǔ)句 select table_a.age from table_a order by table_a.age 為例說明流式處理的過程。

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)整體流式排序。

Join 處理

現(xiàn)在我們看下如何在 JED 上執(zhí)行 Join 查詢的,在下面所有的說明中,我們都有一個(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í)候,也是相同的思路,這里不再贅述。

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

前面已經(jīng)提到 BinLake 有一個(gè)很大的特點(diǎn):一個(gè)完全無(wú)狀態(tài)的集群,沒有 Master 管理節(jié)點(diǎn),而要實(shí)現(xiàn)這個(gè)特性最重要的就是要有合理的元數(shù)據(jù)設(shè)計(jì)。

之所以沒有 Master 節(jié)點(diǎn),是因?yàn)榘?Master 節(jié)點(diǎn)的功能委托給了 ZooKeeper 或 ETCD。

通過借助 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ì)說明。

一個(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ù)重啟超過 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)行 leader 選舉。

若成功選舉,就接入,否則依次對(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 采集。

集群化 Binlog 訂閱

BinLake 中的 Binlog 采集方式有兩種:

  • 時(shí)序
  • 亂序

時(shí)序:通過 NIO 實(shí)現(xiàn)的類似 Epoll 的網(wǎng)絡(luò)模型監(jiān)聽所有與 MySQL 之間的鏈接的網(wǎng)絡(luò)事件等,檢測(cè)到與某個(gè) MySQL 之間的連接有 byte 流到達(dá)時(shí),就會(huì)盡量多的讀取所有的 byte 流。

將其全部放到一個(gè) Byte Buffer 里,然后通過 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ù)表類型過濾、列過濾、事務(wù)頭 Event 和尾 Event 過濾等。

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

落地使用

從上圖可以看出,JED 數(shù)據(jù)庫(kù)中間件服務(wù)通過 JTransfer 來(lái)實(shí)現(xiàn) MySQL 和 JED 之間的數(shù)據(jù)正反向同步和傳輸。

現(xiàn)在 JED 可以實(shí)現(xiàn) MySQL 向 Oracle、Postgre 等多種數(shù)據(jù)庫(kù)的實(shí)時(shí)數(shù)據(jù)同步和傳輸。

BinLake 可以對(duì) MySQL 和 JED 中的 Binlog 進(jìn)行采集,并發(fā)送到 JMQ 或者 Kafka。

在 MQ 后端有兩種使用方式:

  • 通過 Spark Streaming 把它同步到 HBase 里,目前京東內(nèi)部實(shí)際上是有一個(gè)項(xiàng)目叫做實(shí)時(shí)數(shù)據(jù)快照,就是通過這種方式,實(shí)現(xiàn)了 HBase 中的數(shù)據(jù)與線上 MySQL 實(shí)例中的數(shù)據(jù)的完全實(shí)時(shí)同步更新。
  • 下游各個(gè)業(yè)務(wù)部門各自通過 Consumer 消費(fèi),進(jìn)而進(jìn)行訂單積壓監(jiān)控、智能報(bào)表以及營(yíng)銷實(shí)時(shí)推薦等。當(dāng)然 JED 以及 BinLake、Jtransfer 都是通過 DBS 進(jìn)行自動(dòng)化運(yùn)維、調(diào)度和管理的。

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

這些是在 9 月份從 DBS 系統(tǒng)里面拿到的數(shù)據(jù),服務(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í)幾乎沒有變化(延時(shí)的單位是毫秒)。

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

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

[[216856]]

呂信,京東商城數(shù)據(jù)庫(kù)技術(shù)部資深架構(gòu)師,擁有多年數(shù)據(jù)產(chǎn)品研發(fā)及架構(gòu)經(jīng)驗(yàn)。在京東及國(guó)內(nèi)主導(dǎo)多種數(shù)據(jù)產(chǎn)品開發(fā)及社區(qū)建設(shè),積極活躍于數(shù)據(jù)產(chǎn)品領(lǐng)域,對(duì)數(shù)據(jù)庫(kù)及大數(shù)據(jù)領(lǐng)域各個(gè)產(chǎn)品具有豐富經(jīng)驗(yàn),目前在京東商城主導(dǎo)彈性數(shù)據(jù)庫(kù)研發(fā)及推廣使用。

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

2010-05-10 16:25:49

2021-06-10 14:01:38

大數(shù)據(jù)數(shù)據(jù)平臺(tái)數(shù)據(jù)湖

2021-06-10 09:00:00

數(shù)據(jù)湖架構(gòu)數(shù)據(jù)平臺(tái)

2024-03-04 07:55:41

數(shù)據(jù)架構(gòu)AlluxioNewsBreak

2025-04-17 03:00:00

dbt數(shù)據(jù)轉(zhuǎn)換工具開源

2011-03-23 16:26:30

數(shù)據(jù)變革

2011-02-15 10:02:54

數(shù)據(jù)中心新一代數(shù)據(jù)中心數(shù)據(jù)中心網(wǎng)絡(luò)技術(shù)

2023-11-13 12:37:07

2022-08-23 08:21:13

數(shù)據(jù)庫(kù)AIOPS工具

2016-12-11 10:35:52

2016-03-11 10:09:29

2010-05-05 18:02:17

新一代數(shù)據(jù)中心

2010-05-05 18:05:00

新一代數(shù)據(jù)中心

2013-10-31 16:20:33

Orange數(shù)據(jù)中心云計(jì)算

2010-05-05 14:33:55

虛擬化

2010-05-12 18:23:21

新一代數(shù)據(jù)中心H3C

2010-11-17 09:56:18

數(shù)據(jù)中心博科康普

2010-11-15 20:58:00

低碳新一代數(shù)據(jù)中心

2010-03-30 16:49:36

互聯(lián)網(wǎng)

2013-05-29 21:16:10

點(diǎn)贊
收藏

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