国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Sharding-JDBC分庫連接數(shù)優(yōu)化

這篇具有很好參考價值的文章主要介紹了Sharding-JDBC分庫連接數(shù)優(yōu)化。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

Sharding-JDBC分庫連接數(shù)優(yōu)化

一、背景
配運平臺組的快遞訂單履約中心(cp-eofc)及物流平臺履約中心(jdl-uep-ofc)系統(tǒng)都使用了ShardingSphere生態(tài)的sharding-jdbc作為分庫分表中間件, 整個集群采用只分庫不分表的設(shè)計,共16個MYSQL實例,每個實例有32個庫,集群共512個庫.

當(dāng)每增加一臺客戶端主機,一個MYSQl實例最少要增加32個連接(通常都會使用連接池,根據(jù)配置的最大連接數(shù),這個連接數(shù)可能會放大5~10倍).并且通常一個系統(tǒng)都會分為web,provider,worker等多個應(yīng)用,這些應(yīng)用共用一套數(shù)據(jù)源.隨著應(yīng)用機器數(shù)的增加,MYSQL實例的連接數(shù)會很快達到上限,這就對系統(tǒng)的擴容造成了阻礙,無法橫向的增加機器數(shù),只能縱向的提高機器的配置來應(yīng)對流量的增長.

作為京東物流的核心系統(tǒng),業(yè)務(wù)增長迅速,系統(tǒng)所承接的流量也是逐漸增加,所以急需解決這個制約系統(tǒng)擴展的瓶頸點。

?

二、分庫分表的相關(guān)概念介紹

2.1 為什么要分庫分表

2.1.1 分庫

隨著業(yè)務(wù)的發(fā)展,單庫中的數(shù)據(jù)量不斷增加,數(shù)據(jù)庫的QPS會越來越高,對數(shù)據(jù)庫的讀寫耗時也會相應(yīng)的增長,這時單庫的讀寫性能必然會成為系統(tǒng)的瓶頸點.這時可以通過將單個數(shù)據(jù)庫拆分為多個數(shù)據(jù)庫的方法,來分擔(dān)數(shù)據(jù)庫的壓力,提升性能.同時多個數(shù)據(jù)庫分布在不同的機器上也提高了數(shù)據(jù)庫的可用性.

2.1.2 分表

隨著單表數(shù)據(jù)量的增加,對于數(shù)據(jù)的查詢和更新,即使在數(shù)據(jù)庫底層有一定的優(yōu)化,但是隨著量變必定會引起質(zhì)變,導(dǎo)致性能急劇下降.這時可以通過分表的方法,將單表數(shù)據(jù)按一定規(guī)則水平拆分到多個表中,減小單表的數(shù)據(jù)量,提升系統(tǒng)性能.

2.2 sharding-jdbc簡介

ShardingSphere

是一套開源的分布式數(shù)據(jù)庫中間件解決方案組成的生態(tài)圈,它由Sharding-JDBC、Sharding-Proxy和Sharding-Sidecar(計劃中)這3款相互獨立的產(chǎn)品組成.他們均提供標準化的數(shù)據(jù)分片、分布式事務(wù)和數(shù)據(jù)庫治理功能,可適用于如Java同構(gòu)、異構(gòu)語言、容器、云原生等各種多樣化的應(yīng)用場景。

Sharding-JDBC

定位為輕量級Java框架,在Java的JDBC層提供的額外服務(wù)。它使用客戶端直連數(shù)據(jù)庫,以jar包形式提供服務(wù),無需額外部署和依賴,可理解為增強版的JDBC驅(qū)動,完全兼容JDBC和各種ORM框架。

適用于任何基于Java的ORM框架,如:JPA, Hibernate, Mybatis, Spring JDBC Template或直接使用JDBC?;谌魏蔚谌降臄?shù)據(jù)庫連接池,如:DBCP, C3P0, BoneCP, Druid, HikariCP等。

支持任意實現(xiàn)JDBC規(guī)范的數(shù)據(jù)庫。目前支持MySQL,Oracle,SQLServer和PostgreSQL。

