91欧美超碰AV自拍|国产成年人性爱视频免费看|亚洲 日韩 欧美一厂二区入|人人看人人爽人人操aV|丝袜美腿视频一区二区在线看|人人操人人爽人人爱|婷婷五月天超碰|97色色欧美亚州A√|另类A√无码精品一级av|欧美特级日韩特级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

數(shù)據(jù)庫的中間件有啥用?

數(shù)據(jù)分析與開發(fā) ? 來源:Coder的技術(shù)之路 ? 作者:Coder的技術(shù)之路 ? 2021-06-21 16:16 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

Part1 數(shù)據(jù)庫中間件有啥用

有一天,你去三亞玩耍,就想玩?zhèn)€沖浪,即時你不差錢,難道還要自己采買快艇、滑板等等裝備來滿足這為數(shù)不多的心血來潮么。租一個就行了嘛。這其實就是連接池的作用。

數(shù)據(jù)庫中間件可以理解為是一種具有連接池功能,但比連接池更高級的、帶很多附加功能的輔助組件,不僅可以租沖浪板,還可以提供地點推薦、上保險等等各類服務(wù)。

從網(wǎng)上的資料看,zdal應(yīng)該算是半開源的,好像是之前開源過,但后續(xù)沒有準備維護,然后就刪除了,不過github被fork下來好多,隨便一搜就是一片,當前,只是老的版本。目前螞蟻內(nèi)部的zdal好像已經(jīng)更新到zdal5了吧,那咱可就看不到了。

越復(fù)雜的系統(tǒng),數(shù)據(jù)庫中間件的作用越大。就拿zdal來說,它提供分庫分表,結(jié)果集合并,sql解析,數(shù)據(jù)庫failover動態(tài)切換等數(shù)據(jù)訪問層統(tǒng)一解決方案。下面就一起來看下,其內(nèi)部實現(xiàn)是怎么樣的。

Part2 架構(gòu)剖析之高屋建瓴

c87433b8-d145-11eb-9e57-12bb97331649.png

2.1 整體概述

如上圖所示,zdal有四個重要的組成部分:

價值體現(xiàn)--客戶端Client包。對外暴露基本操作接口,用于業(yè)務(wù)層簡單黑盒的操作數(shù)據(jù)源;業(yè)務(wù)只和client交互,動態(tài)切換/路由等邏輯只需要進行規(guī)則配置,相關(guān)邏輯由zdal實現(xiàn)。

核心功能--連接管理datasource包。最核心的能力,提供多種類型數(shù)據(jù)庫的連接管理;不管功能多花哨,最終目的還是為了解決數(shù)據(jù)庫連接的問題。

關(guān)鍵能力--SQL解析parser包。基礎(chǔ)SQL解析能力;解析sql類型、字段名稱、數(shù)據(jù)庫等等,配合規(guī)則進行路由

擴展能力--庫表路由rule包。根據(jù)parser解析出的字段確定邏輯庫表和物理庫表。

2.2 組件圖看架構(gòu)

組件圖對整體架構(gòu)和各組件及相互聯(lián)系的理解可以起到很好的幫助。一個簡版的組件圖畫了好久,還有不少錯,不過大概是這么個意思,哎,基本功要丟~

c8833368-d145-11eb-9e57-12bb97331649.png

對照上圖可以比較清晰的看到:

Client包對應(yīng)用層暴露的數(shù)據(jù)源、負責監(jiān)聽配置動態(tài)變更的監(jiān)聽組件、負責加載組織各部分的配置組件、負責加載spring bean 和庫表規(guī)則的配置組件;

Client中加載了規(guī)則組件,實現(xiàn)邏輯表和數(shù)據(jù)庫的路由規(guī)則。

Client中的庫表配置調(diào)用datasource中的數(shù)據(jù)源管理服務(wù)并構(gòu)建連接池的連接池;

