自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

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

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

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

[[216850]]

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

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

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

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

發(fā)展歷程

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

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

在大規(guī)模使用 MySQL 的過程中,我們發(fā)現(xiàn),隨著業(yè)務(wù)數(shù)據(jù)量的增長,很多業(yè)務(wù)開始了漫長的分庫、分表之旅,起初各個業(yè)務(wù)系統(tǒng)在自己的業(yè)務(wù)代碼中維護(hù)分庫分表的路由規(guī)則。

而且各個業(yè)務(wù)系統(tǒng)的路由規(guī)則和整體設(shè)計(jì)都不一樣,后來由于人員更迭以至于業(yè)務(wù)代碼無法維護(hù),不同業(yè)務(wù)使用的數(shù)據(jù)庫分庫分表模式不盡相同,導(dǎo)致數(shù)據(jù)庫的維護(hù)工作也難如登天。

這時我們開始重新思考應(yīng)該提供什么樣的數(shù)據(jù)庫服務(wù),得出了以下幾點(diǎn):

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

為了實(shí)現(xiàn)上述功能特點(diǎn),我們分為兩步走:

  • 優(yōu)先解決業(yè)務(wù)和運(yùn)維窘境,從而爭取足夠的時間和技術(shù) buffer 進(jìn)一步完善產(chǎn)品。
  • 最終完美形態(tài)的產(chǎn)品研發(fā)。

因此,我們首先在 2015 年開發(fā)了 JProxy,優(yōu)先解決緊急的業(yè)務(wù)和運(yùn)維難題:分庫分表規(guī)則統(tǒng)一化和路由透明化。

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

功能特性

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

JED(JD Elastic DataBase)

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

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

起初某個業(yè)務(wù)可能申請了 4 個分庫,后面隨著業(yè)務(wù)的發(fā)展,數(shù)據(jù)量越來越大,可能需要擴(kuò)容到 8 個分庫。

一般的數(shù)據(jù)庫中間件在擴(kuò)容時,需要與業(yè)務(wù)研發(fā)部門協(xié)商一個業(yè)務(wù)低谷期停業(yè)務(wù),然后進(jìn)行擴(kuò)容,擴(kuò)容完畢后重新啟動業(yè)務(wù)。

為了解決這個問題,JED 提供了在線動態(tài)擴(kuò)容功能,擴(kuò)容只會對業(yè)務(wù)造成秒級影響,且無需人工介入。

我們現(xiàn)在可以觸發(fā)自動擴(kuò)容,設(shè)置的策略是當(dāng)磁盤的使用率達(dá)到80%,就自動進(jìn)行擴(kuò)容。

自動 FailOver

Master 一旦出現(xiàn)宕機(jī),哨兵檢測系統(tǒng)就會第一時間檢測到,會自動觸發(fā)注冊在哨兵檢測系統(tǒng)中的 Hook 程序。

Hook 程序就會選擇一個最新的 Slave 替換 Master,然后更新 ETCD 中的元數(shù)據(jù)信息,業(yè)務(wù)方的下一次請求就會發(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ù)的動態(tài)遷移。

如果以前你的業(yè)務(wù)是運(yùn)行在 MySQL 上的,現(xiàn)在要遷到 JED 上,你不需要停止任何業(yè)務(wù),直接啟動 JTransfer 的數(shù)據(jù)遷移服務(wù),就可以在后臺自動完成數(shù)據(jù)的同步和遷移。

遷移完畢后,JTransfer 會自行比對 JED 上的數(shù)據(jù)與原來數(shù)據(jù)的一致性和 lag 計(jì)算。

當(dāng)數(shù)據(jù)完全一致, 且 lag 小于 5 秒時,就會郵件通知業(yè)務(wù)方進(jìn)行復(fù)驗(yàn),復(fù)驗(yàn)沒有問題,業(yè)務(wù)方直接將數(shù)據(jù)庫連接指向到 JED 就可以正常提供服務(wù)了。

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

