SpringBoot中使用ShardingJdbc切分?jǐn)?shù)據(jù)庫表

本文主要將業(yè)界知名的開源分庫分表中間件—ShardingJdbc集成至SpringBoot工程中,利用ShardingJdbc的數(shù)據(jù)庫切分能力來實現(xiàn)庫表水平切分和擴(kuò)展的目標(biāo)妇穴,提高分布式系統(tǒng)整體的并發(fā)量,解決數(shù)據(jù)庫中的單表因數(shù)據(jù)量過大而帶來得各種瓶頸和影響(本文所述的ShardingJdbc中間件以其1.X版本為參考凉翻,2.X版本和1.X版本有較大區(qū)別蔽莱,在后面的文章中會有介紹)。

分庫分表中間件ShardingJdbc介紹

ShardingJdbc是當(dāng)當(dāng)開源的數(shù)據(jù)庫水平切分的中間件捶惜,其代表了客戶端類的分庫分表技術(shù)框架(這一點(diǎn)與MyCat不同,MyCat本質(zhì)上是一種數(shù)據(jù)庫代理)荔烧。ShardingJdbc定位為輕量級數(shù)據(jù)庫驅(qū)動吱七,由客戶端直連數(shù)據(jù)庫,以jar包形式提供服務(wù)鹤竭,未使用中間層踊餐,無需額外部署,無其他依賴臀稚,業(yè)務(wù)系統(tǒng)開發(fā)人員與數(shù)據(jù)庫運(yùn)維人員無需改變原有的開發(fā)與運(yùn)維方式吝岭。因此ShardingJdbc即為增強(qiáng)版的JDBC驅(qū)動,可以實現(xiàn)舊代碼遷移零成本的目標(biāo)吧寺。

下面的是ShardingJdbc的架構(gòu)圖:

從上面的架構(gòu)圖中窜管,可以看出ShardingJdbc與業(yè)務(wù)工程集成起來十分方便與快捷,同時其提供的分片規(guī)則配置稚机、SQL解析幕帆、SQL改寫、SQL路由赖条、SQL執(zhí)行以及結(jié)果歸并等強(qiáng)大的功能失乾,使得業(yè)務(wù)開發(fā)人員無需在這些方面花費(fèi)較大多的精力,而可以更加專注于業(yè)務(wù)流程的開發(fā)纬乍。其主要的特點(diǎn)如下:

(1)分片規(guī)則配置

ShardingJdbc的分片邏輯非常靈活碱茁,支持分片策略自定義、復(fù)數(shù)分片鍵蕾额、多運(yùn)算符分片等功能早芭。

(2)JDBC規(guī)范重寫

ShardingJdbc中間件對標(biāo)準(zhǔn)JDBC規(guī)范的重寫思路是針對DataSource、Connection诅蝶、Statement退个、PreparedStatement和ResultSet五個核心接口封裝,將多個JDBC實現(xiàn)類集合(如:MySQL JDBC實現(xiàn)/DBCP JDBC實現(xiàn)等)納入ShardingJdbc實現(xiàn)類管理调炬。

(3)SQL解析

SQL解析作為分庫分表類中間件框架的核心之一语盈,其性能和兼容性是最重要的衡量指標(biāo)。目前常見的SQL解析器主要有fdb/jsqlparser和Druid缰泡。在ShardingJdbc1.5.0之前的版本是采用解析速度相對最快的Druid作為SQL解析器刀荒。ShardingJdbc在1.5.0.M1 正式發(fā)布時代嗤,將SQL解析引擎從Druid替換成了自研的。新引擎僅解析分片上下文缠借,對于 SQL 采用“半理解”理念干毅,進(jìn)一步提升性能和兼容性,同時降低了代碼復(fù)雜度泼返。

(4)SQL改寫

這里一部分是將分表的邏輯表名稱替換為實際真實的分表名稱硝逢。另一部分是根據(jù)SQL解析結(jié)果替換一些在分片環(huán)境中不正確的功能。其中绅喉,1.5.0之前的版本渠鸽,SQL改寫是在SQL路由之前完成的,而在1.5.x中調(diào)整為SQL路由之后柴罐,因為SQL改寫可以根據(jù)路由至單庫表還是多庫表而進(jìn)行進(jìn)一步優(yōu)化徽缚。