Client中的SqlDispatcher服務(wù)調(diào)用SQL解析組件實現(xiàn)SQL解析。

Part3 細節(jié)剖析之一葉知秋

3.1 配置加載和bean初始化

大部分情況下,我們使用如mybatis這樣的ORM框架來進行數(shù)據(jù)庫操作,其實不管是ORM還是其他方式,應(yīng)用層都需要對數(shù)據(jù)源進行配置。

所以,client對外暴露了一個符合JDBC標準的datasource數(shù)據(jù)源,用來滿足應(yīng)用層ORM等框架配置數(shù)據(jù)源的要求--ZdalDataSource

c89b1afa-d145-11eb-9e57-12bb97331649.png

//只提供了一個init方法,這也是spring啟動時時,必須要調(diào)用的初始化方法,所有功能,都從這里開始
public class ZdalDataSource extends AbstractZdalDataSource implements DataSource{
    public void init() {
        try {
            super.initZdalDataSource();
        } catch (Exception e) {
            CONFIG_LOGGER.error("...");
            throw new ZdalClientException(e);
        }
    }

ZdalDataSource#init()方法即為配置加載的核心入口,init中負責加載spring配置,根據(jù)配置初始化數(shù)據(jù)源,并創(chuàng)建連接池,同時,將邏輯表和物理庫的對應(yīng)關(guān)系都維護起來供后續(xù)路由調(diào)用。

/*父類的init方法*/
protected void initZdalDataSource() {
    /*用FileSystemXmlApplicationContext方式加載配置文件中的數(shù)據(jù)源和規(guī)則,轉(zhuǎn)化成zdalConfig對象*/
    this.zdalConfig = ZdalConfigurationLoader.getInstance().getZdalConfiguration(appName,dbmode, appDsName, configPath);
    this.dbConfigType = zdalConfig.getDataSourceConfigType();
   this.dbType = zdalConfig.getDbType();
   //初始化數(shù)據(jù)源
   this.initDataSources(zdalConfig);
   this.inited.set(true);
    }
}

從上面的類圖和這里的兩個入口方法大概了解到zdal配置加載的啟動流程。下面我們就來詳細看一下,讀寫分離和分庫分表的規(guī)則是怎么被加載,怎么起作用的。

3.2 細說讀寫分離

讀寫分離配置的加載

首先,我們需要有數(shù)據(jù)源的相關(guān)配置,如下圖:

c8b7a6b6-d145-11eb-9e57-12bb97331649.png

此XML配置會在init方法被調(diào)用時,被初始化,解析成ZdalConfig類的屬性,ZdalConfig類的主要成員見下面代碼:

