mycat catlet初步探析续

分析catlet,画出Mycat收到新连接请求,执行SQL,返回结果集的过程中所涉及到的重要类,方法,以及逻辑


样例SQL:Select a.id,a.name,b.title from a,b where a.id=b.id
**分布:**假如sql涉及到多个节点。

大概mycat的流程如下:
1,前端sql请求过来,调用RouteService类,会跟原始SQL进行判断需要返回哪个 RouteResultset,同时会对返回结果进行缓存,在这个类里面加载catletclass,并且调用route方法、调用processSQL方法。

public RouteResultset route(SystemConfig sysConfig, SchemaConfig schema,  
        int sqlType, String realSQL, String charset, ServerConnection sc,  
        LayerCachePool cachePool, String hintSQLValue,int hintSqlType, Map hintMap)  
        throws SQLNonTransientException {  
    // sc.setEngineCtx ctx  
    String cateletClass = hintSQLValue;  
    if (LOGGER.isDebugEnabled()) {  
        LOGGER.debug("load catelet class:" + hintSQLValue + " to run sql "  
                + realSQL);  
    }  
    try {  
        Catlet catlet = (Catlet) MycatServer.getInstance()  
                .getCatletClassLoader().getInstanceofClass(cateletClass);  
        catlet.route(sysConfig, schema, sqlType, realSQL,charset, sc, cachePool);  
        catlet.processSQL(realSQL, new EngineCtx(sc.getSession2()));  
    } catch (Exception e) {  
        LOGGER.warn("catlet error "+e);  
        throw new SQLNonTransientException(e);  
    }  
    return null;  
}  

1.1,new DirectDBJoinHandler(ctx)加载handler
1.2,ctx.executeNativeSQLSequnceJob(dataNodes,sql,joinHandler);一个个处理节点,串行不并行担心内存撑了(bty,可以设置大内存用来并行处理吗)

public void executeNativeSQLSequnceJob(String[] dataNodes, String sql,  
            SQLJobHandler jobHandler) {  
        for (String dataNode : dataNodes) {  
            SQLJob job = new SQLJob(jobId.incrementAndGet(), sql, dataNode,  
                    jobHandler, this);  
            bachJob.addJob(job, false);  
  
        }  
    }  

2,Jobhandler处理
2.1 onHeadler方法;记录当前处理的datanode数据节点和处理字段
2.2 onRowData方法;收到一行记录开始处理,根据fielads得到id信息
2.3 rows.put(id,rowData)方法、ids.offer(id)方法;放入结果集
2.4 createQryJob方法;满足>1000调用,执行下一批job,进去B里面
2.5 executeNativeSQLParallJob方法;获取join的B表数据,
2.6 onRowData方法;获取id字符,加入A表记录形成新的报文结果集,有B字段
2.7 ctx.writeRow(rowDataPkg)方法;把新记录write出来

3,循环执行1.2到2.7遍历完所有节点
4,onAllJobFinished方法;
5,ctx.writeEof方法;最后执行ctx写入,输出结果集标记,前端就可以得到执行结果了。


–随笔
1,EngineCtx类,里面有一个jobId,保持每一个sql的job任务都是唯一的,jobId递增。

2,EngineCtx(NonBlockingSession session){…}里面保存了sql的job任务

3,会去调用executeNativeSQLSequnceJob(String[] datanodes,String sql,SQLJobHandler jobHandler)方法在executeNativeSQLSequnceJob方法里面,会循环数据节点组datenodes,每一个循环里面先new SQLJob一个SQLJob出来(SQLJob sqljob=new SQLJob(jobId.incrementAndGet(),sql,dateNode,jobHandler,this);),sqljob会包含sql信息和datanode节点信息,然后讲这个sqljob添加进来,有一个参数false和true,true表示立即执行这个job,代码:bachJob.addJob(sqljob,true);然后在addJob方法里面,就会调用runJob方法。

4,讲下SQL Job
在connnectionAcquired方法里面,一句代码conn.query()异步通知处理后端数据,调用了rowResponse方法rowEofReponse方法,这里面执行代码conn.syncAndExcute()来执行数据处理,而数据处理都是交给SQLJobHandler来实现。里面就有个报文头onHeader(),onRowData()数据处理,finished()处理过程,实际上只要实现了QLJobHandler就可以实现我们自己的catlet了。

5,catlet
catlet只有2个接口,一个是processSQL,一个是route,route就是路由到什么地方去的问题,在HintCatletHandler里面做路由端口,先加载一个catlet,然后会调用catlet.route方法,route过程中主要是去看catlet产生哪样一些的job去执行,然后调用processSQL去执行。

6,catlet demo
以一个跨节点的SQL为例,
Select a.id,a.name,b.title from a,b where a.id=b.id
其中a在分片1,2,3上,b在4,5,6上,需要把数据全部拉到本地(MyCAT服务器),执行JOIN逻辑,具体过程如下(只是一种可能的执行逻辑):
EngineCtx ctx=new EngineCtx();//包含 MyCat.SQLEngine
String sql=,“select a.id ,a.name from a ”;
//在a表所在的所有分片上顺序执行下面的本地SQL
ctx. executeNativeSQLSequnceJob(allAnodes,new DirectDBJoinHandler());

DirectDBJoinHandler类是一个回调类,负责处理SQL执行过程中返回的数据包,这里的这个类,主要目的是用a表返回的ID信息(这里会调用onRowData方法,满足1000条后,去调用createQryJob返回b表的数据),去b表上查询对于的记录,做实时的关联
String sql=” select b.id, b.title from hotnews b where id in (………….)”;
拼出 a.id ,a.name,b.title 完整的一行记录并输出到前端。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值