• [zebra源码]如果定位到多个分库或分表怎么执行的?


    假设分库分表情况如下

    • 分库 id0:分表  test_0 、 test_1
    • 分库 id1:   分表  test_2、  test_3

    sql语句: select test.* from test

    一、路由结果

    DefaultRouter#router 路由出来的结果两个 RouterResult, 每个里边有多个分表的sql, 即所有分库下的所有test分表

    dbName: id0
    sqls:
    - SELECT test_0.* 
    FROM test_0
    - SELECT test_1.* 
    FROM test_1
    
    dbName: id1
    sqls:
    - SELECT test_2.* 
    FROM test_2
    - SELECT test_3.* 
    FROM test_3
    

    二、执行过程

    如果路由定位到多个分库,会根据并发度n,将每个分库的sql语句 拆分成n个任务,放入线程池执行
    默认单库并发度 concurrentLevel = 1, 执行过程为

    (1) 执行分库id0里各分表的sql

    • 从分库id0 对应的数据源中一个数据连接,创建 (SELECT test_0.* FROM test_0)的 statement
    • 从分库id0 对应的数据源中一个数据连接,创建l (SELECT test_1.* FROM test_1 )的statement
    • 把这两个statement包裹到一个线程task中

    (2) 执行分库id1里各分表的sql

    • 从分库id1 对应的数据源中一个数据连接,创建 (SELECT test_2.* FROM test_2 ) 的statement
    • 从分库id1 对应的数据源中一个数据连接,创建l (SELECT test_3.* FROM test_3 )的statement
    • 把这两个statement包裹到一个线程task中

    (3) 把这两个task 丢到 SQLThreadPoolExecutor 中执行, 阻塞等待执行完毕

    三、结果集合并

    ShardResultSet#init() -> ShardResultSetMerger.merge 合并这四个 ResultSet

    ShardResultSet 内部包含多个sql执行的结果集 ResultSet, 它实现了 ResultSet ,当从它遍历查询结果的时候,会根据 MergeContext( join、limit…etc)来组合结果数据

    debug单测入口:

    com.dianping.zebra.shard.jdbc.MultiDBPreparedStatementLifeCycleTest#testSingleRouterResult1

    总结

    路由定位到多个分库或分表的执行逻辑:

    ShardPrepardStatement#normalSelectExecute 会依次执行这多个路由目标分库 RouterResult 内的语句,然后 ShardPrepardStatement#executeQueryByOriginal执行单个分库内的所有sql, 如果它发现有多个sql需要执行,则会根据 单库并发度的配置 concurrentLevel=1

    (1)  默认concurrentLevel = 1  ,每个分库内不同表的sql, 先创建对应的 statement, 然后会打包到一个task里

    (2) 如果 concurrentLevel > 1, 则每个分库会获取 concurrentLevel 个数据库连接,将这几条分表的sql均摊到这几个数据库连接,创建多个statement, 包成 concurrentLevel 个线程task

    (3) 然后丢到java线程池中并发执行  ,然后阻塞等待执行完毕,获取结果

    完整目录:数据库中间件zebra源码分析

    本文来自博客园,作者:mushishi,转载请注明原文链接:https://www.cnblogs.com/mushishi/p/15022072.html

  • 相关阅读:
    OracleSql语句学习(一)
    java(2019)面试题整理所
    用Eclipse中的git提交代码流程
    C# 导出数据到Excel模板中(转)
    C# 导出Excel的示例(转)
    JS中window.showModalDialog()详解(转)
    C#多线程编程(转)
    文件各种上传,离不开的表单(转自——因为菜,所以要好好学习、天天向上! —— 农码一生)
    WebApi Ajax 跨域请求解决方法(CORS实现)(作者:jianxuanbing)
    如何将ASP.NET-WebApi发布到IIS6.0上(转)
  • 原文地址:https://www.cnblogs.com/mushishi/p/15022072.html
Copyright © 2020-2023  润新知