public class ZdalConfig {
    /** key=dsName;value=DataSourceParameter 所有物理數(shù)據(jù)源的配置項,比如用戶名,密碼,庫名等 */
    private Map dataSourceParameters = new ConcurrentHashMap();
    /** 邏輯數(shù)據(jù)源和物理數(shù)據(jù)源的對應(yīng)關(guān)系:key=logicDsName,value=physicDsName */
    private Map              logicPhysicsDsNames  = new ConcurrentHashMap();
    /** 數(shù)據(jù)源的讀寫規(guī)則,比如只讀,或讀寫等配置*/
    private Map              groupRules           = new ConcurrentHashMap();
    /** 異常轉(zhuǎn)移的數(shù)據(jù)源規(guī)則*/
    private Map              failoverRules        = new ConcurrentHashMap();
    //一份完整的讀寫分離和分庫分表規(guī)則配置
    private AppRule                          appRootRule;

可以看到,xml中的規(guī)則,被解析到xxxRules里。這里以groupRules為例,failover同理。

下一步則是通過解析得到的zdalConfig 來初始化數(shù)據(jù)源:

protected final void initDataSources(ZdalConfig zdalConfig) {
    //DataSourceParameter中存的是數(shù)據(jù)源參數(shù),如用戶名密碼,最大最小連接數(shù)等
    for (Entry entry : zdalConfig.getDataSourceParameters().entrySet()) {
        try {
           //初始化連接池
           ZDataSource zDataSource = new ZDataSource(/*設(shè)置最大最小連接數(shù)*/createDataSourceDO(entry.getValue(),zdalConfig.getDbType(), appDsName + "." + entry.getKey()));
           this.dataSourcesMap.put(entry.getKey(), zDataSource);
        } catch (Exception e) {
            //...
        }
   }
  //其他分支略,只看最簡單的分組模式
  if (dbConfigType.isGroup()) {
       //讀寫配置賦值
       this.rwDataSourcePoolConfig = zdalConfig.getGroupRules();
       //初始化多份讀庫下的負載均衡
       this.initForLoadBalance(zdalConfig.getDbType());
  }
  //注冊監(jiān)聽:為了滿足動態(tài)切換
  this.initConfigListener();
}

initForLoadBalance的方法如下:

private void initForLoadBalance(DBType dbType) {
    Map dsSelectors = this.buildRwDbSelectors(this.rwDataSourcePoolConfig);
    this.runtimeConfigHolder.set(new ZdalRuntime(dsSelectors));
    this.setDbTypeForDBSelector(dbType);
}

可以看到,首先構(gòu)建出了DB選擇器,然后賦值給了runtimeConfigHolder供運行時獲取。而構(gòu)建DB選擇器的時候,其實是按讀寫兩個維度,把所有數(shù)據(jù)源都構(gòu)建了一遍,即group_r和group_w下都包含5個數(shù)據(jù)源,只不過各自的權(quán)重不一樣:

//比如按上面的配置寫庫只有一個,但是也會包含全數(shù)據(jù)源

group_0_w_0 :< bean:read0DataSource , writeWeight:0>
group_0_w_1 :< bean:writeDataSource , writeWeight:10>
group_0_w_2 :< bean:read1DataSource , writeWeight:0>
group_0_w_3 :< bean:read2DataSource , writeWeight:0>
group_0_w_4 :< bean:read3DataSource , writeWeight:0>

//上述就是寫相關(guān)的DBSelecter的內(nèi)容。

讀寫分離怎么起作用

以delete為例,更新刪除是要操作寫庫的

 public void delete(ZdalDataSource dataSource) {
     String deleteSql = "delete from test";
     Connection conn = null;
     PreparedStatement pst = null;
     try {
        conn = dataSource.getConnection();
        pst = conn.prepareStatement(deleteSql);
        pst.execute();
     } catch (Exception e) {
            //...
     } finally {
           //資源關(guān)閉
     }
 }

getConnection會從上文中提到的runtimeConfigHolder中獲取DBSelecter,然后執(zhí)行execute方法

