`
enjiex
  • 浏览: 67217 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Memcached历险记

阅读更多
点击查看英文原文

两个勇敢的冒险者,程序员和系统管理员,开始了一段旅程。他们一起搭建一个基于web server和database的网站。网上的用户与web server交互,并请求获得他们所需要的页面。web server请求databases以获得数据来构建页面。在这个项目中,程序员进行编码,而系统管理员负责web server 和database的安装与部署。

某天,管理员发现他们的数据库系统快要跨掉了,几乎也不能负载得起web server的请求了。程序员咨询起管理员该怎么办,这时管理员想起了一个叫memcached的项目,它曾真真切切的使用在livejournal项目中,并取得了很好的效果。程序员高兴的说:“非常好,咱们也试一下吧”。

勇敢的管理员分析下当前的web server,发现已经有了6个web servers。他决定使用其中的三个用为memcached server,并为每个web server添加一个G的内存空间,然后把每个memcached的缓存空间限定为1G,并启动了memcached server。现在,他已经拥有了三个memcached 实例,并且每个都能负载1G的数据容量。这时程序员和管理员开始回过头来并分析如何使用这神奇的memcached。

他们发现memcached还不能正确的工作,因为memcached server里并未缓存任何内容,而当前databases的负载已经更高了。勇敢的程序员拿来了pecl/memcache客户端使用手册,并自信地说“不要担心,我知道怎么办了”。然后取到了三个memcache server的IP地址及端口,并添加到一个php的数组中:如下
$MEMCACHE_SERVERS = array(
    "10.1.1.1", //web1
    "10.1.1.2", //web2
    "10.1.1.3", //web3
);

然后他定义了个Memcache实例,并把上面得到的server加入其中:
$memcache = new Memcache();
foreach($MEMCACHE_SERVERS as $server){
    $memcache->addServer ( $server );
}

完成这些工作后,程序员陷入了深思,突然眼睛一亮:“我知道了,在网站的首页上会运行这个SQL'SELECT * FROM hugetable WHERE timestamp > lastweek ORDER BY timestamp ASC LIMIT 5000',但这个语句会耗时5秒钟,我可以把这个查询的结果放到memcached里。”他改变了原有的SELECT语句,并开始使用了$memcache对象,在程序中会判断这个查询是否已经缓存到了memcache server里,如果还没有就到databases里查询并把结果放到memcache里,如下:
$huge_data_for_frong_page = $memcache->get("huge_data_for_frong_page");
if($huge_data_for_frong_page === false){
    $huge_data_for_frong_page = array();
    $sql = "SELECT * FROM hugetable WHERE timestamp > lastweek ORDER BY timestamp ASC LIMIT 50000";
    $res = mysql_query($sql, $mysql_connection);
    while($rec = mysql_fetch_assoc($res)){
        $huge_data_for_frong_page[] = $rec;
    }
    // cache for 10 minutes
    $memcache->set("huge_data_for_frong_page", $huge_data_for_frong_page, 600);
}

程序员提交了代码,”汗,数据库负载降到了原来的一半。“管理员惊喜的叫喊着。现在网站速度又变得相当快了。”那么,“管理员猜测,”到底发生了什么呢“。”我把数据放到了memcached server里。通过cacti,我看到数据只发送到了一台memchace server上,可我部署了三台memcached server啊“,管理员想着。管理员快速查看ascii protocol并telnet到memcached server的11211端口。

”嗨,'get huge_data_for_front_page'在这吗?“,管理员问道。
这一台memcached server没有回答,第二台也没有回答。即便如此,第三台memchaced server把一堆数据显示在了当前的telnet会话终端上。”这是要查询的数据,“管理员自言自语道,”原来只有一个memcached server会缓存程序的数据“。

管理员感到很困惑,他就到邮件列表上去寻找答案,而他们却一致的回答道:这是一个分部式缓存,正如它所做的,数据只会缓存到一台机器上。但是,这对于应用来说又意味着什么呢,管理员依然很茫然。经过挣扎之后,他决定请程序员再cache一些数据到memcached server里。”让我们看到memcached到底做了些什么,虽然我们是些奇怪的想法,但我们确信能找到答案。“管理员说着。

”呃,这还有一个查询,虽然不太慢,但每秒会有100次请求。也许缓存起来也应该有用的“,程序员说。说着,他说按着上次的做法,把这个查询操作也与memcached结合起来进行了重构。然后他们发现,系统负载又降了不少。

有了上面的效果,程序员对越来越多的查询做了重构。多神奇的东西啊,程序员说,现在DB负载已经降到很低了。

现在,管理员又telnet到这三台memcached server上,此时些三台server都在运行,并且对于每台机器的查询请求,都有结果返回。这下管理员终于放心了,所有的memcached server都在正常的使用。

但是他不解的是程序中的数据是如何映射到memcached server上的呢,也就是说为何有些查询在某个server上没有结果,而在另外一个server有返回呢。”难道就不能把每个key映射到所有的memcached上吗?“管理员想着。
”等一下,我给每个memcached分配了1G内存,也就是说现在我总共可以缓存3G的数据了,而不是1G。呃,原来如此“管理员松了口气。
”但是,web server还在运行,可突然某个memcached server死机了会怎么样?“为了确信会发现什么,管理员把其中一台memcached server给停掉了。这时他再观察DB的负载,稍有上升,但并没有表现出负载压力,同时另外两台memcached server还在运行并有数据传输。”不会太坏,只是一部分的缓存丢失了,另外的memcached server还会有效,不会一下子把所有的请求扔给database。“,管理员想着。终于找着答案了,管理员把网停掉的memcached server重新启动起来了。

经过上面的历险,程序员和管理员继续他们的网站开发,并不停的在应用中使用缓存,而db也不再有压力了。从而每个人都过上了开心的生活。
分享到:
评论
1 楼 路人昭 2011-06-26  
英杰翻译的好东东~不错的java故事~

相关推荐

Global site tag (gtag.js) - Google Analytics