我們先看下ShardingSphere官網(wǎng)給出的基于Spring命名空間的規(guī)則配置示例:


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:sharding="http://shardingsphere.io/schema/shardingsphere/sharding" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
                        http://www.springframework.org/schema/beans/spring-beans.xsd
                        http://shardingsphere.io/schema/shardingsphere/sharding 
                        http://shardingsphere.io/schema/shardingsphere/sharding/sharding.xsd 
                        ">
    <!-數(shù)據(jù)源ds0->
    <bean id="ds0" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://localhost:3306/ds0" />
        <property name="username" value="root" />
        <property name="password" value="" />
    </bean>
    <!-數(shù)據(jù)源ds1->
    <bean id="ds1" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://localhost:3306/ds1" />
        <property name="username" value="root" />
        <property name="password" value="" />
    </bean>
    
    <!-分片策略->
    <sharding:inline-strategy id="databaseStrategy" sharding-column="user_id" algorithm-expression="ds$->{user_id % 2}" />
    <sharding:inline-strategy id="orderTableStrategy" sharding-column="order_id" algorithm-expression="t_order$->{order_id % 2}" />
    <sharding:inline-strategy id="orderItemTableStrategy" sharding-column="order_id" algorithm-expression="t_order_item$->{order_id % 2}" />
    
    <!-sharding數(shù)據(jù)源配置->
    <sharding:data-source id="shardingDataSource">
        <sharding:sharding-rule data-source-names="ds0,ds1">
            <sharding:table-rules>
                <sharding:table-rule logic-table="t_order" actual-data-nodes="ds$->{0..1}.t_order$->{0..1}" database-strategy-ref="databaseStrategy" table-strategy-ref="orderTableStrategy" />
                <sharding:table-rule logic-table="t_order_item" actual-data-nodes="ds$->{0..1}.t_order_item$->{0..1}" database-strategy-ref="databaseStrategy" table-strategy-ref="orderItemTableStrategy" />
            </sharding:table-rules>
        </sharding:sharding-rule>
    </sharding:data-source>
</beans>

配置總結(jié):

  1. 需要配置多個數(shù)據(jù)源ds0,ds1;

  2. 分片策略中配置分片鍵(sharding-column)和分片表達式(algorithm-expression)需符合groovy語法;

  3. 在sharding數(shù)據(jù)源中<sharding:table-rule>標簽中配置邏輯表名(logic-table),庫分片策略(database-strategy-ref)和表分片策略(table-strategy-ref),actual-data-node屬性由數(shù)據(jù)源名 + 表名組成,以小數(shù)點分隔,用于廣播表;

?

三、問題分析與解決方案

3.1 問題分析

正如文章開頭提到的目前我們的MYSQL集群架構(gòu)如下,16個MYSQL實例,每個實例有32個庫,集群共512個庫.當(dāng)客戶端主機啟動后與MYSQL_0實例中的32個庫連接,分別會建立32個數(shù)據(jù)源,連接池配置的最大連接數(shù)為5,也就是說極端情況下一個客戶端與一個MYSQL實例最多會建立32*5=160個連接數(shù).對于物流的一些核心系統(tǒng)在大促時擴容上百臺是很常見的,所以很快單個實例的最大連接數(shù)就會觸達上限.

目前客戶端連接連接數(shù)據(jù)庫集群形式如圖所示:

Sharding-JDBC分庫連接數(shù)優(yōu)化

3.2 可行方案

我們的目標就是降低單個MYSQL實例的連接數(shù),其中我們共探討了幾種方案如下:

3.2.1 單實例不分庫只分表

這樣一個客戶端與單個數(shù)據(jù)庫實例只需通過一個連接池連接,大大降低了連接數(shù).但這種方案改變了現(xiàn)有的分片規(guī)則,需要新建一套數(shù)據(jù)庫集群,根據(jù)新規(guī)則同步歷史數(shù)據(jù)和增量數(shù)據(jù),還有新舊數(shù)據(jù)驗證,但難度和風(fēng)險最高的還是線上切換過程,可能會造成數(shù)據(jù)不一致,且一旦出問題回滾方案也會非常復(fù)雜.

3.2.2 使用支持彈性擴展的數(shù)據(jù)庫

使用京東的jed,tidb等支持彈性擴展的數(shù)據(jù)庫,將數(shù)據(jù)同步到新庫中,這類數(shù)據(jù)庫的優(yōu)勢是開發(fā)人員只需關(guān)注業(yè)務(wù),不需要再去處理數(shù)據(jù)庫連接這些底層細節(jié).

3.2.3 使用sharding-proxy

Sharding-Proxy的定位是透明化的數(shù)據(jù)庫代理,我們可以在服務(wù)器上部署一套Sharding-Proxy,客戶端只需連接proxy服務(wù),再由proxy服務(wù)器連接MYSQL集群,這樣MYSQL集群的連接數(shù)只與proxy服務(wù)器的數(shù)量有關(guān),與客戶端解耦.

