AVt天堂网 手机版,亚洲va久久久噜噜噜久久4399,天天综合亚洲色在线精品,亚洲一级Av无码毛片久久精品

當前位置:首頁 > 科技  > 軟件

Shardingjdbc啟動優化,你學會了嗎?

來源: 責編: 時間:2023-11-07 09:12:39 277觀看
導讀一.Sharding-JDBC 啟動優化問題分析最近在本地調試的時候發現,項目本地啟動比較慢,對啟動日志進行分析,Sharding-JDBC 在加載元數據的過程中中耗時 116 秒 ,占用了項目啟動時間的一半。[org.apache.shardingsphere.core.l

一.Sharding-JDBC 啟動優化

問題分析

最近在本地調試的時候發現,項目本地啟動比較慢,對啟動日志進行分析,Sharding-JDBC 在加載元數據的過程中中耗時 116 秒 ,占用了項目啟動時間的一半。2pP28資訊網——每日最新資訊28at.com

[org.apache.shardingsphere.core.log.ConfigurationLogger:104] : [0||0] Properties:max.connections.size.per.query: '1'[org.apache.shardingsphere.core.metadata.ShardingMetaDataLoader:131] : [0||0] Loading 2 logic tables' meta data.[org.apache.shardingsphere.sql.parser.binder.metadata.schema.SchemaMetaDataLoader:70] : [0||0] Loading 401 tables' meta data.[org.apache.shardingsphere.shardingjdbc.jdbc.core.context.MultipleDataSourcesRuntimeContext:59] : [0||0] Meta data load finished, cost 115930 milliseconds.

分析加載流程,核心部分在 SchemaMetaDataLoader#load。2pP28資訊網——每日最新資訊28at.com

List<List<String>> tableGroups = Lists.partition(tableNames, Math.max(tableNames.size() / maxConnectionCount, 1));Map<String, TableMetaData> tableMetaDataMap = 1 == tableGroups.size()        ? load(dataSource.getConnection(), tableGroups.get(0), databaseType) : asyncLoad(dataSource, maxConnectionCount, tableNames, tableGroups, databaseType);

進入代碼看一下,發現這里會根據 maxConnectionCount 對數據庫的表分組進行不同的加載策略,往上游看一下這個 maxConnectionCount 來源于 Sharding-JDBC 的配置,默認為 1。2pP28資訊網——每日最新資訊28at.com

public enum ConfigurationPropertyKey implements TypedPropertyKey {  //.......  /**   * Max opened connection size for each query.   */  MAX_CONNECTIONS_SIZE_PER_QUERY("max.connections.size.per.query", String.valueOf(1), int.class)  //......}

那是不是把這個配置擴展一下就可以提高啟動速度了?在將配置隨意設置成 8 之后由 116s 提升至 15s。2pP28資訊網——每日最新資訊28at.com

從這里來看啟動問題解決了,同時也產生了疑問,為什么 max.connections.size.per.query 默認值設置為 1。2pP28資訊網——每日最新資訊28at.com

這里是官網對于配置的解釋,物理數據庫為每次查詢分配的最大連接數量。2pP28資訊網——每日最新資訊28at.com

圖片2pP28資訊網——每日最新資訊28at.com

光看字面意思無法評估影響面,那就從 Sharding-JDBC 的查詢入口開始看一下 ShardingPreparedStatement#executeQuery2pP28資訊網——每日最新資訊28at.com

public ResultSet executeQuery() throws SQLException {  ResultSet result;  try {  clearPrevious();  prepare();  initPreparedStatementExecutor();  MergedResult mergedResult = mergeQuery(preparedStatementExecutor.executeQuery());  result = new ShardingResultSet(preparedStatementExecutor.getResultSets(), mergedResult, this, executionContext);  } finally {  clearBatch();  }  currentResultSet = result;  return result;}

......2pP28資訊網——每日最新資訊28at.com

SQLExecutePrepareTemplate#getSQLExecuteGroups2pP28資訊網——每日最新資訊28at.com

private List<InputGroup<StatementExecuteUnit>> getSQLExecuteGroups(  final String dataSourceName,  final List<SQLUnit> sqlUnits,  final SQLExecutePrepareCallback callback) throws SQLException {  List<InputGroup<StatementExecuteUnit>> result = new LinkedList<>();  int desiredPartitionSize = Math.max(0 == sqlUnits.size() % maxConnectionsSizePerQuery ? sqlUnits.size() / maxConnectionsSizePerQuery : sqlUnits.size() / maxConnectionsSizePerQuery + 1, 1);  List<List<SQLUnit>> sqlUnitPartitions = Lists.partition(sqlUnits, desiredPartitionSize);  ConnectionMode connectionMode = maxConnectionsSizePerQuery < sqlUnits.size() ? ConnectionMode.CONNECTION_STRICTLY : ConnectionMode.MEMORY_STRICTLY;  List<Connection> connections = callback.getConnections(connectionMode, dataSourceName, sqlUnitPartitions.size());  int count = 0;  for (List<SQLUnit> each : sqlUnitPartitions) {      result.add(getSQLExecuteGroup(connectionMode, connections.get(count++), dataSourceName, each, callback));  }  return result;}

這里可以看到,根據 maxConnectionsSizePerQuery 選擇了不同的模式 CONNECTION_STRICTLY 、 MEMORY_STRICTLY2pP28資訊網——每日最新資訊28at.com

這里先說一下 sqlUnits 是什么,在分表之后進行查詢,如果查詢參數中不帶分片參數的話,Sharding-JDBC 會將 SQL 進行處理,例:2pP28資訊網——每日最新資訊28at.com

select * from table where field= “測試查詢”;

實際執行的過程中會被處理成2pP28資訊網——每日最新資訊28at.com

select * from table0 where field = “測試查詢”; select * from table1 where field = “測試查詢”; select * from table2 where field = “測試查詢”; ...... select * from table(n-1) where field = “測試查詢”;

Sharding-JDBC 會將真實 SQL 查詢的數據進行聚合,聚合的方式根據 maxConnectionsSizePerQuery 配置有兩種,即 CONNECTION_STRICTLY、MEMORY_STRICTLY。2pP28資訊網——每日最新資訊28at.com

CONNECTION_STRICTLY 可以理解為對同一數據源最多創建 maxConnectionsSizePerQuery 個連接。2pP28資訊網——每日最新資訊28at.com

MEMORY_STRICTLY 則是對一次操作的數據庫連接不做限制,同一數據源 n 張分表就創建 n 個連接,多線程并發處理。2pP28資訊網——每日最新資訊28at.com

從理論上看,是不是可以將 max.connections.size.per.query 設置的大一點,只要單次操作創建的數據源不超過數據庫連接上限就可以了?其實不一定,這里進入 UPDATE 的方法看一下。2pP28資訊網——每日最新資訊28at.com

public int executeUpdate() throws SQLException {  try {  clearPrevious();  prepare();  initPreparedStatementExecutor();  return preparedStatementExecutor.executeUpdate();  } finally {  clearBatch();  }}

發現這里在執行 SQL 前同 SELECT 執行了一樣的預處理邏輯 initPreparedStatementExecutor() ,那么在 max.connections.size.per.query > 1 的情況下,無論是那種模式都可能會根據配置的不同獲取多個數據源,執行 UPDATE 就有可能存在死鎖問題。2pP28資訊網——每日最新資訊28at.com

例:2pP28資訊網——每日最新資訊28at.com

@Transactionalpublic void test(){  updateByID(1);  updateByKey(1);}

圖片圖片2pP28資訊網——每日最新資訊28at.com

所以最終得出結論目前狀態下,測試環境、預發環境可對max.connections.size.per.query 進行配置,提高啟動速度,在線上環境 max.connections.size.per.query 默認為 1 保證應用的穩定。2pP28資訊網——每日最新資訊28at.com

總結

在分析啟動問題的過程中對 Sharding-JDBC 查詢過程進行了簡單的了解,規避了線上可能引發的問題,同時也提醒了自己在改動一些配置時需要對配置所涉及的影響面進行充分評估后再進行改動。2pP28資訊網——每日最新資訊28at.com

參考資料

  • Sharding-JDBC 官方文檔 https://shardingsphere.apache.org/document/current/cn/overview/

本文鏈接:http://www.tebozhan.com/showinfo-26-17373-0.htmlShardingjdbc啟動優化,你學會了嗎?

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 開發微服務的九個最佳實踐

下一篇: Golang 中的 Bytes 包詳解之Bytes.Buffer

標簽:
  • 熱門焦點
Top