JED 具有數(shù)據(jù)庫審計(jì)的功能,該功能實(shí)現(xiàn)在 Gate 層,在 Gate 層我們會得到應(yīng)用發(fā)送給 JED 的所有 SQL,然后將 SQL 語句或者 SQL 模板發(fā)送給 MQ。

由于是在 Gate 層實(shí)現(xiàn)的,而 Gate 層與 MySQL 服務(wù)不在一個容器上,因此對 MySQL 服務(wù)不會產(chǎn)生任何的負(fù)面影響。

BinLake

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

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

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

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

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

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

高可用與自動故障轉(zhuǎn)移

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

負(fù)載自動均衡

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

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

支持多種 MQ

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

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

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

DBS

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

整體架構(gòu)

如上圖是京東數(shù)據(jù)庫的一個整體架構(gòu)圖,最底層是 JDOS2.0,JDOS 2.0 是京東新一代的容器技術(shù),是 Docker 的管理平臺。

實(shí)際上京東所有的數(shù)據(jù)庫服務(wù)現(xiàn)在已經(jīng)完全運(yùn)行在 Docker 之上了,這一點(diǎn)是讓我們比較引以為豪的工作成績,而這些都離不開京東 JDOS 的底層支持。

JED 包括六大組件:

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

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

BinLake 整個集群是完全無狀態(tài)的。我們所知道的大部分集群化服務(wù)都是有狀態(tài)集群和不對等集群。

所謂不對等集群就是集群里要有 Master 服務(wù)角色,負(fù)責(zé)整個集群的管理;還要有 Worker 服務(wù)角色,負(fù)責(zé)實(shí)際任務(wù)的執(zhí)行。

但整個 BinLake 是沒有任何 Master 的,只有一種服務(wù)角色:Wave,就是你的工作節(jié)點(diǎn)。Tower 只是一個可以與集群進(jìn)行交互式操作的 HTTP 服務(wù)。

Tower 與傳統(tǒng) Master 節(jié)點(diǎn)的不同之處在于:它不負(fù)責(zé)任何元數(shù)據(jù)的管理,它只是向 Topology 服務(wù)發(fā)送命令,更新或者獲取存儲在 ETCD 或 ZooKeeper 中的元數(shù)據(jù)信息。

DBS 是構(gòu)建于我們的 API Platform 之上的,API Platform 是我們自己開發(fā)的一個簡單 Faas 平臺。

有了 API Platform,在京東只要是會寫代碼的人,不管你用何種開發(fā)語言,只要是滿足 Restful 協(xié)議的服務(wù),都可以注冊到 API Platform 中,并不斷豐富 DBS。

DBS 包括幾個核心模塊:

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

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

JED

JED 的前端是 AppServer,從整體架構(gòu)上,JED 和 AppServer 直接打交道的只有一個角色,就是 JED-Gate。

JED-Gate 完全兼容 MySQL 協(xié)議,AppServer 可以將一些查詢語句發(fā)送給 JED-Gate。

JED-Gate 層對所有查詢的查詢執(zhí)行計(jì)劃都會做緩存,并且根據(jù)查詢執(zhí)行計(jì)劃,通過 Topology 服務(wù)獲得查詢所涉及表的路由源數(shù)據(jù)信息,根據(jù)元數(shù)據(jù)信息將查詢語句改寫或者拆分發(fā)送到底層的 Shard 上去。

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

BinLake

針對上圖的 BinLake 架構(gòu)圖,可以看到 BinLake 集群中的每個工作節(jié)點(diǎn)叫做 Wave。

每個 Wave 節(jié)點(diǎn)上有多個 instance,這個 instance 就是針對于每個 MySQL 實(shí)例的 Binlog 采集線程,在同一個 Wave 實(shí)例上的多個 instance 實(shí)例通過 Epoll 模型實(shí)現(xiàn)高效網(wǎng)絡(luò)監(jiān)聽和通訊。

