使用libdrizzle实现mysql代理服务器的问题及优化

近期项目需要一个mysql代理服务器,实现mysql协议代理和路由功能,形成简单的mysql集群服务。现成的开源方案是mysql-proxy , 分析功能和源代码后发现跟我们的应用场景不太匹配,于是决定重新实现一个符合需求的mysql代理服务器,考虑到需要完美支持mysql协议,优先选择了libdrizzle库, libdrizzle是开源项目drizzle中的协议库,而drizzle可以看作mysql的分支版本,目前稳定版本是7.1.36 , 下面主要是记录使用libdrizzle中遇到的一些问题。
1. 关于nonblock模式的问题,现代应用服务器典型架构一般是使用reactor/proactor模式的事件驱动模型,如何把libdrizzle和应用服务器的驱动模型很好的结合起来尤其重要,  libdrizzle支持nonblock模式,独立实现了事件驱动机制,使用poll监控网络事件,具体在drizzle_con_wait()中实现,然后通过drizzle_con_ready()遍历产生事件的网络连接,即drizzle_con_st对象,该接口难以与通常的网络事件驱动机制配合使用,性能也不太理想,具体用法可参见其自带的样例程序examples/client.cc , 也就是说libdrizzle的驱动模型需要重新封装成跟应用服务器相匹配,才能真正发挥nonblock模式的性能。

2. drizzle_result_st对象初始时一些内部数据没有初始化,容易造成程序崩溃,因此需要修改构造函数,初始化所有内部数据。涉及文件libdrizzle-2.0/structs.h 
相应字段为field, field_buffer,row 。

3. libdrizzle中运行时产生的内部对象都以双链表形式挂接在其上级对象中,例如drizzle_st对象中有个双链表维护其创建的drizzle_con_st对象,类似地,drizzle_con_st对象中有个双链表维护其创建的drizzle_result_st对象,所有的对象通过这种形式级联管理,并且这些对象中保存着上下文相关的状态,这样的实现方便资源管理,防止资源泄露,但在代理服务器中,请求和结果在不断转发过程中会形成大量的内存拷贝,为了减少转发过程中的内存拷贝,需要把drizzle_result_st显式的从drizzle_con_st中移除,当数据发往客户端完成后再删除,因此增加了drizzle_result_detach()接口,用于从drizzle_con_st对象中移除drizzle_result_st对象 , 涉及文件libdrizzle-2.0/result.h , libdrizzle-2.0/result.cc 

void drizzle_result_detach(drizzle_result_st *result)
{

   if (result->con)
  {
    result->con->result_count--;
     if (result->con->result_list == result)
      result->con->result_list= result->next;
  }

   if (result->prev)
    result->prev->next= result->next;

   if (result->next)
    result->next->prev= result->prev;

  result->con = NULL ;
  result->prev = NULL ;
  result->next = NULL ;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值