真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

怎么做數(shù)據(jù)庫(kù)讀寫(xiě)分離

這篇文章主要講解了“怎么做數(shù)據(jù)庫(kù)讀寫(xiě)分離”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來(lái)研究和學(xué)習(xí)“怎么做數(shù)據(jù)庫(kù)讀寫(xiě)分離”吧!

創(chuàng)新互聯(lián)公司主營(yíng)寧遠(yuǎn)網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司,主營(yíng)網(wǎng)站建設(shè)方案,APP應(yīng)用開(kāi)發(fā),寧遠(yuǎn)h5小程序開(kāi)發(fā)搭建,寧遠(yuǎn)網(wǎng)站營(yíng)銷(xiāo)推廣歡迎寧遠(yuǎn)等地區(qū)企業(yè)咨詢(xún)

實(shí)現(xiàn)方式

對(duì)于讀寫(xiě)分離的使用,主要分為兩種方式,客戶(hù)端方式和代理方式。

客戶(hù)端方式可以自己用 Spring 自帶的 AbstractRoutingDataSource 來(lái)實(shí)現(xiàn),也可以用開(kāi)源的框架來(lái)實(shí)現(xiàn),比如  Sharding-JDBC。

怎么做數(shù)據(jù)庫(kù)讀寫(xiě)分離

代理方式需要編寫(xiě)代理服務(wù)來(lái)對(duì)所有節(jié)點(diǎn)進(jìn)行管理,應(yīng)用不需要關(guān)注多個(gè)數(shù)據(jù)庫(kù)節(jié)點(diǎn)信息??梢宰约簩?shí)現(xiàn),也可以用開(kāi)源的框架,也可以用商業(yè)的云服務(wù)。

怎么做數(shù)據(jù)庫(kù)讀寫(xiě)分離

數(shù)據(jù)延遲

談到數(shù)據(jù)延遲,你先得理解主從架構(gòu)的原理。對(duì)數(shù)據(jù)的增刪改操作在主庫(kù)上執(zhí)行,查詢(xún)?cè)趶膸?kù)上執(zhí)行,當(dāng)數(shù)據(jù)剛插入到主庫(kù),然后馬上去查詢(xún)的時(shí)候,很有可能數(shù)據(jù)還沒(méi)同步到從庫(kù)上,就會(huì)出現(xiàn)查詢(xún)不到的情況。

像我之前在某些網(wǎng)站發(fā)表文章,發(fā)表之后跳轉(zhuǎn)到列表頁(yè)面,發(fā)現(xiàn)沒(méi)有新發(fā)表的文章,重新刷新下頁(yè)面又有了,這一看這就是讀寫(xiě)分離后的數(shù)據(jù)延遲導(dǎo)致的現(xiàn)象。

強(qiáng)制路由數(shù)據(jù)延遲要不要解決,一般取決于業(yè)務(wù)場(chǎng)景。對(duì)于實(shí)時(shí)性要求沒(méi)有那么高的業(yè)務(wù)場(chǎng)景,允許一定的延遲,對(duì)于實(shí)時(shí)性要求高的場(chǎng)景,唯一的方式就是直接從主庫(kù)進(jìn)行查詢(xún),這樣才能及時(shí)讀到剛插入或者修改后最新的數(shù)據(jù)。

強(qiáng)制路由

就是一種解決方案,也就是將讀請(qǐng)求強(qiáng)制分發(fā)到主庫(kù)進(jìn)行查詢(xún)。大部分中間件都支持 Hint  語(yǔ)法/FORCE_MASTER/和/FORCE_SLAVE/。

以 Sharding-JDBC 舉例,框架提供了 HintManager 來(lái)強(qiáng)制路由,使用方式如下:

HintManager hintManager = HintManager.getInstance(); hintManager.setMasterRouteOnly();

為了方便使用,建議封裝一個(gè)注解,在需要實(shí)時(shí)查詢(xún)的業(yè)務(wù)方法上加上注解,通過(guò)切面進(jìn)行強(qiáng)制路由的設(shè)置。

注解使用:

@MasterRoute @Override public UserBO getUser(Long id) {     log.info("查詢(xún)用戶(hù) [{}]", id);     if (id == null) {         throw new BizException(ResponseCode.PARAM_ERROR_CODE, "id不能為空");     }     UserDO userDO = userDao.getById(id);     if (userDO == null) {         throw new BizException(ResponseCode.NOT_FOUND_CODE);     }     return userBoConvert.convert(userDO); }

切面設(shè)置:

@Aspect public class MasterRouteAspect {     @Around("@annotation(masterRoute)")     public Object aroundGetConnection(final ProceedingJoinPoint pjp, MasterRoute masterRoute) throws Throwable {         HintManager hintManager = HintManager.getInstance();         hintManager.setMasterRouteOnly();         try {             return pjp.proceed();         } finally {             hintManager.close();         }     } }

事務(wù)操作

在事務(wù)中的讀請(qǐng)求,走主庫(kù)還是從庫(kù)呢?對(duì)于這個(gè)問(wèn)題,最簡(jiǎn)單的方式就是所有事務(wù)中的操作都走主庫(kù),在事務(wù)中經(jīng)常會(huì)存在插入,然后再重新查詢(xún)的場(chǎng)景,此時(shí)事務(wù)沒(méi)提交,就算同步很快,從庫(kù)也是沒(méi)有數(shù)據(jù)的,所以只能走主庫(kù)。

