您好,登錄后才能下訂單哦!
Sharding-JDBC的架構以及源碼的示例分析,針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。
Sharding-jdbc 系統架構分成5個部分:
SQL解析
SQL路由
SQL改寫
SQL執行
結果集歸并
下面從上面五個部分來分析Sharding-jdbc
執行方法
org.apache.shardingsphere.shardingjdbc.jdbc.core.statement.ShardingPreparedStatement.execute()
方法源碼
@Override public boolean execute() throws SQLException { try { //本地緩存清空 clearPrevious(); /** * 路由 * */ shard(); // 初始化 preparedStatement initPreparedStatementExecutor(); // 執行sql return preparedStatementExecutor.execute(); } finally { clearBatch(); } }
org.apache.shardingsphere.core.BaseShardingEngine.shard(String, List<Object>)
public SQLRouteResult shard(final String sql, final List<Object> parameters) { List<Object> clonedParameters = cloneParameters(parameters); // 根據SQL去路由 SQLRouteResult result = executeRoute(sql, clonedParameters); // 改寫sql result.getRouteUnits().addAll(HintManager.isDatabaseShardingOnly() ? convert(sql, clonedParameters, result) : rewriteAndConvert(sql, clonedParameters, result)); // 打印路由后的sql if (shardingProperties.getValue(ShardingPropertiesConstant.SQL_SHOW)) { boolean showSimple = shardingProperties.getValue(ShardingPropertiesConstant.SQL_SIMPLE); SQLLogger.logSQL(sql, showSimple, result.getShardingStatement(), result.getRouteUnits()); } return result; }
一些路由相關的hook在這里執行。
org.apache.shardingsphere.core.BaseShardingEngine.executeRoute(String, List<Object>)
private SQLRouteResult executeRoute(final String sql, final List<Object> clonedParameters) { routingHook.start(sql); try { SQLRouteResult result = route(sql, clonedParameters); routingHook.finishSuccess(result, metaData.getTables()); return result; // CHECKSTYLE:OFF } catch (final Exception ex) { // CHECKSTYLE:ON routingHook.finishFailure(ex); throw ex; } }
org.apache.shardingsphere.core.route.PreparedStatementRoutingEngine.route(List<Object>)
public SQLRouteResult route(final List<Object> parameters) { if (null == sqlStatement) { // 解析SQL sqlStatement = shardingRouter.parse(logicSQL, true); } /** * 第一步:根據上面異步解析出來的sqlStatement,結合配置的路由規則,找到對應的物理表表名 * 第二步:這里是主從(讀寫)路由,根據sql的類型(select、DML)決定走主庫還是從庫。 */ return masterSlaveRouter.route(shardingRouter.route(logicSQL, parameters, sqlStatement)); }
org.apache.shardingsphere.core.parse.SQLParseEngine.parse0(String, boolean)
private SQLStatement parse0(final String sql, final boolean useCache) { …… // 創建一個根據數據庫匹配的解析引擎,解析sql。比如mysql的sql創建mysql的數據解析引擎。 SQLStatement result = new SQLParseKernel(ParseRuleRegistry.getInstance(), databaseType, sql).parse(); if (useCache) { cache.put(sql, result); } return result; }
這個是解析sql。這個方法不再深入了。
org.apache.shardingsphere.core.parse.core.SQLParseKernel.parse()
public SQLStatement parse() { // 解析sql SQLAST ast = parserEngine.parse(); // 抽取sql 片段 Collection<SQLSegment> sqlSegments = extractorEngine.extract(ast); Map<ParserRuleContext, Integer> parameterMarkerIndexes = ast.getParameterMarkerIndexes(); return fillerEngine.fill(sqlSegments, parameterMarkerIndexes.size(), ast.getSqlStatementRule()); }
org.apache.shardingsphere.core.route.router.sharding.ParsingSQLRouter.route(String, List<Object>, SQLStatement)
public SQLRouteResult route(final String logicSQL, final List<Object> parameters, final SQLStatement sqlStatement) { /** * 根據sql類型,生成不同的優化引擎。比如我這里調試用的是select語句,生成就是ShardingSelectOptimizeEngine 實例。 * 對 語句進行優化 */ ShardingOptimizedStatement shardingStatement = ShardingOptimizeEngineFactory.newInstance(sqlStatement).optimize(shardingRule, metaData.getTables(), logicSQL, parameters, sqlStatement); boolean needMergeShardingValues = isNeedMergeShardingValues(shardingStatement); if (shardingStatement instanceof ShardingConditionOptimizedStatement && needMergeShardingValues) { checkSubqueryShardingValues(shardingStatement, ((ShardingConditionOptimizedStatement) shardingStatement).getShardingConditions()); mergeShardingConditions(((ShardingConditionOptimizedStatement) shardingStatement).getShardingConditions()); } /** * 這里獲取一個路由引擎,這里有各種引擎,常見的有 StandardRoutingEngine、ComplexRoutingEngine * 這次獲取的就是 獲取一個 StandardRoutingEngine 路由引擎。(shardingtable數目為1,或者所有的表都是有綁定關系的) * 接著執行 StandardRoutingEngine.route方法 * */ RoutingResult routingResult = RoutingEngineFactory.newInstance(shardingRule, metaData.getDataSources(), shardingStatement).route(); if (needMergeShardingValues) { Preconditions.checkState(1 == routingResult.getRoutingUnits().size(), "Must have one sharding with subquery."); } // 分布式主鍵插入 if (shardingStatement instanceof ShardingInsertOptimizedStatement) { setGeneratedValues((ShardingInsertOptimizedStatement) shardingStatement); } // 加密 EncryptOptimizedStatement encryptStatement = EncryptOptimizeEngineFactory.newInstance(sqlStatement) .optimize(shardingRule.getEncryptRule(), metaData.getTables(), logicSQL, parameters, sqlStatement); SQLRouteResult result = new SQLRouteResult(shardingStatement, encryptStatement); result.setRoutingResult(routingResult); return result; }
org.apache.shardingsphere.core.route.type.standard.StandardRoutingEngine.route()
public RoutingResult route() { if (isDMLForModify(optimizedStatement.getSQLStatement()) && !optimizedStatement.getTables().isSingleTable()) { throw new ShardingException("Cannot support Multiple-Table for '%s'.", optimizedStatement.getSQLStatement()); } /** * 1、根據邏輯表名去拿分表規則 * 2、根據分表規則 去拿DataNode(key 為 dataSourceName,value 為物理表表名)。 * 3、將上面的 dataNode 封裝成 RoutingResult */ return generateRoutingResult(getDataNodes(shardingRule.getTableRule(logicTableName))); }
關于Sharding-JDBC的架構以及源碼的示例分析問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。