3.2.4 通過改造sharding-jdbc

理論上我們只要獲取數(shù)據(jù)庫實例上某個庫的連接,我們就可以通過"庫名.表名"的方式訪問這臺實例上其他庫中的數(shù)據(jù)(當(dāng)然前提是用戶要擁有要訪問庫的權(quán)限),我們是否可以通過改造sharding-jdbc來實現(xiàn)這種訪問方式?

以上幾種方案,3.2.1和3.2.2都需要新建數(shù)據(jù)庫,同步歷史和增量數(shù)據(jù),還涉及線上切換數(shù)據(jù)源,3.2.3需要部署一套proxy服務(wù),并且為了高可用必定要以集群方式部署,這三種方案工作量和風(fēng)險都較高,我們基于成本最小原則,最終選擇改造sharding-jdbc的方案.

3.3 探究sharding-jdbc

3.3.1 工作流程

sharding-jdbc的工作流程可以分為以下步驟:

  • sql解析-詞法解析和語法解析;

  • sql路由-根據(jù)解析上下文匹配數(shù)據(jù)庫和表的分片策略,并生成路由路徑;

  • sql改寫-將邏輯SQL改寫為在真實數(shù)據(jù)庫中可以正確執(zhí)行的SQL;

  • sql執(zhí)行-使用多線程并發(fā)執(zhí)行sql;

  • 結(jié)果歸并-將從各個數(shù)據(jù)節(jié)點獲取的多數(shù)據(jù)結(jié)果集,組合成為一個結(jié)果集并正確的返回至請求客戶端;

顯然數(shù)據(jù)庫和表的分片是在sql路由階段處理,所以我們以sql路由邏輯為入口分析下源碼.

3.3.2 源碼分析

ShardingStandardRoutingEngine類中的route方法為計算路由的入口,返回的結(jié)果是數(shù)據(jù)庫和表的分片集合:

Sharding-JDBC分庫連接數(shù)優(yōu)化

route方法中的核心邏輯在該類的route0方法中,其中routeDataSources方法負責(zé)database路由,routeTables方法負責(zé)table路由,實際路由計算在StandardShardingStrategy的doSharding方法中,我們繼續(xù)深入.

Sharding-JDBC分庫連接數(shù)優(yōu)化

在StandardShardingStrategy類中有兩個成員屬性,preciseShardingAlgorithm(精準分片算法),rangeShardingAlgorithm(范圍分片算法),由于我們的sql都只指定分片鍵精準查詢,使用的都是preciseShardingAlgorithm計算出的結(jié)果,PreciseShardingAlgorithm是個接口,那我們就可以實現(xiàn)這個接口來自定義分片算法.

Sharding-JDBC分庫連接數(shù)優(yōu)化

同時在sharding-sphere官網(wǎng)上也找到了相應(yīng)的標簽支持:

Sharding-JDBC分庫連接數(shù)優(yōu)化

所以我們只需要自己實現(xiàn)PreciseShardingAlgorithm接口并配置在標簽內(nèi)即可實現(xiàn)自定義分片策略.

3.4 改造步驟

3.4.1 庫分片改造

目前應(yīng)用配置了ds_0~ds_511共512個數(shù)據(jù)源,我們只需配置ds_0~ds_15共16個數(shù)據(jù)源,每個數(shù)據(jù)源配置的是單個實例上的第一個庫.

對于分片規(guī)則,我們可以依然使用<sharding:inline-strategy>標簽,只需對Groovy表達式進行重寫,分片鍵為order_code,之前分片算法為(Math.abs(order_code.hashCode()) % 512)即用order_code列的哈希值對512取模得到0~511,我們只需要將結(jié)果再整除32即可得到0~16,即表達式改寫為(Math.abs(order_code.hashCode()) % 512).intdiv(32).

改造前分庫規(guī)則配置:

Sharding-JDBC分庫連接數(shù)優(yōu)化

改造后分庫規(guī)則配置:

Sharding-JDBC分庫連接數(shù)優(yōu)化

3.4.2 表分片改造

實現(xiàn)PreciseShardingAlgorithm接口,重寫表分片算法,使計算結(jié)果返回"實際庫名+表名"的形式;

例如:查詢DB_31庫上t_order表的user_id=35711的數(shù)據(jù),數(shù)據(jù)庫分片算法返回的數(shù)據(jù)源為"DB_0",表分片算法返回"DB_31.t_order";

自定義表分片算法:

