百度空间 | 百度首页 
               
 
查看文章
 
memcachedb单线程访问bdb的阻塞问题
2008-02-24 23:38
  • 本文讨论的是sina的memcachedb,不是memcached
  • Memcachedb基于libevent实现,也就是说单线程的。理论上讲所有的IO操作都需要通过信号来处理,先注册信号,系统通知可以读写了再调用具体的读写命令。这主要针对网络,严格意义上来说本地的读写也要这样处理。否则本地阻塞会引起整个服务器阻塞。
  • Memcachedb基于实用的原因,读写数据库未作信号处理,但问题也不大:
    • 使用嵌入的berkeley db,仅本程序访问。
    • 直接调用berkeley db的API操作数据库,相当于直接操作文件的性能。
    • 由于不是标准的IO调用,而是berkeley db API,要通过信号来控制也很复杂。
    • 但如果启用berkeley db的replication特性,数据库阻塞的机会可能会增大。

为什么考虑这个呢,因为今天考虑在libevent里面调用mysql,情况就复杂一点。

  • 调用的MySQL client C API, 通过socket同MySQL沟通,网络可能会阻塞。
  • MySQL同时服务多个应用,可能有时候会繁忙响应很慢。
  • MySQL C API无法设置event

所以感觉不能用memcachedb的方法。目前想到的办法就是把所有的MySQL操作通过异步去完成,比如把操作放入队列,用另外一个程序或线程去处理。但是这只适合插入和修改,如果是查询需要即时等待返回结果就不适合,很麻烦。

本文分类:高性能服务器

附:memcachedb的存取数据库代码

void complete_nread(conn * c) {
item *it = &(c->item);
int comm = c->item_comm;
int ret;
stats.set_cmds++;
while (1) {
if (strncmp(ITEM_data(it) + it->nbytes - 2, "\r\n", 2) != 0) {
out_string(c, "CLIENT_ERROR bad data chunk");
break;
}
cleanup_dbt();
if (comm == NREAD_ADD || comm == NREAD_REPLACE) {
dbkey.data = ITEM_key(it);
dbkey.size = strlen(ITEM_key(it));
if ((ret = dbp->get(dbp, NULL, &dbkey, &dbdata, 0)) == 0) {
if (comm == NREAD_ADD) {
out_string(c, "NOT_STORED");
break;
}
} else if (comm == NREAD_REPLACE) {
out_string(c, "NOT_STORED");
break;
}
}
cleanup_dbt();
dbkey.data = ITEM_key(it);
dbkey.size = strlen(ITEM_key(it));
dbdata.data = ITEM_data(it);
dbdata.size = it->nbytes;
// 这里直接调用数据库存取
if ((ret = dbp->put(dbp, NULL, &dbkey, &dbdata, 0)) == 0) {
/* some future code? */
out_string(c, "STORED");
} else {
out_string(c, "NOT_STORED");
}
break;
}
return;
}

类别:高性能服务器 | 添加到搜藏 | 浏览() | 评论 (5)
 
最近读者:
 
网友评论:
1
2008-02-27 16:16 | 回复
我觉得队列的Cache也是有限的,解决的是数据库性能波动的问题。发生阻塞的时候只好返回给Caller异常,要求重发
 
2
2008-02-27 20:15 | 回复
呵呵,我已经想到解决方法。select时候先在队列添加请求,然后先不返回client内容,主程序进行其他工作。db进程查询结果之后放入内存,然后通知主程序。主程序返回结果给client。仍然是单线程。
 
3
2008-03-02 22:41 | 回复
哥们,认识一下
 
4
2008-03-03 02:12 | 回复
这个博主技术不错啊,而且很大方,都写出来,不像有些牛人,会的东西都不告诉别人
 
5
2008-04-22 11:09 | 回复
可以看看基于 libevent 的 半同步半异步 线程池框架。 http://iunknown.javaeye.com/blog/59804
 
发表评论:
姓 名:
网址或邮箱: (选填)
内 容:
验证码: 请点击后输入四位验证码,字母不区分大小写
      

     

©2009 Baidu