分布式Map中实现引用计数-阿里云开发者社区

开发者社区> 雪地脚印> 正文

分布式Map中实现引用计数

简介:
+关注继续查看

前言

在《ReferenceCountSet无锁实现》中,详细介绍了如何在一个进程中实现一个无锁版本的ReferenceCountSet(或者说是在自己的代码里没有锁),但是最近遇到一个问题,如果是在分布式的环境中呢?如何实现这个引用计数?这个问题如果从头开始写,会是一个比较复杂的问题,在实际中,我们可以使用ZooKeeper设置时的version机制来实现,即CAS(Compare-And-Set)。这是一个本人在实际项目中遇到的一个问题,但是会更简单一些,因为在我们的项目中,我们使用GemFire,即已经有一个现成的分布式Map了(在Gemfire中叫做Region),所以问题简化成如果如何使用一个分布式Map实现引用计数?

实现

如果对ConcurrentMap接口比较熟悉的话,这个其实是一个比较简单的问题。在ConcurrentMap中最主要的就是引入几个CAS相关的操作:
public interface ConcurrentMap<K, V> extends Map<K, V> {
    V putIfAbsent(K key, V value);
    boolean remove(Object key, Object value);
    boolean replace(K key, V oldValue, V newValue);
    V replace(K key, V value);
}
在《ReferenceCountSet无锁实现》中我们只需要使用putIfAbsent就可以了,剩下的实现可以交给AtomicInteger提供的CAS来实现,因为它是在同一个进程中,但是如果在分布式的环境中就不能使用这个AtomicInteger,这个时候应该怎么办呢?其实这个时候我们就可以求助于replace方法了。replace方法的注释中这样描述:
    /**
     * Replaces the entry for a key only if currently mapped to a given value.
     * This is equivalent to
     * <pre>
     *   if (map.containsKey(key) &amp;&amp; map.get(key).equals(oldValue)) {
     *       map.put(key, newValue);
     *       return true;
     *   } else return false;</pre>
     * except that the action is performed atomically.
     *
     * 
@param key key with which the specified value is associated
     * 
@param oldValue value expected to be associated with the specified key
     * 
@param newValue value to be associated with the specified key
     * 
@return <tt>true</tt> if the value was replaced
     * 
@throws UnsupportedOperationException if the <tt>put</tt> operation
     *         is not supported by this map
     * 
@throws ClassCastException if the class of a specified key or value
     *         prevents it from being stored in this map
     * 
@throws NullPointerException if a specified key or value is null,
     *         and this map does not permit null keys or values
     * 
@throws IllegalArgumentException if some property of a specified key
     *         or value prevents it from being stored in this map
     
*/
    boolean replace(K key, V oldValue, V newValue);

在ConcurrentMap的value中我们只需要给Integer,然后用replace去不断的尝试,即自己实现一个CAS:
private int incrementRefCount(Object key) {
    do {
        Integer curCount = distributedMap.get(key);
        if (curCount == null) {
            curCount = distributedMap.putIfAbsent(key, new Integer(1));
            if (curCount == null) {
                return 1;
            }
        }
        
        Integer newCount = new Integer(curCount.intValue() + 1);
        if (distributedMap.replace(key, curCount, newCount)) {
            return newCount;
        }
    } while (true);
}

主要逻辑就是这样了,其实比较简单,只是之前没有遇到过这个问题,所以感觉可以记录下来。或许什么时候补充一下ZooKeeper版本的实现。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
阿里云服务器怎么设置密码?怎么停机?怎么重启服务器?
如果在创建实例时没有设置密码,或者密码丢失,您可以在控制台上重新设置实例的登录密码。本文仅描述如何在 ECS 管理控制台上修改实例登录密码。
10089 0
蚂蚁金服分布式事务实践解析 | SOFAChannel#12 直播整理
本文根据 SOFAChannel#12 直播分享整理,主题:蚂蚁金服分布式事务实践解析,也就是分布式事务 Seata 在蚂蚁金服内部的实践。
705 0
蚂蚁金服大规模分布式事务实践和开源详解 | GIAC 实录
详解在分布式架构演进中,蚂蚁金服面对的跨服务、跨数据库的业务数据一致性问题以及应对措施。更有分布式事务 Seata 的 AT、TCC、Saga 和 XA 四种模式分享。ps:文末附分享 PPT 下载地址哟。
1238 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,阿里云优惠总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系.
13892 0
蚂蚁金服分布式链路跟踪组件 SOFATracer 总览 | 剖析
Scalable Open Financial Architecture是蚂蚁金服自主研发的金融级分布式中间件,包含了构建金融级云原生架构所需的各个组件,是在金融场景里锤炼出来的最佳实践。
809 0
Gearman——分布式任务分发框架
工作中我们有时候会遇到比如需要同时发布数据到多个个服务器上,或者同时处理多个任务。可以使用PHP的curl_multi的方式并发处理请求,但是由于网络和数据以及各个服务器等等的一些情况导致这种并发处理的响应时间很慢,因为在并发请求的过程中还包括记录日志,处理数据等逻辑,等待处理结果并返回,所以也不能友好的满足后台操作的体验。
952 0
漫谈分布式计算框架
这是一个计算架构层出不穷的时代,每种架构都是为了解决其面对的领域问题出现的,必然包含对其问题的特殊优化。通用性不是用户解决问题的出发点,而更多的是框架设计者的“一厢情愿”,用户关注的永远是领域问题。从这个意义上讲,面向领域的计算架构应该才是正确的方向。
595 0
Mars——基于张量的统一分布式计算框架
很高兴在这里宣布我们的新项目:Mars,一个基于张量的统一分布式计算框架。我们已经在 Github 开源:https://github.com/mars-project/mars 。 背景 Python Python 是一门相当古老的语言了,如今,在数据科学计算、机器学习、以及深度学习领域,Python 越来越受欢迎。
9535 0
+关注
116
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载