中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

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

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

Sharding-JDBC的架構以及源碼的示例分析

發布時間:2021-10-09 11:44:59 來源:億速云 閱讀:337 作者:柒染 欄目:大數據

Sharding-JDBC的架構以及源碼的示例分析,針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

Sharding-jdbc架構

Sharding-JDBC的架構以及源碼的示例分析

Sharding-jdbc 系統架構分成5個部分:

  1. SQL解析

  2. SQL路由

  3. SQL改寫

  4. SQL執行

  5. 結果集歸并

下面從上面五個部分來分析Sharding-jdbc

功能模塊

SQL解析

SQL路由

SQL路由序列圖

Sharding-JDBC的架構以及源碼的示例分析

調用鏈

ShardingPreparedStatement.execute

執行方法

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();
        }
    }
BaseShardingEngine.shard
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;
    }
BaseShardingEngine.executeRoute

一些路由相關的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;
        }
    }
PreparedStatementRoutingEngine.route
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));
    }
SQLParseEngine.parse0
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;
    }
SQLParseKernel.parse

這個是解析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());
    }
ParsingSQLRouter.route ( 重要)
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;
    }
StandardRoutingEngine.route(重要)
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)));
    }

SQL改寫

SQL執行

關于Sharding-JDBC的架構以及源碼的示例分析問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。

向AI問一下細節

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

AI

洪雅县| 扶沟县| 吴堡县| 林州市| 公主岭市| 芦山县| 灵寿县| 泰宁县| 霞浦县| 云南省| 六盘水市| 绥德县| 龙泉市| 海南省| 许昌县| 清丰县| 图木舒克市| 开鲁县| 昂仁县| 福泉市| 习水县| 溆浦县| 清河县| 永福县| 游戏| 夏邑县| 米易县| 吴旗县| 台南市| 莎车县| 马公市| 伊宁市| 锡林郭勒盟| 屏南县| 无为县| 阿城市| 新源县| 南丰县| 无极县| 梁平县| 牙克石市|