我們可以使用分布式鎖加上自旋解決這個(gè)問(wèn)題 , 本文給出一段示例代碼 , 具體原理請(qǐng)參看我之前的一篇文章:緩存穿透與擊穿問(wèn)題解決方案
/*** 業(yè)務(wù)回調(diào)** @author 微信公眾號(hào)「JAVA前線」**/public interface RedisBizCall {/*** 業(yè)務(wù)回調(diào)方法** @return 序列化后數(shù)據(jù)值*/String call();}/*** 安全緩存管理器** @author 微信公眾號(hào)「JAVA前線」**/@Servicepublic class SafeRedisManager {@Resourceprivate RedisClient RedisClient;@Resourceprivate RedisLockManager redisLockManager;public String getDataSafe(String key, int lockExpireSeconds, int dataExpireSeconds, RedisBizCall bizCall, boolean alwaysRetry) {boolean getLockSuccess = false;try {while(true) {String value = https://www.520longzhigu.com/shenghuo/redisClient.get(key);if (StringUtils.isNotEmpty(value)) {return value;}/** 競(jìng)爭(zhēng)分布式鎖 **/if (getLockSuccess = redisLockManager.tryLock(key, lockExpireSeconds)) {value = redisClient.get(key);if (StringUtils.isNotEmpty(value)) {return value;}/** 查詢數(shù)據(jù)庫(kù) **/value = bizCall.call();/** 數(shù)據(jù)庫(kù)無(wú)數(shù)據(jù)則返回**/if (StringUtils.isEmpty(value)) {return null;}/** 數(shù)據(jù)存入緩存 **/redisClient.setex(key, dataExpireSeconds, value);return value;} else {if (!alwaysRetry) {logger.warn("競(jìng)爭(zhēng)分布式鎖失敗,key={}", key);return null;}Thread.sleep(100L);logger.warn("嘗試重新獲取數(shù)據(jù),key={}", key);}}} catch (Exception ex) {logger.error("getDistributeSafeError", ex);return null;} finally {if (getLockSuccess) {redisLockManager.unLock(key);}}}}
4 分我們首先看一個(gè)概念:讀寫(xiě)比 。互聯(lián)網(wǎng)場(chǎng)景中一般是讀多寫(xiě)少 , 例如瀏覽20次訂單列表信息才會(huì)進(jìn)行1次確認(rèn)收貨 , 此時(shí)讀寫(xiě)比例就是20:1 。面對(duì)讀多寫(xiě)少這種情況我們可以做什么呢?
我們可以部署多臺(tái)MySQL讀庫(kù)專門(mén)用來(lái)接收讀請(qǐng)求 , 主庫(kù)接收寫(xiě)請(qǐng)求并通過(guò)binlog實(shí)時(shí)同步的方式將數(shù)據(jù)同步至讀庫(kù) 。MySQL官方即提供這種能力 , 進(jìn)行簡(jiǎn)單配置即可 。
那么客戶端怎么知道訪問(wèn)讀庫(kù)還是寫(xiě)庫(kù)呢?推薦使用ShardingSphere組件 , 通過(guò)配置將讀寫(xiě)請(qǐng)求分別路由至讀庫(kù)或者寫(xiě)庫(kù) 。
5 拆如果刪除了歷史數(shù)據(jù)并采用了其它存儲(chǔ)介質(zhì) , 也用了讀寫(xiě)分離 , 但是單表壓力還是太大怎么辦?這時(shí)我們只能拆分?jǐn)?shù)據(jù)表 , 即把單庫(kù)單表數(shù)據(jù)遷移到多庫(kù)多張表中 。
假設(shè)有一個(gè)電商數(shù)據(jù)庫(kù)存放訂單、商品、支付三張業(yè)務(wù)表 。隨著業(yè)務(wù)量越來(lái)越大 , 這三張業(yè)務(wù)數(shù)據(jù)表也越來(lái)越大 , 我們就以這個(gè)例子進(jìn)行分析 。
5.1 垂直拆分垂直拆分就是按照業(yè)務(wù)拆分 , 我們將電商數(shù)據(jù)庫(kù)拆分成三個(gè)庫(kù) , 訂單庫(kù)、商品庫(kù) 。支付庫(kù) , 訂單表在訂單庫(kù) , 商品表在商品庫(kù) , 支付表在支付庫(kù) 。這樣每個(gè)庫(kù)只需要存儲(chǔ)本業(yè)務(wù)數(shù)據(jù) , 物理隔離不會(huì)互相影響 。
5.2 水平拆分按照垂直拆分方案 , 現(xiàn)在我們已經(jīng)有三個(gè)庫(kù)了 , 平穩(wěn)運(yùn)行了一段時(shí)間 。但是隨著業(yè)務(wù)增長(zhǎng) , 每個(gè)單庫(kù)單表的數(shù)據(jù)量也越來(lái)越大 , 逐漸到達(dá)瓶頸 。
這時(shí)我們就要對(duì)數(shù)據(jù)表進(jìn)行水平拆分 , 所謂水平拆分就是根據(jù)某種規(guī)則將單庫(kù)單表數(shù)據(jù)分散到多庫(kù)多表 , 從而減小單庫(kù)單表的壓力 。
水平拆分策略有很多方案 , 最重要的一點(diǎn)是選好ShardingKey , 也就是按照哪一列進(jìn)行拆分 , 怎么分取決于我們?cè)L問(wèn)數(shù)據(jù)的方式 。
5.2.1 范圍分片現(xiàn)在我們要對(duì)訂單庫(kù)進(jìn)行水平拆分 , 我們選擇的ShardingKey是訂單創(chuàng)建時(shí)間 , 拆分策略如下:
(1) 拆分為四個(gè)數(shù)據(jù)庫(kù) , 分別存儲(chǔ)每個(gè)季度的數(shù)據(jù)(2) 每個(gè)庫(kù)三張表 , 分別存儲(chǔ)每個(gè)月的數(shù)據(jù)
以上關(guān)于本文的內(nèi)容,僅作參考!溫馨提示:如遇健康、疾病相關(guān)的問(wèn)題,請(qǐng)您及時(shí)就醫(yī)或請(qǐng)專業(yè)人士給予相關(guān)指導(dǎo)!
「愛(ài)刨根生活網(wǎng)」www.malaban59.cn小編還為您精選了以下內(nèi)容,希望對(duì)您有所幫助:- 湯姆索亞歷險(xiǎn)《當(dāng)海盜去》記這一文章用了什么寫(xiě)法?
- 一文讀懂全國(guó)哪些城市限行外地車(chē)輛 全國(guó)外地車(chē)限行的城市
- 一文了解額溫槍及使用方法 額溫槍正確使用方法及溫度范圍值
- 一文復(fù)盤(pán)雅戈?duì)柕纳虡I(yè)版圖:雅戈?duì)柕亩嘣l(fā)展,是對(duì)還是錯(cuò)?
- 輔酶Q10是輔助治療慢性心衰的常用藥,可以長(zhǎng)期服用嗎?一文講清
- 什么是i386,x86,RISV ? 一文了解處理器架構(gòu)
- 一文了解天貓精靈連接手機(jī)的方法 天貓精靈怎么連接的手機(jī)的
- 一文錢(qián)等于多少人民幣
- 考研統(tǒng)一文具什么樣
- 3000育人故事