當(dāng)用戶新采集一個 MySQL 的 Binlog 或者某個 instance 線程掛掉了,會根據(jù)當(dāng)前集群中各個 Wave 服務(wù)的健康狀況選擇一個健康度最高的 Wave 實(shí)例,去實(shí)例化這個新的 instance 線程。

而每個 Wave 實(shí)例上的健康度是根據(jù) Zabbix 的監(jiān)控?cái)?shù)據(jù)進(jìn)行動態(tài)計(jì)算的。

從圖中可以看到,Tower 服務(wù)其實(shí)沒有跟 Wave 服務(wù)做任何直接的通訊或者聯(lián)系。

Tower 只會跟 ZK 或 ETCD 集群直接做交互,它對 ZK 或者 ETCD 集群任何元數(shù)據(jù)的更改都被 Wave 服務(wù)及時發(fā)現(xiàn),發(fā)現(xiàn)之后,Wave 服務(wù)會采取一系列相應(yīng)的措施,來對元數(shù)據(jù)的更改進(jìn)行響應(yīng)。

DBS

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

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

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

無論是 JGuard、JProcessMaker、DBS-Tools 還是 Scheduler,它們做的所有工作都只有一樣:調(diào)用 API Platform 上所暴露的接口。

API Platform 會根據(jù)你的注冊信息,去調(diào)用 Tower 暴露的 API 接口,或者是調(diào)用 MHA 的一些腳本或者其他接口。

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

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

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

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

Step 1:創(chuàng)建兩個目標(biāo) Shard

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

假設(shè)現(xiàn)在有一萬條記錄,要擴(kuò)成兩個 Shard,那么每個目標(biāo) Shard 里面就有 5000 條。

在 JED 里,在觸發(fā)擴(kuò)容這個動作時,首先會通過 JDOS 接口,將目標(biāo) Shard 的所有 POD 都創(chuàng)建并啟動起來。

如果每個目標(biāo) Shard 都是 1 主 2 從,總共會啟動 6 個POD,12 個 Container(一個 POD 中有 2 個 Container,1 個 Container 中是 Tablet 服務(wù),1 個 Container 是 MySQL 服務(wù))。

然后每個 POD 都是 Not Sevring 狀態(tài),其中每三個 POD 實(shí)例組成一個 Target shard。

可以看到,Source Shard 中的 sharding key 對應(yīng)的 key range 是:0x00-OxFF,這里的 KeyRange 也就是你的 sharding key 經(jīng)過哈希之后能夠落到多大的范圍。

現(xiàn)在要將一個 Source Shard 分為兩個 Target Shard,所以 Source Target 對應(yīng)的 Key Range 也就要一分為二。

可以看到兩個 Target Shard 對應(yīng)的 KeyRange 是 0x00-Ox80,Ox80-Oxff,并且是 Not Serving 狀態(tài)。

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

兩個 Target Shard 建立之后,會根據(jù) ETCD 里的默認(rèn)配置針對每個 Target Shard 建立 MySQL 的復(fù)制關(guān)系,比如:

  • 一主兩從:一個 Master,一個 Replication,一個 ReadOnly。
  • 一主三從,一個 Master,兩個 Replication,一個 Readonly。
  • 一主四從,一個 Master,兩個 Replication 和兩個 ReadOnly。

建立完復(fù)制關(guān)系之后,首先會通過 JED-Worker 將 Source Shard 中的 Schema 信息復(fù)制到兩個 TargetShard 中。

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

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

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

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

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

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

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

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

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

Step 5:切 Shard

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

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

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

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

自動 FailOver

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

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

檢測到異常之后會通過郵件和短信通知業(yè)務(wù)接口人,通知完之后,不會等業(yè)務(wù)接口人進(jìn)行處理,直接從當(dāng)前整個 MySQL 集群當(dāng)中選擇一個 GTID 最大的一個 MySQL 實(shí)例,將這個 MySQL 實(shí)例切成 Master。

