再则memcache的multiget hole(无底洞)

< 再说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“详解:     火丁在2012年描述了 multiget  无底洞:
『让我们来模拟一下案发经过,看看到底发生了什么:

我们使用 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 nod
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值