(5)SQL路由

SQL路由是指根據(jù)分片規(guī)則配置,將待執(zhí)行的SQL定位至真正的DB數(shù)據(jù)源革屠。

(6)SQL執(zhí)行

這里指的是路由至真實的DB數(shù)據(jù)源后凿试,ShardingJdbc將采用多線程并發(fā)執(zhí)行SQL,并完成對addBatch等批量方法的處理似芝。

(7)結(jié)果歸并

ShardingJdbc支持通遍歷類红省、排序類、聚合類和分組類四種結(jié)果并歸方式国觉。普通遍歷類最為簡單,只需按順序遍歷ResultSet的集合即可虾啦。排序類結(jié)果則將結(jié)果先排序再輸出麻诀,因為各分庫的分片結(jié)果均按照各自條件完成排序,所以采用歸并排序算法整合最終結(jié)果傲醉。聚合類分為3種類型蝇闭,比較型、累加型和平均值型硬毕。分組類相對最為復(fù)雜呻引,需要將所有的ResultSet結(jié)果放入內(nèi)存,使用Map-Reduce算法分組吐咳,最后根據(jù)排序和聚合條件做相關(guān)處理逻悠。最為消耗內(nèi)存,損失性能的地方就是這里了韭脊,可以考慮使用limit合理的限制分組數(shù)據(jù)大小童谒。

在Spring Boot中實踐ShardingJdbc

本節(jié)將主要詳細(xì)介紹在SpringBoot工程中如何集成ShardingJdbc這款切分庫表的中間件,并使用其完成對庫表的切分/路由沪羔,以及在業(yè)務(wù)開發(fā)中的使用饥伊。

版本環(huán)境

Spring Boot 1.4.1.RELEASE

Druid 1.0.12

JDK 1.8

添加ShardingJdbc的pom依賴

因為當(dāng)當(dāng)開源了ShardingJdbc的源碼,我們可以通過maven倉庫來獲得jar包依賴。當(dāng)訪問http://mvnrepository.com/artifact/com.dangdang/sharding-jdbc-core(該鏈接為1.X版本的)選擇自己項目需要的版本(在本次集成中選擇的版本為1.4.2)琅豆,點(diǎn)擊進(jìn)入后復(fù)制maven內(nèi)容到pom.xml內(nèi)即可辽俗。同時辨泳,這里需要注意的是在ShardingJdbc 1.5.0.M1正式發(fā)布以前,SQL解析引擎仍然是采用阿里的Druid數(shù)據(jù)源連接池,還需要在Pom中引入Druid的依賴(版本為1.0.12)项乒,此外需要保證ShardingJdbc與Druid版本相對應(yīng),否則在執(zhí)行SQL解析時候會導(dǎo)致ShardingJdbc的運(yùn)行時異常猜揪。Pom文件的引入如下圖所示:

yaml文件配置

在MySql數(shù)據(jù)庫中創(chuàng)建相應(yīng)的分庫和分表后麸澜,需要在SpringBoot工程中的yaml配置文件(或property配置文件)中完成對分庫數(shù)據(jù)源的配置,具體如下:

? ?testShardingDB0:

? ? ?type: com.alibaba.druid.pool.DruidDataSource

? ? ?driverClassName: com.mysql.jdbc.Driver

? ? ?url: jdbc:mysql://{ip}:{port} /res_test_cloud_bill_sharding0?useUnicode=true&characterEncoding=utf-8

? ? ?username: xxxxxx

? ? ?password: xxxxxx

? ? ?max-idle: 500

? ? ?max-active: 100

? ? ?min-idle: 50

? ? ?initial-size: 50

? ? ?validation-query: SELECT 1

? ? ?max-wait: -1

? ? ?test-on-borrow: true

? ? ?test-on-return: true

? ? ?test-while-idle: true

? ? ?num-tests-per-eviction-run: 3

? ? ?time-between-eviction-runs-millis: 30000

? ? ?min-evictable-idle-time-millis: 18000000

? ? ?removeAbandoned: true

? ? ?removeAbandonedTimeout: 180