然后根據(jù)新的 Master 重建新 MySQL 主從復(fù)制關(guān)系,將剩余的 Replication 和 ReadOnly 重新掛載到新的 Master 上,再調(diào)用 JED-Ctrld 服務(wù)的接口更新 ETCD 中的元數(shù)據(jù)。

這樣后續(xù)的 DDL/DML 就會發(fā)到最新的 Master 之上,最后缺失的一個 Tablet 需要人工補(bǔ)入。

Streaming Process

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

JED-Gate 接收到該查詢語句之后,會根據(jù) ETCD 中的分片元數(shù)據(jù),將該語句分發(fā)到三個 Shard 中,各個 Shard 返回給 JED-Gate 數(shù)據(jù)本身就是有序的。

在 JED-Gate 中針對每個 Shard 都會有一個 buffer 與之對應(yīng),每個 buffer 用來流式的接收每個 Shard 返回的排序完畢的數(shù)據(jù),因此該 buffer 中的數(shù)據(jù)也是有序的。

然后將每個 buffer 的首地址存儲到一個 PriorityQueue 里面, PriorityQueue 是一個堆排序的優(yōu)先級隊(duì)列,會根據(jù)每個 buffer 中的首元素不斷的進(jìn)行排序。

每從 PriorityQueue 中取出一個元素,PriorityQueue 都會調(diào)整 buffer 的先后順序,JED-Gate 會將元數(shù)一個一個地取出來,以流式的方式發(fā)給前端,從而實(shí)現(xiàn)整體流式排序。

Join 處理

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

對 Join 查詢的處理,要分情況:

第一種情況:Join Key 與 Sharding Key 相同。

這種情況下由于 Join Key 和 Sharding  Key 是完全相同的,因此是可以將 Join 查詢語句直接發(fā)送到下面的每個 shard,在 JED-Gate 匯聚各個 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。

針對該查詢語句,JED-Gate 首先對其進(jìn)行 SQL 語句改寫,改寫為兩條語句:

  • select a.col,a.id from a where a.id=0
  • select b.col from b where b.id_2=a.id

在第二個查詢語句中的 a.id 是綁定變量。JED-Gate 會首先根據(jù) select a.col,a.id from a where a.id=0,定位到該 SQL 需要定位到哪個 shard,將 SQL 發(fā)送到相應(yīng)的 Shard 執(zhí)行,并流式的獲取其結(jié)果。

然后將結(jié)果中的 a.id 字段的值取出,并將值賦給 select b.col from b where b.id_2=a.id 語句中的綁定變量 a.id,將復(fù)制后的第二條 SQL 語句依次發(fā)送給所有的 shard,并將結(jié)果與第一條 SQL 語句中的結(jié)果組合,流式地返回給前端。

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

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

