`
zhengyun_ustc
  • 浏览: 80415 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

再说memcache的multiget hole(无底洞)

阅读更多
关键词:multiget hole,memcache
适用于:java,php

基础知识背景:
1)multiget 是什么:
    multiget 指的是从 memcache(或其他分布式缓存) 一次性获得多个键值,一般由 memcached client 自行实现。如 PHP-memcache-client 提供了 Memcached::getMulti 函数。调用示范如下:
<?php
$items = array(
    'key1' => 'value1',
    'key2' => 'value2',
    'key3' => 'value3'
);
$m->setMulti($items);
$result = $m->getMulti(array('key1', 'key3', 'badkey'), $cas);
var_dump($result, $cas);
?>
2)”multiget hole“详解:
『让我们来模拟一下案发经过,看看到底发生了什么:

我们使用 Multiget 一次性获取100个键对应的数据。

系统最初只有一台 Memcached 服务器,随着访问量的增加,系统负载捉襟见肘,于是我们又增加了一台 Memcached 服务器,数据散列到两台服务器上。

开始那100个键在两台服务器上各有50个。

问题就在这里:原本只要访问一台服务器就能获取的数据,现在要访问两台服务器才能获取;服务器加的越多,需要访问的服务器就越多,所以问题不会改善,甚至还会恶化。

不过,作为被告方,Memcached官方开发人员对此进行了辩护

请求多台服务器并不是问题的症结,真正的原因在于客户端在请求多台服务器时是并行的还是串行的!问题是很多客户端,包括Libmemcached在内,在处理Multiget多服务器请求时,使用的是串行的方式!也就是说,先请求一台服务器,然后等待响应结果,接着请求另一台,结果导致客户端操作时间累加,请求堆积,性能下降

如何解决这个棘手的问题呢?只要保证 Multiget 中的键只出现在一台服务器上即可!(注:事实上这可不容易做到。)

3)以前郑昀在文章里说过,spymemcached 某版本又是如何实现 Multiget(即getBulk)的

  1. 给一组 key,[1,2,3,4,5]。
  2. 先 算一下这些key都落在哪些节点上(通过 KetamaNodeLocator 的 public Iterator<MemcachedNode> getSequence(String k)。Now that we know how many servers it breaks down into.);
  3. 此时,得到一个map:<Node1,[1,3]>;<Node2,[2,4]>;<Node3,[5]>;
  4. 遍历这个map,从每一个 mc node 读出对应的 keys(即单节点的 multiget 操作);一个Node一个Node串行的;
  5. 拼成一个大map<key,value>返回。
这样就是一个 node 复一个 node 串行检索的,虽然做了优化,但是如果涉及的 mc nodes 数量多,线程势必长时间阻塞在等待网络资源返回上。
(注:
spymemcached 后来的版本不再按 node 串行轮询,而是并行:第一步,将本次操作构造成一个针对每个 node 的 Operation 对象,加入连接对象中;第二步,在连接对象中,将所有的 node 操作放入 addedQueue 队列,然后触发 Selector 方式异步非阻塞的执行。)

现象:
    某中心每天很多个读取 memcache 键值超时,报错如下:
Caused by: java.util.concurrent.ExecutionException: net.spy.memcached.internal.CheckedOperationTimeoutException: Operation timed out. - failing node: mcN.domain.name

         at net.spy.memcached.internal.OperationFuture.get(OperationFuture.java:172)

         at net.spy.memcached.internal.GetFuture.get(GetFuture.java:62)

分析:
    在 memcache 集群节点较多情况下,
    特别是在一次性获取成百上千键值的极端场景面前,
    服务端轻则请求超时,重则宕机
 
    无论是先计算 keys 都散列到哪些 mc nodes 上了,还是直接轮询 memcached::get ,或者说并行提交给各个 mc nodes 然后异步等待,
    假设每个 mc get 耗时2~3毫秒,一次性取 2000 个keys,都将阻塞线程长达2~6秒之久,这是身为服务所不能容忍的。
 
    所以,必须约定,适度使用批量获取键值功能,100个键值就到顶了,别因小失大。
    
    当然,也有业务场景绕不开 multiget,那么,一是按照 facebook 所说,此时需要的是更多的 CPU,把缓存数据复制一份到另一个 memcache 集群上,一个集群负责读一半的 keys;二是按照火丁所说,最好保证批量查的这批键值都在同一个 mc node 上。
 

参考资源:
1)火丁,2012,memcache 二三事儿

赠图几枚:
死锁分析
 
http://ww1.sinaimg.cn/bmiddle/62532502jw1e8837n50faj20dc0dcjsp.jpg
分享到:
评论

相关推荐

    memcache-3.0.8.tgz

    php的memcache扩展,linux下的,php的memcache扩展分为两种,一种是memcache,一种是基于libmemcached的memcached,这个是memcache版本的beta版本

    memcache图形监控工具phpmemcache

    memcache图形监控工具phpmemcache,尽是一个PHP文件就可以实现对memcache的监控。 使用方法:本地测试监控机安装Apache或者下载XAMPP(Apache+MySQL+PHP+PERL),安装后把memcachephp.zip中的memcache.php文件放到...

    php_memcache 服务扩展

    memcache win8 x64 php5.4.7 测试通过(开发套件 xampp 1.8.1) 配置如下: 1、开启memcached 服务,注意路径 memcached.exe -d install(安装) memcached.exe -d start(自动启动...var_dump($memcache-&gt;get("key"));

    memcache1.2.1 for windows

    windows下memcache安装包 附带php扩展包

    memcache安装包,memcache

    memcache是一套分布式的高速缓存系统,由LiveJournal的Brad Fitzpatrick开发,但目前被许多网站使用以提升网站的访问速度,尤其对于一些大型的、需要频繁访问数据库的网站访问。

    最新windows版php_memcache.dll和memcache.exe

    最新windows的memcache模块下载 这个模块是平和php5.3的,在我的windowsxp php5.3.5上安装成功 里面有两个php库,一个php_memcache.dll.vc6 和一个php_memcache.dll.vc9 另外一个windows的memcache.exe文件,都是网上...

    Memcache完全剖析 最实用的Memcache文档

    Memcache就不用多介绍了,做开发的人都知道。 但要用得好,却并不是那么容易的事。 如果用得不好,反而得不偿失。 这篇文档短小精悍,囊括了使用过程中需要要注意的方方面面。值得一读。

    MemCache开发说明文档

    Memcache是一个高性能的分布式的内存对象缓存系统,通过在内存里维护一个统一的巨大的hash表,它能够用来存储各种格式的数据,包括图像、视频、文件以及数据库检索的结果等。简单的说就是将数据调用到内存中,然后从...

    C语言memcache代码文档

    C语言memcache代码文档C语言memcache代码文档C语言memcache代码文档C语言memcache代码文档C语言memcache代码文档C语言memcache代码文档C语言memcache代码文档

    delphi memcache MemCache.0.2.0.zip

    MemCache.0.2.0.zip Memcached Client for Delphi 客户端调用类 MemCache.0.2.0.zip Show all LinksExternal links Memcached Project This project is a delphi unit which implements a thread safe client for ...

    Memcache win32

    windows memcache 安装服务,php_memcache.dll所有版本扩展dll 安装说明 在命令行下安装Memcache,输入 ‘c:/memcached/memcached.exe -d install’。 3.启动Memcache,再输入: ‘c:/memcached/memcached.exe -d ...

    memcache.dll(5.2/5.3/5.4/5.5)

    很多个 memcache.dll 涵盖PHP 5.2 -5.5 。我找到一个能用的,现在共享给大家。 配置如下: 1、开启memcached 服务,注意路径 memcached.exe -d install(安装,cmd 需要已管理员...var_dump($memcache-&gt;get("key"));

    memcache for linux

    linux平台使用的memcache压缩包,解压缩之后运行make && make install安装, 然后/usr/local/memcache/bin/memcache -d -m 1024 -u root -p 11211 -c 1024命令运行memcache

    memcache

    将信息保持memcache中

    PHP5.5/5.6的 32&63 VC11 Memcache扩展php_memcache.dll

    PHP 添加 Memcache 扩展 : 下载包中包括如下: php_memcache-3.0.8-5.5-nts-vc11-x64.zip php_memcache-3.0.8-5.5-nts-vc11-x86.zip php_memcache-3.0.8-5.5-ts-vc11-x64.zip ...

    Memcache win版 服务器和.net驱动

    win版的memcache,包括.net的驱动

    PHP7.x 8.0 memcache dll php_memcache.dll

    php_memcache.dll

    memcache监控工具

    memcache 监控工具,可以实现实时对内存中的memcache进行监控 获取值等等

    memcache的配置及使用——memcache及其客户端telnet

    memcache的配置及使用——memcache及其客户端telnet

    memcache也spring,hibernate的配置

    memcache的客户端,用maven构建,里有用hibernate-memcached与hibernate,spring3.0进行配置,也有与spring3.0单独配置。

Global site tag (gtag.js) - Google Analytics