? ? ?# 打開PSCache,并且指定每個連接上PSCache的大小

? ? ?poolPreparedStatements: false

? ? ?maxPoolPreparedStatementPerConnectionSize: -1

? ? ?# 配置監(jiān)控統(tǒng)計攔截的filters,去掉后監(jiān)控界面sql無法統(tǒng)計,'wall'用于防火墻

? ? ?filters: stat,wall,log4j

? ? ?# 通過connectProperties屬性來打開mergeSql功能;慢SQL記錄

? ? ?connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000

? ? ?# 合并多個DruidDataSource的監(jiān)控數(shù)據(jù)

? ? ?useGlobalDataSourceStat: true

###分庫1配置,具體的ip/host:port和數(shù)據(jù)庫用戶名和密碼根據(jù)實際填寫

? ?testShardingDB1:

? ? ?type: com.alibaba.druid.pool.DruidDataSource

? ? ?driverClassName: com.mysql.jdbc.Driver

? ? ?url: jdbc:mysql:// {ip}:{port}/res_test_cloud_bill_sharding1?useUnicode=true&characterEncoding=utf-8

? ? ?username: xxxxxx

? ? ?password: xxxxxx

? ? ?max-idle: 500

? ? ?max-active: 100

? ? ?min-idle: 50

? ? ?initial-size: 50

? ? ?validation-query: SELECT 1

? ? ?max-wait: -1

? ? ?test-on-borrow: true

? ? ?test-on-return: true

? ? ?test-while-idle: true

? ? ?num-tests-per-eviction-run: 3

? ? ?time-between-eviction-runs-millis: 30000

? ? ?min-evictable-idle-time-millis: 18000000

? ? ?removeAbandoned: true

? ? ?removeAbandonedTimeout: 180

? ? ?# 打開PSCache,并且指定每個連接上PSCache的大小

? ? ?poolPreparedStatements: false

? ? ?maxPoolPreparedStatementPerConnectionSize: -1

? ? ?# 配置監(jiān)控統(tǒng)計攔截的filters,去掉后監(jiān)控界面sql無法統(tǒng)計,'wall'用于防火墻

? ? ?filters: stat,wall,log4j

? ? ?# 通過connectProperties屬性來打開mergeSql功能;慢SQL記錄

? ? ?connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000

? ? ?# 合并多個DruidDataSource的監(jiān)控數(shù)據(jù)

? ? ?useGlobalDataSourceStat: true

ShardingJdbc分庫分表的Bean配置

引入了ShardingJdbc中間件后翼雀,在SpringBoot工程中可以通過配置Bean來初始化分庫分表的數(shù)據(jù)源饱苟,其中需要設(shè)置邏輯表與實際分表的映射關(guān)系和分庫分表的ID路由策略。

@Configuration

@MapperScan(basePackages ? = "com.chinamobile.bcop.test.sharding.xxxxxxxx", ? sqlSessionTemplateRef = "shardingSqlSessionTemplate")