Sharding-JDBC分庫連接數(shù)優(yōu)化

在xml中定義<sharding:standard-strategy>標簽,其屬性precise-algorithm-ref配置為我們自定義的分表算法.

Sharding-JDBC分庫連接數(shù)優(yōu)化

3.4.3 數(shù)據(jù)庫連接池參數(shù)調(diào)整

改造前是一個庫對應(yīng)一個數(shù)據(jù)源連接池,改造后一個實例上的32個庫共用一個數(shù)據(jù)源連接池,那么連接池的最大連接數(shù),最小空閑連接數(shù)等參數(shù)需要相應(yīng)的做調(diào)整.這個需要根據(jù)業(yè)務(wù)流量做合理的評估,當(dāng)然最嚴謹?shù)倪€是要以壓測結(jié)果作為依據(jù).

改造后客戶端連接集群的形式如圖:

Sharding-JDBC分庫連接數(shù)優(yōu)化

優(yōu)化前后數(shù)據(jù)庫集群連接數(shù)對比:

Sharding-JDBC分庫連接數(shù)優(yōu)化

四、小插曲

在改寫庫分片規(guī)則的Groovy表達式時,整除32直接在原有表達式上配置"/32"即Math.abs(order_code.hashCode()) % 512 / 32 ,在調(diào)試中發(fā)現(xiàn)執(zhí)行sql會報"no database route info"錯誤信息,經(jīng)過debug發(fā)現(xiàn)sharding-jdbc計算分片規(guī)則時會出現(xiàn)小數(shù)(例如:ds_14.6857),導(dǎo)致找不到數(shù)據(jù)源,這是因為Groovy沒有提供專用的整數(shù)除法運算符,所以要用.intdiv()方法,最終表達式改寫為(Math.abs(order_code.hashCode()) % 512).intdiv(32).

五、總結(jié)

本文介紹了分庫分表的概念及優(yōu)勢,以及sharding-jdbc分庫分表中間件,探究了sharding-jdbc的路由規(guī)則的執(zhí)行流程.當(dāng)然在系統(tǒng)設(shè)計之初,對于數(shù)據(jù)庫的分庫分表,到底需不需要做?是多分庫好還是多分表好?并沒有一個放之四海而皆準的法則,需結(jié)合系統(tǒng)的特點(例如qps,tps,單表數(shù)據(jù)量,磁盤規(guī)格,數(shù)據(jù)保留時間,業(yè)務(wù)增量,數(shù)據(jù)冷熱方案等因素)來決策權(quán)衡,有利有弊才需決策,有取有舍才需權(quán)衡.

-end-

?

作者|張仲良文章來源地址http://www.zghlxwxcb.cn/news/detail-634474.html

