亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么做數據庫讀寫分離

發布時間:2021-10-22 15:41:05 來源:億速云 閱讀:120 作者:iii 欄目:數據庫

這篇文章主要講解了“怎么做數據庫讀寫分離”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“怎么做數據庫讀寫分離”吧!

實現方式

對于讀寫分離的使用,主要分為兩種方式,客戶端方式和代理方式。

客戶端方式可以自己用 Spring 自帶的 AbstractRoutingDataSource 來實現,也可以用開源的框架來實現,比如  Sharding-JDBC。

怎么做數據庫讀寫分離

代理方式需要編寫代理服務來對所有節點進行管理,應用不需要關注多個數據庫節點信息。可以自己實現,也可以用開源的框架,也可以用商業的云服務。

怎么做數據庫讀寫分離

數據延遲

談到數據延遲,你先得理解主從架構的原理。對數據的增刪改操作在主庫上執行,查詢在從庫上執行,當數據剛插入到主庫,然后馬上去查詢的時候,很有可能數據還沒同步到從庫上,就會出現查詢不到的情況。

像我之前在某些網站發表文章,發表之后跳轉到列表頁面,發現沒有新發表的文章,重新刷新下頁面又有了,這一看這就是讀寫分離后的數據延遲導致的現象。

強制路由數據延遲要不要解決,一般取決于業務場景。對于實時性要求沒有那么高的業務場景,允許一定的延遲,對于實時性要求高的場景,唯一的方式就是直接從主庫進行查詢,這樣才能及時讀到剛插入或者修改后最新的數據。

強制路由

就是一種解決方案,也就是將讀請求強制分發到主庫進行查詢。大部分中間件都支持 Hint  語法/FORCE_MASTER/和/FORCE_SLAVE/。

以 Sharding-JDBC 舉例,框架提供了 HintManager 來強制路由,使用方式如下:

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

為了方便使用,建議封裝一個注解,在需要實時查詢的業務方法上加上注解,通過切面進行強制路由的設置。

注解使用:

@MasterRoute @Override public UserBO getUser(Long id) {     log.info("查詢用戶 [{}]", 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); }

切面設置:

@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();         }     } }

事務操作

在事務中的讀請求,走主庫還是從庫呢?對于這個問題,最簡單的方式就是所有事務中的操作都走主庫,在事務中經常會存在插入,然后再重新查詢的場景,此時事務沒提交,就算同步很快,從庫也是沒有數據的,所以只能走主庫。

但還有一些請求,只需要查詢從庫就行了,如果針對所有事務中的操作都強制路由,也不是很好。在 Sharding-JDBC  中的做法挺好的,對于同一線程且同一數據庫連接內,如有寫入操作,以后的讀操作均從主庫讀取,用于保證數據一致性。如果我們在數據寫入之前有查詢請求,還是走的從庫,減輕主庫壓力。

怎么做數據庫讀寫分離

動態強制路由

在功能開發的時候就決定了哪些接口要強制走主庫,這個時候我們會在代碼上進行路由的控制,也就是前面講的自定義注解。如果有些是沒有加的,但是在線上運行的時候發現還是要走主庫才可以,這個時候就需要改代碼重新發布了。

動態強制路由可以結合配置中心來實現,通過配置的方式來決定哪些接口要強制路由,然后在 Filter 中通過 HintManager  來設置,避免改代碼重啟。

也可以通過切面精確到業務方法級別的動態路由配置。

流量分發

場景一:

假設你有一個主節點,兩個從節點,讀請求較多,兩個從節點壓力有點大。這個時候只能增加第三個從節點來分擔壓力。現象是主庫的壓力并不大,寫入較少,從成本來考慮,是否可以不增加第三個從節點呢?

場景二:

假設你有一個 8 核 64G 的主庫,8 核 64G 的從庫,4 核 32G 的從庫,從配置上來看,4 核 32G  的從庫處理能力肯定是要低于其他兩個的,這個時候如果我們沒有定制流量分發的比例,就會出現低配數據庫壓力過高而導致的問題。當然這個也能避免使用不同規則的從庫。

上面的場景需要能夠對請求進行管理,在 Sharding-JDBC 中提供了讀寫分離的路由算法,我們可以自定義算法來進行流量的分發管理。

實現算法類:

public class KittyMasterSlaveLoadBalanceAlgorithm implements MasterSlaveLoadBalanceAlgorithm {     private RoundRobinMasterSlaveLoadBalanceAlgorithm roundRobin = new RoundRobinMasterSlaveLoadBalanceAlgorithm();     @Override     public String getDataSource(String name, String masterDataSourceName, List<String> slaveDataSourceNames) {         String dataSource = roundRobin.getDataSource(name, masterDataSourceName, slaveDataSourceNames);         // 控制邏輯,比如不同的從節點(配置不同)可以有不同的比例         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 機制的配置:

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

讀寫分離的配置:

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

感謝各位的閱讀,以上就是“怎么做數據庫讀寫分離”的內容了,經過本文的學習后,相信大家對怎么做數據庫讀寫分離這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

定结县| 巩留县| 内江市| 南丹县| 三门县| 沈丘县| 武功县| 高雄市| 荔浦县| 临邑县| 阳原县| 福贡县| 兴城市| 堆龙德庆县| 当阳市| 屯昌县| 安达市| 原阳县| 灵山县| 皋兰县| 古交市| 穆棱市| 南丰县| 洛宁县| 三门县| 大安市| 沛县| 丹东市| 新巴尔虎左旗| 江达县| 津市市| 高州市| 嘉定区| 铜山县| 子洲县| 庆城县| 蓝山县| 新和县| 临武县| 台南县| 石城县|