public ? class MybatisTestShardingConfig {

? ?@Bean(name = "testShardingDB0")

? ?@ConfigurationProperties(prefix = "spring.datasource.tesetShardingDB0")

? ?public DataSource testShardingDataSource0(){

? ? ? ?return new ? DruidDataSource();

? ?}

? ?@Bean(name = "testShardingDB1")

? ?@ConfigurationProperties(prefix = ? "spring.datasource.testShardingDB1")

? ?public DataSource testShardingDataSource1(){

? ? ? ?return new ? DruidDataSource();

? ?}

? ?@Bean(name = "dataSourceRule")

? ?public DataSourceRule ? dataSourceRule(@Qualifier("testShardingDB0") DataSource ds0, @Qualifier("testShardingDB1") ? DataSource ds1){

? ? ? ?Map dataSourceMap = new HashMap<>();

? ? ? ?dataSourceMap.put("shardingDataSource0", ? ds0);

? ? ? ?dataSourceMap.put("shardingDataSource1", ? ds1);

? ? ? ?return new ? DataSourceRule(dataSourceMap, "shardingDataSource0");

? ?}

? ?@Bean(name = ? "shardingRule")

? ?public ShardingRule ? shardingRule(@Qualifier("dataSourceRule")DataSourceRule ? dataSourceRule){

? ?//表策略

? ?//設(shè)置分表映射狼渊,將test_msg_queue_bill_record_0~test_msg_queue_bill_record_4

? ?// 幾個實際的表映射到test_msg_queue_bill_record邏輯表

? ?//0~4幾個表是真實的表箱熬,test_msg_queue_bill_record是個虛擬不存在的表,只是供使用

? ?TableRule orderTableRule = TableRule.builder("test_msg_queue_bill_record")

? ? ? ?.actualTables(Arrays.asList(

? ? ? ?"test_msg_queue_bill_record_0",

? ? ? ?"test_msg_queue_bill_record_1",

? ? ? ?"test_msg_queue_bill_record_2",

? ? ? ?"test_msg_queue_bill_record_3",

? ? ? ?"test_msg_queue_bill_record_4"))

? ? ? ?.dataSourceRule(dataSourceRule)

? ? ? ?.build();

? ?//綁定表策略,在查詢時會使用主表策略計算路由的數(shù)據(jù)源狈邑,因此需要約定綁定表策略的表的規(guī)則需要一致城须,可以一定程度提高效率

? ?List bindingTableRules = new ArrayList();

? ?bindingTableRules.add(new ? BindingTableRule(Arrays.asList(orderTableRule)));

? ?return ? ShardingRule.builder()

? ? ? ? ? ? ? ?.dataSourceRule(dataSourceRule) ? ?

? ? ? ? ? ? ? ?.tableRules(Arrays.asList(orderTableRule))

? ? ? ? ? ? ? ?.bindingTableRules(bindingTableRules)

? ? ? ? ? ? ? ?.databaseShardingStrategy(new DatabaseShardingStrategy("CUSTOMER_ID", new ? CustomizedDbShardingStrategy()))

? ? ? ? ? ? ? ?.tableShardingStrategy(new ? TableShardingStrategy("USER_ID", new ? CustomizedTableShardingStrategy()))

? ? ? ? ? ? ? ?.build();

? ?}

? ?@Bean(name = "testShardingDataSource")

? ?public DataSource ? shardingDataSource(@Qualifier("shardingRule")ShardingRule ? shardingRule){

? ? ? ?return ? ShardingDataSourceFactory.createDataSource(shardingRule);

? ?}

? ?//需要手動聲明配置事務(wù)

? ?@Bean(name = "testShardingTransactionManager")

? ?public DataSourceTransactionManager ? transactitonManager(@Qualifier("testShardingDataSource") DataSource ? dataSource){

? ? ? ?return new ? DataSourceTransactionManager(dataSource);

? ?}

//MyBatis ? SqlSessionFactory/SqlSessionTemplate/MybatisDAO的Bean初始化省略

//……..

在本文的示例中,按照業(yè)務(wù)要求先對原來的單庫單表進(jìn)行拆分米苹,由原來的單庫單表—testmsgqueuebillrecord糕伐,分成兩個庫的多表(每個庫中均有testmsgqueuebillrecord0~testmsgqueuebillrecord4五個分表,這里只是示例蘸嘶,在真實的業(yè)務(wù)場景下需要根據(jù)業(yè)務(wù)數(shù)據(jù)的總體容量來設(shè)定分庫分表的規(guī)模良瞧,究竟是分5個庫每個庫5表,還是分10個庫每個庫10表來滿足業(yè)務(wù)要求)训唱。由上面的分庫分表配置Bean的代碼可見褥蚯,使用Druid連接池初始化兩個分庫的數(shù)據(jù)源后設(shè)置ShardingJdbc數(shù)據(jù)源的分片規(guī)則。其中况增,testmsgqueuebillrecord表為邏輯表赞庶,分別與testmsgqueuebillrecord0~testmsgqueuebillrecord4的實際分表名建立映射。如果執(zhí)行的SQL為“select * from testmsgqueuebillrecord” 就能遍歷查完hwmsgqueuebillrecord0~4五個分表澳骤。最后歧强,在設(shè)置切分規(guī)則時候,分別以customerId和userId作為切分?jǐn)?shù)據(jù)庫和切分?jǐn)?shù)據(jù)表的路由規(guī)則宴凉。根據(jù)上面的配置可以得到下面的分庫分表邏輯視圖:

具體的庫表分片路由策略

ShardingJdbc對分片路由策略完全采用開放式的誊锭,將這一部分的控制權(quán)交給業(yè)務(wù)側(cè)開發(fā)人員手中。業(yè)務(wù)開發(fā)人員可以根據(jù)具體業(yè)務(wù)的需求弥锄,設(shè)置靈活的分庫分表路由策略丧靡。在上一節(jié)的示例代碼中蟆沫,可以看到在設(shè)置分庫分表規(guī)則的時候有兩個比較顯著的類——CustomizedDbShardingStrategy和CustomizedTableShardingStrategy。正是這兩個類完成了自定義的庫表的自定義分片路由策略温治,CustomizedDbShardingStrategy的示例代碼如下:

public ?class CustomizedDbShardingStrategy implements ? SingleKeyDatabaseShardingAlgorithm {

? ?@Override

? ?public String ? doEqualSharding(Collection databaseNames, ? ShardingValue shardingValue) {

? ? ? ? //在這里設(shè)置具體的條件為“=”的分庫策略

? ? ? ? //code here

? ? ? ?}

? ?@Override

? ?public Collection ? doInSharding(Collection databaseNames, ? ShardingValue shardingValue) {

? ? ? ?//在這里設(shè)置具體SQL語句條件為“In”的分庫策略

? ? ? ?//code here

? ?}

? ?@Override

? ?public Collection ? doBetweenSharding(Collection databaseNames, ? ShardingValue shardingValue) {

? ? ? ?//在這里設(shè)置具體的SQL語句條件為“between”的分庫策略

? ? ? ?//code here

? ?}

CustomizedTableShardingStrategy的示例代碼如下:

public class CustomizedTableShardingStrategy implements SingleKeyTableShardingAlgorithm {

? ?@Override

? ?public String doEqualSharding(Collection tableNames, ShardingValue shardingValue) {

? ? ? ?//在這里設(shè)置具體的條件為“=”的分表策略

? ? ? ?//code here

? ?}

? ?@Override

? ?public Collection doInSharding(Collection tableNames, ShardingValue shardingValue) {

? ? ? ?//在這里設(shè)置具體SQL語句條件為“In”的分表策略

? ? ? ?//code here

? ?}

? ?@Override

? ?public Collection doBetweenSharding(Collection tableNames, ShardingValue shardingValue) {

? ? ? ?//在這里設(shè)置具體的SQL語句條件為“between”的分表策略

? ? ? ?//code here

? ?}

}

先看分庫表路由策略中的doEqualSharding方法饭庞,比如對于SQL語句—“Insert into testmsgqueuebillrecord(CUSTOMERID,USERID,xxxx1,xxxx2……)values(‘testcustid111111’,’testuserid22222’,’xxxx1’,’xxxx2’……)”,doEqualSharding方法中的形參databaseNames為分庫的名稱(比如shardingDataSource0數(shù)據(jù)源對應(yīng)的實際分庫名稱為restestcloudbillsharding0),shardingValue為分庫的鍵值(在前一節(jié)分庫分表Bean配置中設(shè)定)熬荆,也就是對應(yīng)該SQL語句中的“testcustid111111”舟山,我們可以在doEqualSharding方法中設(shè)置適合業(yè)務(wù)需求的鍵值分片路由規(guī)則,比如以“testcustid111111”的哈希值作為分片路由規(guī)則來選擇該插入SQL究竟應(yīng)該路由至實際的哪個分庫的哪個分表來執(zhí)行卤恳。而另外的兩個方法累盗,doInSharding和doBetweenSharding則是作用在SQL條件為“Between”和“In”的語句上。

分布式主鍵生成

對于傳統(tǒng)的數(shù)據(jù)表設(shè)計而言突琳,主鍵自增都是基本需求若债。對MySQL而言,分庫分表之后拆融,不同表生成全局唯一主鍵是較為頭疼的問題蠢琳。因為同一個邏輯表所對應(yīng)的不同實際分表之間的自增鍵是無法感知,這樣會造成有部分分表的主鍵值重復(fù)镜豹。我們當(dāng)然可以通過分表的約束規(guī)則來達(dá)到數(shù)據(jù)不重復(fù)傲须,但是這需要引入額外的方法來解決重復(fù)性問題。

目前趟脂,有許多第三方技術(shù)方案可以解決該問題泰讽,比如flickr的全局主鍵生成方案和uuid的全局主鍵生成方案。ShardingJdbc在設(shè)計之初也有考慮過這個問題昔期,提供了自己的實現(xiàn)方案菇绵,其分布式全局ID自動生成器可以根據(jù)時間偏移量、工作進(jìn)程id和同一毫秒的自增量來生成一個64位的Long型數(shù)值以保證其全局唯一性镇眷。

在工程中需要在pom中添加依賴如下:

在配置中需要完成對其Bean對象的初始化,具體代碼如下:

@Bean(name = "shardingIdGenerator")

public IdGenerator getIdGenerator() {

? ?return new CommonSelfIdGenerator();

}

使用ShardingJdbc編寫自定義的Dao

經(jīng)過上面幾節(jié)內(nèi)容后翎嫡,這一節(jié)就可以使用配置后的ShardingJdbc所對應(yīng)的MybatisDao來完成一些業(yè)務(wù)的應(yīng)用了欠动。

public abstract class AbstractResBillShardingDao {

? ?@Qualifier(value = "hwShardingMyBatisDao")

? ?@Autowired

? ?protected IMybatisDAO mybatisShardingDao;

? ?@Qualifier(value = "shardingIdGenerator")

? ?@Autowired

? ?private IdGenerator idGenerator;

? ?public int shardingInsertRows (List resBillRecordList, String resType) {

? ? ? ?int resultRowNum = 0;

? ? ? ?try {

? ? ? ? ? ?String shardingInsertSqlMapper = MyBatisMapperMapping.ResBatchInsertMapper.getBatchInsertMapperByTypeCode(resType);

? ? ? ? ? ?if(StringUtils.isEmpty(shardingInsertSqlMapper)) {

? ? ? ? ? ? ? ?log.info("無法匹配到對應(yīng)的sqlmapper的statement,直接返回,無法匹配的資源類型為:{}",resType);

? ? ? ? ? ? ? ?return resultRowNum;

? ? ? ? ? ?}

? ? ? ? ? ?for(BillRecord msgQueueBillRecord:resBillRecordList) {

? ? ? ? ? ? ? ?//設(shè)置分布式id主鍵msgQueueBillRecord.setId(idGenerator.generateId().longValue());

? ? ? ? ? ?resultRowNum+=mybatisShardingDao.insert(shardingInsertSqlMapper, msgQueueBillRecord);

? ? ? ? ? ?}

? ? ? ?} catch (Exception ex) {

? ? ? ? ? ?log.error("批量插入數(shù)據(jù)出現(xiàn)異常", ex);

? ? ? ?}

? ? ? ?return resultRowNum;

? ?}

}

可以看到在這個Dao的類中,批量插入方法—shardingInsertBills惑申,通過自動注入的mybatisShardingDao和idGenerator來完成對數(shù)據(jù)記錄的切分插入具伍,這里需要注意ShardingJdbc目前尚未支持批量插入的SQL語句,因此需要在代碼中自己完成遍歷數(shù)據(jù)集合后的單行插入圈驼,這里idGenerator用于生成每個待插入記錄的全局唯一健值人芽。工程運(yùn)行的截圖日志如下:

使用ShardingJdbc的限制

ShardingJdbc中間件并非是萬能,它還是有一些SQL和JDCB接口的使用限制绩脆,其最大的使用限制在于如下幾點(diǎn):

(1)對于DataSource接口不支持超時相關(guān)的操作萤厅。

(2)對于Connection接口不支持存儲過程橄抹、游標(biāo)、函數(shù)惕味、savePoint楼誓、自定義類型映射等。

(3)對于Statement和PreparedStatement接口名挥,不支持返回多結(jié)果集的語句和國際化操作疟羹。

(4)對于ResultSet接口,不支持對于結(jié)果集指針位置判斷禀倔;不支持通過非next方法改變結(jié)果指針位置榄融;不支持修改結(jié)果集內(nèi)容。

(5)SQL語句限制:不支持HAVING救湖;不支持OR愧杯,UNION 和 UNION ALL;不支持特殊INSERT捎谨,尤其是是批量插入的SQL語句民效;不支持DISTINCT聚合;不支持dual虛擬表涛救;不支持SELECT LASTINSERTID()畏邢;不支持CASE WHEN。

總結(jié)

本文主要介紹了如何在Spring Boot工程中完成數(shù)據(jù)庫切分中間件—ShardingJdbc集成以及如何進(jìn)行分庫分表配置检吆、庫表分片路由策略設(shè)置和分布式主鍵生成關(guān)鍵點(diǎn)的闡述舒萎。限于筆者的才疏學(xué)淺,對本文內(nèi)容可能還有理解不到位的地方蹭沛,如有闡述不合理之處還望留言一起探討臂寝。在這里在給大家推薦一個架構(gòu)交流群:617434785,里面會分享一些資深架構(gòu)師錄制的視頻錄像:有Spring摊灭,MyBatis咆贬,Netty源碼分析,高并發(fā)帚呼、高性能掏缎、分布式、微服務(wù)架構(gòu)的原理煤杀,JVM性能優(yōu)化這些成為架構(gòu)師必備的知識體系眷蜈。還能領(lǐng)取免費(fèi)的學(xué)習(xí)資源。相信對于已經(jīng)工作和遇到技術(shù)瓶頸的碼友沈自,在這個群里會有你需要的內(nèi)容酌儒。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市枯途,隨后出現(xiàn)的幾起案子忌怎,更是在濱河造成了極大的恐慌籍滴,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,383評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件呆躲,死亡現(xiàn)場離奇詭異异逐,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)插掂,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評論 3 385
  • 文/潘曉璐 我一進(jìn)店門灰瞻,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人辅甥,你說我怎么就攤上這事酝润。” “怎么了璃弄?”我有些...
    開封第一講書人閱讀 157,852評論 0 348
  • 文/不壞的土叔 我叫張陵要销,是天一觀的道長。 經(jīng)常有香客問我夏块,道長疏咐,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,621評論 1 284
  • 正文 為了忘掉前任脐供,我火速辦了婚禮浑塞,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘政己。我一直安慰自己酌壕,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,741評論 6 386
  • 文/花漫 我一把揭開白布歇由。 她就那樣靜靜地躺著卵牍,像睡著了一般。 火紅的嫁衣襯著肌膚如雪沦泌。 梳的紋絲不亂的頭發(fā)上糊昙,一...
    開封第一講書人閱讀 49,929評論 1 290
  • 那天,我揣著相機(jī)與錄音谢谦,去河邊找鬼溅蛉。 笑死,一個胖子當(dāng)著我的面吹牛他宛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播欠气,決...
    沈念sama閱讀 39,076評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼厅各,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了预柒?” 一聲冷哼從身側(cè)響起队塘,我...
    開封第一講書人閱讀 37,803評論 0 268
  • 序言:老撾萬榮一對情侶失蹤袁梗,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后憔古,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體遮怜,經(jīng)...
    沈念sama閱讀 44,265評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,582評論 2 327
  • 正文 我和宋清朗相戀三年鸿市,在試婚紗的時候發(fā)現(xiàn)自己被綠了锯梁。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,716評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡焰情,死狀恐怖陌凳,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情内舟,我是刑警寧澤合敦,帶...
    沈念sama閱讀 34,395評論 4 333
  • 正文 年R本政府宣布,位于F島的核電站验游,受9級特大地震影響充岛,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜耕蝉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,039評論 3 316
  • 文/蒙蒙 一崔梗、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧赔硫,春花似錦炒俱、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至推盛,卻和暖如春峦阁,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背耘成。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評論 1 266
  • 我被黑心中介騙來泰國打工榔昔, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人瘪菌。 一個月前我還...
    沈念sama閱讀 46,488評論 2 361
  • 正文 我出身青樓撒会,卻偏偏與公主長得像,于是被迫代替她去往敵國和親师妙。 傳聞我的和親對象是個殘疾皇子诵肛,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,612評論 2 350

推薦閱讀更多精彩內(nèi)容