Atlas权重测试中的bug调试

一、 问题背景

    Atlasslave进行负载均衡,每一台slave都有一个权重值,权重越大,负载的读请求越多。负载均衡的算法比较巧妙,代码如下:

     

        guint max_weight = rwsplit->max_weight;
        guint cur_weight = rwsplit->cur_weight;
        guint next_ndx   = rwsplit->next_ndx;

        // get backend index by slave wrr
        gint ndx = -1;
        for(i = 0; i < ndx_num; ++i) {
                network_backend_t* backend = network_backends_get(backends, next_ndx);
                if (backend == NULL) goto next;

                network_connection_pool* pool = chassis_event_thread_pool(backend);
                if (pool == NULL) goto next;

                if (backend->type == BACKEND_TYPE_RO && 
                  backend->weight >= cur_weight && 
                  backend->state == BACKEND_STATE_UP)
                        ndx = next_ndx;

        next:
                if (next_ndx == ndx_num - 1) {
                        --cur_weight;
                        next_ndx = 0;

                        if (cur_weight == 0) cur_weight = max_weight;
                } else {
                        ++next_ndx;
                }

                if (ndx != -1) break;
        }

        rwsplit->cur_weight = cur_weight;
        rwsplit->next_ndx = next_ndx;

其中rwsplit->max_weight保存了各slave的最大权重;rwsplit->cur_weight保存了当前可选slave所需的最小权重,即slave的权重大于或等于rwsplit->cur_weight时,可以发送sql语句到这台slaverwsplit->next_ndx则保存着从哪一台slave开始检查权重。

当检查到最后一台slave时,会将cur_weight1,若cur_weight变成了0,则将它设置成max_weightnetx_ndx则置为0,表示重新从第一台slave检查起。

用一副图来表示:

Atlas权重测试中的bug调试_第1张图片

    Atlas每一次开始遍历时,从slave1开始,取每一层中的块,当发现这一层没有块可取时,再从下一层开始取,直到取完slave3的最后一台。

    现在我们要对Atlas的负载均衡进行测试。

    我们想到的方案是,在后台建一个test表,表由自增的id和一个数值value组成,插入100条数据,value的值为0~99;同步后,所有slave里面的数据都会一样。修改slave2test表中的value值,改为100~199slave3中的改为200~299。然后对Atlas发送取值的select语句,这样,根据得到的值,我们就可以知道这条语句发送到了哪台slave

    测试用shell脚本写成,因此每一次取值都得建立一次连接。连接与查询语句如下:

    mysql –h198.168.10.1 –P1234 –uroot –p1234 –N –e “use test; select value from test where id = $id;”

二、 问题现象

    进行读写分离对slave机器的负载均衡进行测试时,发现对三台slave的权重配比为1、1、2,211121时,所有的查询结果都将来自最后一台slave;从现象上来看,这时权重没有发生作用,所有读都转发给了同一台slave。

三、 解决思路

    首先检查了一下slave的权重选择算法,没有发现问题。试用了一下其的权重配比,能得到正确的结果。

    在权重选择部分加入每次权重选择后的输出,发现会按正确的配比进行输出。

    对每条sql语句进行输出,发现发送过来的语句不止“select value from test where id = $id;”,还有“select @@version_comment limit 1;”、”select database()”、”test”这三条语句。 

四、 定位问题

    测试脚本是另一个同事写的,所以一开始并不知道具体写法,只是拿来运行。

    当看到发送过来的语句后,我笑了。众里寻她千百度,bug在此处。心中的疑惑消逝了,一个上午紧张的查找没有白费。

    从出现“问题”的配比来看,我们知道所有比重分成了4份,而发送过来的语句刚好也是4条,很巧的是,最后一条取数据的语句总是发送给了slave3,所以,获取的数据值都是来自slave3,这时就出现了“权重没有发生作用”的现象。也就是说,bug不存在,这是巧合。




你可能感兴趣的:(Atlas,源码,linux,c,bug,调试)