但還有一些請(qǐng)求,只需要查詢(xún)從庫(kù)就行了,如果針對(duì)所有事務(wù)中的操作都強(qiáng)制路由,也不是很好。在 Sharding-JDBC  中的做法挺好的,對(duì)于同一線(xiàn)程且同一數(shù)據(jù)庫(kù)連接內(nèi),如有寫(xiě)入操作,以后的讀操作均從主庫(kù)讀取,用于保證數(shù)據(jù)一致性。如果我們?cè)跀?shù)據(jù)寫(xiě)入之前有查詢(xún)請(qǐng)求,還是走的從庫(kù),減輕主庫(kù)壓力。

怎么做數(shù)據(jù)庫(kù)讀寫(xiě)分離

動(dòng)態(tài)強(qiáng)制路由

在功能開(kāi)發(fā)的時(shí)候就決定了哪些接口要強(qiáng)制走主庫(kù),這個(gè)時(shí)候我們會(huì)在代碼上進(jìn)行路由的控制,也就是前面講的自定義注解。如果有些是沒(méi)有加的,但是在線(xiàn)上運(yùn)行的時(shí)候發(fā)現(xiàn)還是要走主庫(kù)才可以,這個(gè)時(shí)候就需要改代碼重新發(fā)布了。

動(dòng)態(tài)強(qiáng)制路由可以結(jié)合配置中心來(lái)實(shí)現(xiàn),通過(guò)配置的方式來(lái)決定哪些接口要強(qiáng)制路由,然后在 Filter 中通過(guò) HintManager  來(lái)設(shè)置,避免改代碼重啟。

也可以通過(guò)切面精確到業(yè)務(wù)方法級(jí)別的動(dòng)態(tài)路由配置。

流量分發(fā)

場(chǎng)景一:

假設(shè)你有一個(gè)主節(jié)點(diǎn),兩個(gè)從節(jié)點(diǎn),讀請(qǐng)求較多,兩個(gè)從節(jié)點(diǎn)壓力有點(diǎn)大。這個(gè)時(shí)候只能增加第三個(gè)從節(jié)點(diǎn)來(lái)分擔(dān)壓力?,F(xiàn)象是主庫(kù)的壓力并不大,寫(xiě)入較少,從成本來(lái)考慮,是否可以不增加第三個(gè)從節(jié)點(diǎn)呢?

場(chǎng)景二:

假設(shè)你有一個(gè) 8 核 64G 的主庫(kù),8 核 64G 的從庫(kù),4 核 32G 的從庫(kù),從配置上來(lái)看,4 核 32G  的從庫(kù)處理能力肯定是要低于其他兩個(gè)的,這個(gè)時(shí)候如果我們沒(méi)有定制流量分發(fā)的比例,就會(huì)出現(xiàn)低配數(shù)據(jù)庫(kù)壓力過(guò)高而導(dǎo)致的問(wèn)題。當(dāng)然這個(gè)也能避免使用不同規(guī)則的從庫(kù)。

上面的場(chǎng)景需要能夠?qū)φ?qǐng)求進(jìn)行管理,在 Sharding-JDBC 中提供了讀寫(xiě)分離的路由算法,我們可以自定義算法來(lái)進(jìn)行流量的分發(fā)管理。

實(shí)現(xiàn)算法類(lèi):

public class KittyMasterSlaveLoadBalanceAlgorithm implements MasterSlaveLoadBalanceAlgorithm {     private RoundRobinMasterSlaveLoadBalanceAlgorithm roundRobin = new RoundRobinMasterSlaveLoadBalanceAlgorithm();     @Override     public String getDataSource(String name, String masterDataSourceName, List slaveDataSourceNames) {         String dataSource = roundRobin.getDataSource(name, masterDataSourceName, slaveDataSourceNames);         // 控制邏輯,比如不同的從節(jié)點(diǎn)(配置不同)可以有不同的比例         return dataSource;     }     @Override     public String getType() {         return "KITTY_ROUND_ROBIN";     }     @Override     public Properties getProperties() {         return roundRobin.getProperties();     }     @Override     public void setProperties(Properties properties) {         roundRobin.setProperties(properties);     } }

基于 SPI 機(jī)制的配置:

org.apache.shardingsphere.core.strategy.masterslave.RoundRobinMasterSlaveLoadBalanceAlgorithm org.apache.shardingsphere.core.strategy.masterslave.RandomMasterSlaveLoadBalanceAlgorithm com.cxytiandi.kitty.db.shardingjdbc.algorithm.KittyMasterSlaveLoadBalanceAlgorithm

讀寫(xiě)分離的配置:

spring.shardingsphere.masterslave.load-balance-algorithm-class-name=com.cxytiandi.kitty.db.shardingjdbc.algorithm.KittyMasterSlaveLoadBalanceAlgorithm spring.shardingsphere.masterslave.load-balance-algorithm-type=KITTY_ROUND_ROBIN

感謝各位的閱讀,以上就是“怎么做數(shù)據(jù)庫(kù)讀寫(xiě)分離”的內(nèi)容了,經(jīng)過(guò)本文的學(xué)習(xí)后,相信大家對(duì)怎么做數(shù)據(jù)庫(kù)讀寫(xiě)分離這一問(wèn)題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!


文章標(biāo)題:怎么做數(shù)據(jù)庫(kù)讀寫(xiě)分離
網(wǎng)站地址:http://weahome.cn/article/gepjed.html

其他資訊

在線(xiàn)咨詢(xún)

微信咨詢(xún)

電話(huà)咨詢(xún)

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部