前面已經(jīng)提到 BinLake 有一個很大的特點(diǎn):一個完全無狀態(tài)的集群,沒有 Master 管理節(jié)點(diǎn),而要實(shí)現(xiàn)這個特性最重要的就是要有合理的元數(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 的自動發(fā)現(xiàn)和 HA,并最終實(shí)現(xiàn)了無 Master,無狀態(tài)的完全對等集群。

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

一個 BinLake 集群的 root znode 是一個名為 wave 的 znode,在 wave 之下是一系列的形式為:MySQL 域名命名:port 的 znode。

這樣的每個 znode 都對應(yīng)了一個 MySQL 實(shí)例,而在每個 MySQL 實(shí)例對應(yīng)的 znode 下面是該 MySQL 實(shí)例的管理、信息保存和選舉 znode。

其中 counter 節(jié)點(diǎn)中記錄了當(dāng)前 MySQL 實(shí)例對應(yīng)的 instanc 重啟了幾次,若連續(xù)重啟超過 7 次,就會發(fā)出報(bào)警信息。

而 dynamic 節(jié)點(diǎn)則記錄了每個 MySQL 實(shí)例對應(yīng)的 Binlog 采集線程對應(yīng)的快照信息包括:當(dāng)前采集到的 Binlog 文件、Offset、Timestamp、GTID、最近的 10 個時間點(diǎn) Binglog 位置和 Filter Rules 等。

從而保證 instance 重啟后,可以利用這些信息繼續(xù)進(jìn)行 Binlog 采集。

后面的 sequencenumber 對應(yīng)的一系列 znode 是由 Curator 自動創(chuàng)建的 znode,來保證選舉的正確性和防止羊群效應(yīng)。

而“Bingdleader:wavehost”對應(yīng)的 znode,主要用于人工介入 binlake,從而指定讓下次 instance leader 選舉的時候,固定在 wavehost 對應(yīng)的 Wave 節(jié)點(diǎn)上。

如果我某個 MySQL 采集的 instance 掛了,Curator 就會在后面的第一個 znode 對應(yīng)的 wave 服務(wù)上首先進(jìn)行 leader 選舉。

若成功選舉,就接入,否則依次對后面對應(yīng)的每個 Wave 實(shí)例進(jìn)行選舉,直到成功選舉出 leader。

選舉出新的 leader 之后,就會在對應(yīng)的 Wave 服務(wù)上重啟 Binlog 采集的 instance 線程,該 instance 就會根據(jù) dynamic znode 中存儲的快照信息重建 MySQL 的復(fù)制關(guān)系,繼續(xù)進(jìn)行 Binlog 采集。

集群化 Binlog 訂閱

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

  • 時序
  • 亂序

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

將其全部放到一個 Byte Buffer 里,然后通過 Worker Thread 對 ByteBuffer 中的 Byte 進(jìn)行 Decode,并解析成一個個的 EventMsg,進(jìn)而將 EventMsg 也放到一個 MessageBuffer 中。

在 MessageBuffer 后面有一個 Handler 線程,這個 Handler 線程會根據(jù) ZooKeeper 里的一些元數(shù)據(jù)信息(比如:Topics、FilterRules、MQ 類型和地址等)對 EventMessage 進(jìn)行處理。

然后使用 protobuff 進(jìn)行序列化后發(fā)送到正確 MQ 中的特定的 Topic 里。這里的處理包括:根據(jù)庫表類型過濾、列過濾、事務(wù)頭 Event 和尾 Event 過濾等。

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

落地使用

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

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

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

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

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

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

這些是在 9 月份從 DBS 系統(tǒng)里面拿到的數(shù)據(jù),服務(wù)線上業(yè)務(wù)是指上線項(xiàng)目的個數(shù)。

目前京東彈性數(shù)據(jù)庫服務(wù)了線上 3122 個項(xiàng)目,管理的 MySQL 實(shí)例個數(shù)有將近兩萬個,管理的 Table 就比較多了,有 660 多萬個,并且完成了自動在線切換 2700 余次,自動化上線有 27000 余次。

現(xiàn)在京東有一般的業(yè)務(wù)都遷到了 JED 上,當(dāng)然還有一半的業(yè)務(wù)正在容器化的 MySQL 服務(wù)上并逐步地進(jìn)行遷移。

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

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

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

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

[[216856]]

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

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

2010-05-10 16:25:49

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ù)變革

2021-06-10 09:00:00

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

2021-06-10 14:01:38

大數(shù)據(jù)數(shù)據(jù)平臺數(shù)據(jù)湖

2011-02-15 10:02:54

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

2022-08-23 08:21:13

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

2023-11-13 12:37:07

2010-05-05 14:33:55

虛擬化

2010-05-12 18:23:21

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

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-11-17 09:56:18

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

2010-11-15 20:58:00

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

2016-12-11 10:35:52

2010-03-30 16:49:36

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

2010-05-05 17:54:25

點(diǎn)贊
收藏

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