到了這里,關(guān)于Sharding-JDBC分庫連接數(shù)優(yōu)化的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • Sharding-JDBC分庫分表-自動配置與分片規(guī)則加載原理-3

    Sharding JDBC自動配置的原理 與所有starter一樣,shardingsphere-jdbc-core-spring-boot-starter也是通過SPI自動配置的原理實現(xiàn)分庫分表配置加載,spring.factories文件中的自動配置類shardingsphere-jdbc-core-spring-boot-starter功不可沒,他主要是自動創(chuàng)建了模式bean、事務(wù)類型bean和數(shù)據(jù)源bean,配置加載

    2024年02月10日
    瀏覽(25)
  • 一、Sharding-JDBC系列01:整合SpringBoot實現(xiàn)分庫分表,讀寫分離

    一、Sharding-JDBC系列01:整合SpringBoot實現(xiàn)分庫分表,讀寫分離

    目錄 一、概述 二、案例演示-水平分表 (1)、創(chuàng)建springboot工程 (2)、創(chuàng)建數(shù)據(jù)庫和數(shù)據(jù)表 (3)、application.yaml配置分片規(guī)則?? (4)、測試數(shù)據(jù)插入、查詢操作 4.1、插入-控制臺SQL日志? 4.2、查詢-控制臺SQL日志 ?三、案例演示-水平分庫 (1)、創(chuàng)建數(shù)據(jù)庫和數(shù)據(jù)表? (2)、application.yaml配置

    2024年02月02日
    瀏覽(17)
  • Mybatis-Plus集成Sharding-JDBC與Flyway實現(xiàn)多租戶分庫分表

    Mybatis-Plus集成Sharding-JDBC與Flyway實現(xiàn)多租戶分庫分表

    公司產(chǎn)品部收到了一些重要客戶的需求,他們希望能夠依賴獨立的數(shù)據(jù)庫存儲來支持他們的業(yè)務(wù)數(shù)據(jù)。與此同時,仍有許多中小客戶,可以繼續(xù)使用公共庫以滿足其需求。技術(shù)實現(xiàn)方面,此前持久層框架使用的Mybatis-plus,部分業(yè)務(wù)場景使用到了Sharding-JDBC用于分表,另外,我們

    2024年02月05日
    瀏覽(24)
  • Sharding-JDBC概述

    Sharding-JDBC概述

    ? 隨著業(yè)務(wù)數(shù)據(jù)量的增加,原來所有的數(shù)據(jù)都是在一個數(shù)據(jù)庫上的,網(wǎng)絡(luò)IO及文件IO都集中在一個數(shù)據(jù)庫上的,因此CPU、內(nèi)存、文件IO、網(wǎng)絡(luò)IO都可能會成為系統(tǒng)瓶頸。 當(dāng)業(yè)務(wù)系統(tǒng)的數(shù)據(jù)容量接近或超過單臺服務(wù)器的容量、QPS/TPS接近或超過單個數(shù)據(jù)庫實例的處理極限等,此時

    2024年02月13日
    瀏覽(20)
  • 若依框架集成sharding-jdbc

    本文基于4.X版本開發(fā) 官方網(wǎng)站 定位為輕量級Java框架,在Java的JDBC層提供的額外服務(wù)。 它使用客戶端直連數(shù)據(jù)庫,以jar包形式提供服務(wù),無需額外部署和依賴,可理解為增強版的JDBC驅(qū)動,完全兼容JDBC和各種ORM框架。 適用于任何基于JDBC的ORM框架,如:JPA, Hibernate, Mybatis, Spri

    2024年02月08日
    瀏覽(28)
  • Mysql Sharding-JDBC讀寫分離

    Mysql Sharding-JDBC讀寫分離

    深入Sharding-JDBC分庫分表從入門到精通【黑馬程序員】_嗶哩嗶哩_bilibili 1.1.1 msyql 多庫 多表 多服務(wù)器? 1.1.2 通過Sharding-JDBC jar包-增強JDBC 訪問多數(shù)據(jù)源 - 自動處理成一個數(shù)據(jù)源 1.1.3 使用數(shù)據(jù)的人 - 使用Sharding-JDBC 自動合成的數(shù)據(jù)源 - 如同 一庫一表操作 ? 1.3.0 課程視頻 07-Shard

    2024年02月02日
    瀏覽(20)
  • sharding-jdbc多數(shù)據(jù)源配置

    通過sharding-jdbc做分表這里就不多做介紹了,需要的可以看上一片文章 當(dāng)項目中配置了多數(shù)據(jù)源,并且其中一個數(shù)據(jù)源需要使用sharding-jdbc分表時,配置如下 導(dǎo)入shardingjdbc依賴 這里使用的是4.0.1的配置,和上篇的3.1.0差別不大,詳細配置大伙可以上官網(wǎng)查閱。 多數(shù)據(jù)源配置類

    2024年02月14日
    瀏覽(16)
  • Sharding-JDBC之PreciseShardingAlgorithm(精確分片算法)

    Sharding-JDBC之PreciseShardingAlgorithm(精確分片算法)

    ??在我之前的文章里,數(shù)據(jù)的分庫分表都是基于行表達式的方式來實現(xiàn)的,看起來也蠻好用,也挺簡單的,但是有時會有些復(fù)雜的規(guī)則,可能使用行表達式策略會很復(fù)雜或者實現(xiàn)不了,我們就講另外一種分片策略,精確分片算法,通常用來處理=或者in條件的情況比較多。

    2024年02月11日
    瀏覽(18)
  • Sharding-JDBC(十)如何解決根據(jù)ID更新時掃描全部分表

    我們在使用 ShardingJDBC 作為分片工具的時候,會在配置中指定分片鍵,例如根據(jù) create_time 創(chuàng)建時間來按月分片是比較常用的操作。當(dāng)分片表中需要 根據(jù)主鍵 ID 來進行更新的時候 ,由于不確定數(shù)據(jù)的 create_time 具體是多少,ShardingJDBC 就會在選擇使用分片表的時候,就會默認選

    2024年02月07日
    瀏覽(23)
  • SpringBoot+Sharding-jdbc+mybatis-plus實現(xiàn)水平分表

    這塊我就不演示了

    2024年02月12日
    瀏覽(19)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包