 public boolean execute() throws SQLException {
    SqlType sqlType = getSqlType(sql);
    // SELECT相關(guān)的就選擇group_r對應(yīng)的DBSelecter
   if (sqlType == SqlType.SELECT || sqlType == SqlType.SELECT_FOR_UPDATE|| sqlType == SqlType.SELECT_FROM_DUAL) {
     //略
    return true;
    //update/delete相關(guān)的就選擇group_w對應(yīng)的DBSelecter
  } else if (sqlType == SqlType.INSERT || sqlType == SqlType.UPDATE|| sqlType == SqlType.DELETE) {
       if (super.dbConfigType == DataSourceConfigType.GROUP) {
           executeUpdate0();
       } else {
           executeUpdate();
      }
      return false;
  } 
}

如果是讀取相關(guān)的,那就選_r的DBSelecter,如果是寫相關(guān)的,那就選_W的DBSelecter。那么executeUpdate0中是怎么執(zhí)行區(qū)分讀寫數(shù)據(jù)源的呢,其實就是把這一組的數(shù)據(jù)源根據(jù)權(quán)重篩選一遍。

// WeightRandom#select(int[], java.lang.String[])
private String select(int[] areaEnds, String[] keys) {
   //這里的areaEnds數(shù)組,是一個累加范圍值數(shù)據(jù)
   //比如三個庫權(quán)重    10   9   8
   //那么areaEnds就是  10  19  27 是對每個權(quán)重的累加,最后一個值是總和
   int sum = areaEnds[areaEnds.length - 1];
   //這樣隨機出來的數(shù),是符合權(quán)重分布的
   int rand = random.nextInt(sum);
   for (int i = 0; i < areaEnds.length; i++) {
       if (rand < areaEnds[i]) {
           return keys[i];
   }
   return null;
}

Part4 總結(jié)

本篇文章,把阿里數(shù)據(jù)庫中間件相關(guān)的組件和加載流程進行了總結(jié),就一個最基本的分組讀寫分離的流程,對內(nèi)部實現(xiàn)進行了闡述。說是解析,其實是提供給大家一種閱讀的思路,畢竟篇幅有限,如果對中間件感興趣的同學(xué),可以fork下代碼,按上述邏輯自己閱讀下。

看源碼時,比如dubbo這些中間件其實是比較容易入手的,因為他們都依托于Spring進行JavaBean的裝載,所有,對Spring容器暴露的那些init、load方法,就是很好的切入點。個人思路,希望對大家有所幫助。

責任編輯:lq6

,>,>,>,>,>,>,>,>,>,>
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 中間件
    +關(guān)注

    關(guān)注

    0

    文章

    67

    瀏覽量

    18674
  • 數(shù)據(jù)庫
    +關(guān)注

    關(guān)注

    7

    文章

    4020

    瀏覽量

    68364

原文標題:一款優(yōu)秀數(shù)據(jù)庫中間件的不完全解析

文章出處:【微信號:DBDevs,微信公眾號:數(shù)據(jù)分析與開發(fā)】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點推薦

    以“網(wǎng)關(guān)中間件”實現(xiàn)充電樁OCPP 1.6安全配置文件無縫升級

    深圳惠志科技有限公司推出的OCPP安全代理網(wǎng)關(guān)采用"網(wǎng)關(guān)中間件"架構(gòu),在充電樁與云端CSMS之間透明地部署,實現(xiàn)充電樁OCPP 1.6協(xié)議安全配置文件從Profile 0/1到Profile 2/3的無縫升級,而無需觸及樁端硬件與固件。
    的頭像 發(fā)表于 02-04 11:56 ?826次閱讀
    以“網(wǎng)關(guān)<b class='flag-5'>中間件</b>”實現(xiàn)充電樁OCPP 1.6安全配置文件無縫升級

    恒訊科技解析:如何安裝MySQL并創(chuàng)建數(shù)據(jù)庫

    管理系統(tǒng)(RDBMS),使用結(jié)構(gòu)化查詢語言(SQL)高效地組織和管理數(shù)據(jù)。它是全球最受歡迎的開源數(shù)據(jù)庫系統(tǒng)之一,廣泛應(yīng)用于網(wǎng)頁開發(fā)、電子商務(wù)和商業(yè)應(yīng)用。 常見例? MySQL 是多種應(yīng)用的可靠選擇,包括: 網(wǎng)絡(luò)應(yīng)用:管理用戶認
    的頭像 發(fā)表于 01-14 14:25 ?180次閱讀

    國產(chǎn)數(shù)據(jù)庫的AI戰(zhàn)事

    國產(chǎn)數(shù)據(jù)庫硝煙再起,Vastbase V100構(gòu)筑企業(yè)智能基座
    的頭像 發(fā)表于 10-24 20:45 ?4043次閱讀
    國產(chǎn)<b class='flag-5'>數(shù)據(jù)庫</b>的AI戰(zhàn)事

    STM32U575VGT6在cubeMX中沒有FATFS中間件,是不支持嗎?

    STM32U575VGT6在cubeMX中沒有FATFS中間件,是不支持?還是待開發(fā)?現(xiàn)在這塊板子使用FATFS只能自己手動移植嗎?
    發(fā)表于 07-30 06:46

    數(shù)據(jù)庫數(shù)據(jù)恢復(fù)—服務(wù)器異常斷電導(dǎo)致Oracle數(shù)據(jù)庫故障的數(shù)據(jù)恢復(fù)案例

    Oracle數(shù)據(jù)庫故障: 某公司一臺服務(wù)器上部署Oracle數(shù)據(jù)庫。服務(wù)器意外斷電導(dǎo)致數(shù)據(jù)庫報錯,報錯內(nèi)容為“system01.dbf需要更多的恢復(fù)來保持一致性”。該Oracle數(shù)據(jù)庫
    的頭像 發(fā)表于 07-24 11:12 ?650次閱讀
    <b class='flag-5'>數(shù)據(jù)庫</b><b class='flag-5'>數(shù)據(jù)</b>恢復(fù)—服務(wù)器異常斷電導(dǎo)致Oracle<b class='flag-5'>數(shù)據(jù)庫</b>故障的<b class='flag-5'>數(shù)據(jù)</b>恢復(fù)案例

    三款主流國產(chǎn)數(shù)據(jù)庫的技術(shù)特點

    隨著數(shù)字經(jīng)濟的快速發(fā)展和數(shù)據(jù)安全要求的提升,國產(chǎn)數(shù)據(jù)庫正迎來前所未有的發(fā)展機遇。在信創(chuàng)浪潮推動下,達夢數(shù)據(jù)庫、TiDB、華為高斯數(shù)據(jù)庫等國產(chǎn)數(shù)據(jù)庫
    的頭像 發(fā)表于 07-14 11:08 ?1153次閱讀

    數(shù)據(jù)庫數(shù)據(jù)恢復(fù)—MongoDB數(shù)據(jù)庫文件丟失的數(shù)據(jù)恢復(fù)案例

    MongoDB數(shù)據(jù)庫數(shù)據(jù)恢復(fù)環(huán)境: 一臺操作系統(tǒng)為Windows Server的虛擬機上部署MongoDB數(shù)據(jù)庫。 MongoDB數(shù)據(jù)庫故障: 工作人員在MongoDB服務(wù)仍
    的頭像 發(fā)表于 07-01 11:13 ?644次閱讀
    <b class='flag-5'>數(shù)據(jù)庫</b><b class='flag-5'>數(shù)據(jù)</b>恢復(fù)—MongoDB<b class='flag-5'>數(shù)據(jù)庫</b>文件丟失的<b class='flag-5'>數(shù)據(jù)</b>恢復(fù)案例

    數(shù)據(jù)庫數(shù)據(jù)恢復(fù)—SQL Server數(shù)據(jù)庫被加密如何恢復(fù)數(shù)據(jù)?

    SQL Server數(shù)據(jù)庫故障: SQL Server數(shù)據(jù)庫被加密,無法使用。 數(shù)據(jù)庫MDF、LDF、log日志文件名字被篡改。
    的頭像 發(fā)表于 06-25 13:54 ?680次閱讀
    <b class='flag-5'>數(shù)據(jù)庫</b><b class='flag-5'>數(shù)據(jù)</b>恢復(fù)—SQL Server<b class='flag-5'>數(shù)據(jù)庫</b>被加密如何恢復(fù)<b class='flag-5'>數(shù)據(jù)</b>?

    中科創(chuàng)達與ETAS推出預(yù)集成多域中間件解決方案

    近日,ETAS 與 ThunderSoft(中科創(chuàng)達)宣布雙方建立了緊密合作關(guān)系,并將在今年6月24日至25日于路德維希堡舉行的汽車電子大會上,聯(lián)合展示其新開發(fā)的、面向高性能計算(HPC)SoC 車載系統(tǒng)的多域預(yù)集成中間件解決方案。
    的頭像 發(fā)表于 06-25 10:16 ?1274次閱讀

    oracle數(shù)據(jù)恢復(fù)—oracle數(shù)據(jù)庫誤執(zhí)行錯誤truncate命令如何恢復(fù)數(shù)據(jù)?

    oracle數(shù)據(jù)庫誤執(zhí)行truncate命令導(dǎo)致數(shù)據(jù)丟失是一種常見情況。通常情況下,oracle數(shù)據(jù)庫誤操作刪除數(shù)據(jù)只需要通過備份恢復(fù)數(shù)據(jù)
    的頭像 發(fā)表于 06-05 16:01 ?1122次閱讀
    oracle<b class='flag-5'>數(shù)據(jù)</b>恢復(fù)—oracle<b class='flag-5'>數(shù)據(jù)庫</b>誤執(zhí)行錯誤truncate命令如何恢復(fù)<b class='flag-5'>數(shù)據(jù)</b>?

    MySQL數(shù)據(jù)庫采集網(wǎng)關(guān)是什么?什么功能?

    MySQL數(shù)據(jù)庫采集網(wǎng)關(guān)是一種用于連接、采集、處理并傳輸數(shù)據(jù)到MySQL數(shù)據(jù)庫中間設(shè)備或軟件系統(tǒng),通常部署在數(shù)據(jù)源與MySQL
    的頭像 發(fā)表于 05-26 15:20 ?671次閱讀

    SQLSERVER數(shù)據(jù)庫是什么

    SQL Server 是由微軟公司開發(fā)的一款 關(guān)系型數(shù)據(jù)庫管理系統(tǒng)(RDBMS) ,用于存儲、管理和檢索結(jié)構(gòu)化數(shù)據(jù)。它是企業(yè)級應(yīng)用中廣泛使用的數(shù)據(jù)庫解決方案之一,尤其適用于Windows平臺,但也
    的頭像 發(fā)表于 05-26 09:19 ?1177次閱讀

    MySQL數(shù)據(jù)庫是什么

    MySQL數(shù)據(jù)庫是一種 開源的關(guān)系型數(shù)據(jù)庫管理系統(tǒng)(RDBMS) ,由瑞典MySQL AB公司開發(fā),后被Oracle公司收購。它通過結(jié)構(gòu)化查詢語言(SQL)進行數(shù)據(jù)存儲、管理和操作,廣泛應(yīng)用于Web
    的頭像 發(fā)表于 05-23 09:18 ?1223次閱讀

    數(shù)據(jù)庫數(shù)據(jù)恢復(fù)——MongoDB數(shù)據(jù)庫文件拷貝后服務(wù)無法啟動的數(shù)據(jù)恢復(fù)

    MongoDB數(shù)據(jù)庫數(shù)據(jù)恢復(fù)環(huán)境: 一臺Windows Server操作系統(tǒng)虛擬機上部署MongoDB數(shù)據(jù)庫。 MongoDB數(shù)據(jù)庫故障: 管理員在未關(guān)閉MongoDB服務(wù)的
    的頭像 發(fā)表于 04-09 11:34 ?873次閱讀
    <b class='flag-5'>數(shù)據(jù)庫</b><b class='flag-5'>數(shù)據(jù)</b>恢復(fù)——MongoDB<b class='flag-5'>數(shù)據(jù)庫</b>文件拷貝后服務(wù)無法啟動的<b class='flag-5'>數(shù)據(jù)</b>恢復(fù)

    STM32MP131C CbueMX中間件無RTOS選項是怎么回事?

    如題,STM32MP131C CbueMX中間件無RTOS選項,對比選擇STM32MP157芯片是有的,怎么查這部分資料呢
    發(fā)表于 03-14 06:59