zookeeper 分布式计数器
分布式计数器的思路是:指定一个Zookeeper数据节点作为计数器,多个应用实例在分布式锁的控制下,通过更新该数据节点的内容来实现计数功能。
Curator中封装了实现,例如 DistributedAtomicInteger 和 DistributedAtomicLong。
以下是我写的一个测试用例:
- package com.my.CuratorTest;
- import org.apache.curator.framework.CuratorFramework;
- import org.apache.curator.framework.CuratorFrameworkFactory;
- import org.apache.curator.framework.recipes.atomic.AtomicValue;
- import org.apache.curator.framework.recipes.atomic.DistributedAtomicLong;
- import org.apache.curator.retry.ExponentialBackoffRetry;
- import org.apache.curator.retry.RetryNTimes;
- import java.util.concurrent.CyclicBarrier;
- import java.util.concurrent.ExecutorService;
- import java.util.concurrent.Executors;
- /**
- * Title: 分布式计数器演示<br/>
- * Intention: <br/>
- * <p>
- * Class Name: com.my.CuratorTest.RecipesDisAutomicLong<br/>
- * Create Date: 2017/8/20 22:48 <br/>
- * Project Name: MyTest <br/>
- * Company: All Rights Reserved. <br/>
- * Copyright © 2017 <br/>
- * </p>
- * <p>
- * author: GaoWei <br/>
- * 1st_examiner: <br/>
- * 2nd_examiner: <br/>
- * </p>
- *
- * @version 1.0
- * @since JDK 1.7
- */
- public class RecipesDisAutomicLong {
- static String disAutomicIntPath = "/curator_recipes_distatomicint_path3";
- static CuratorFramework client = CuratorFrameworkFactory.builder()
- .connectString("127.0.0.1:2181")
- .retryPolicy(new ExponentialBackoffRetry(1000, 3)).build();
- static DistributedAtomicLong atomicLong =
- new DistributedAtomicLong(client, disAutomicIntPath, new RetryNTimes(10, 500),
- null);
- public static void main(String[] args) throws Exception{
- client.start();
- Long[] nums = {1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L};
- ExecutorService executor = Executors.newFixedThreadPool(nums.length);
- CyclicBarrier barrier = new CyclicBarrier(nums.length);
- atomicLong.compareAndSet(atomicLong.get().postValue(), new Long(0));
- for (int i=0;i<nums.length;i++) {
- final int k = i;
- executor.execute(new Runnable() {
- @Override
- public void run() {
- try {
- barrier.await();
- System.out.println(Thread.currentThread().getName()+" " + System.nanoTime()+ " , 开始执行");
- AtomicValue<Long> av = atomicLong.add(nums[k]);
- System.out.println("to add value=" + nums[k] + ", Result=" + av.succeeded() + " preValue=" + av.preValue()
- + " postValue=" + av.postValue());
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- });
- }
- executor.shutdown();
- }
- }
运行结果:
pool-3-thread-10 89586635189009 , 开始执行
pool-3-thread-8 89586635508120 , 开始执行
pool-3-thread-9 89586635501453 , 开始执行
pool-3-thread-7 89586635493898 , 开始执行
pool-3-thread-6 89586635480564 , 开始执行
pool-3-thread-5 89586635470342 , 开始执行
pool-3-thread-4 89586635427231 , 开始执行
pool-3-thread-3 89586635410787 , 开始执行
pool-3-thread-2 89586635360564 , 开始执行
pool-3-thread-1 89586635236564 , 开始执行
to add value=10, Result=true preValue=0 postValue=10
to add value=2, Result=true preValue=10 postValue=12
to add value=6, Result=true preValue=12 postValue=18
to add value=1, Result=true preValue=18 postValue=19
to add value=7, Result=true preValue=19 postValue=26
to add value=3, Result=true preValue=26 postValue=29
to add value=4, Result=true preValue=29 postValue=33
to add value=8, Result=true preValue=33 postValue=41
to add value=9, Result=true preValue=41 postValue=50
to add value=5, Result=true preValue=50 postValue=55
如果在DistributedAtomicLong的构造方法参数中,RetryNTimes重试次数不够,比如是3,你会发现并不一定每次加数都会成功。显然这里是用了乐观锁机制,它并不保证操作一定成功(它在重试这么多次中都没有成功获得锁,导致操作没有执行),所以我们有必要通过调用 av.succeeded() 来查看此次加数是否成功。
下面是RetryNTimes为3时的某一次运行结果:
pool-3-thread-1 89922027531135 , 开始执行
pool-3-thread-5 89922027681802 , 开始执行
pool-3-thread-8 89922027737357 , 开始执行
pool-3-thread-4 89922027673802 , 开始执行
pool-3-thread-9 89922028120024 , 开始执行
pool-3-thread-10 89922027531580 , 开始执行
pool-3-thread-2 89922027616024 , 开始执行
pool-3-thread-3 89922027606246 , 开始执行
pool-3-thread-7 89922027722691 , 开始执行
pool-3-thread-6 89922027699580 , 开始执行
to add value=9, Result=true preValue=0 postValue=9
to add value=10, Result=true preValue=9 postValue=19
to add value=4, Result=true preValue=19 postValue=23
to add value=7, Result=true preValue=23 postValue=30
to add value=3, Result=true preValue=30 postValue=33
to add value=2, Result=true preValue=33 postValue=35
to add value=5, Result=true preValue=35 postValue=40
to add value=1, Result=false preValue=35 postValue=0
to add value=6, Result=false preValue=35 postValue=0
to add value=8, Result=false preValue=35 postValue=0
参考:
1、从PAXOS到ZOOKEEPER分布式一致性原理与实践
zookeeper 分布式计数器的更多相关文章
- zookeeper之分布式锁以及分布式计数器(通过curator框架实现)
有人可能会问zookeeper我知道,但是curator是什么呢? 其实curator是apachede针对zookeeper开发的一个api框架是apache的顶级项目 他与zookeeper原生a ...
- ZooKeeper 分布式锁
在Redis分布式锁一文中, 作者介绍了如何使用Redis开发分布式锁. Redis分布式锁具有轻量高吞吐量的特点,但是一致性保证较弱.我们可以使用Zookeeper开发分布式锁,来满足对高一致性的要 ...
- Zookeeper分布式过程协同技术 - 群首选举
Zookeeper分布式过程协同技术 - 群首选举 群首概念 群首为集群中服务器选择出来的一个服务器,并被集群认可.设置群首目的在与对客户端所发起的状态变更请求进行排序,包括:create.setDa ...
- Zookeeper 分布式锁 (图解+秒懂+史上最全)
文章很长,而且持续更新,建议收藏起来,慢慢读! 高并发 发烧友社群:疯狂创客圈(总入口) 奉上以下珍贵的学习资源: 疯狂创客圈 经典图书 : 极致经典 + 社群大片好评 < Java 高并发 三 ...
- Curator Zookeeper分布式锁
Curator Zookeeper分布式锁 pom.xml中添加如下配置 <!-- https://mvnrepository.com/artifact/org.apache.curator/c ...
- Zookeeper分布式集群搭建
实验条件:3台安装linux的机子,配置好Java环境. 步骤1:下载并分别解包到每台机子的/home/iHge2k目录下,附上下载地址:http://mirrors.cnnic.cn/apache/ ...
- ZooKeeper 分布式锁实现
1 场景描述 在分布式应用, 往往存在多个进程提供同一服务. 这些进程有可能在相同的机器上, 也有可能分布在不同的机器上. 如果这些进程共享了一些资源, 可能就需要分布式锁来锁定对这些资源的访问. 2 ...
- ZooKeeper分布式锁浅谈(一)
一.概述 清明节的时候写了一篇分布式锁概述,里面介绍了分布式锁实现的几种方式,其实那时候我一直沉迷于使用redis的悲观锁和乐观锁来实现分布式锁,直到一个血案的引发才让我重新认识了redis分布式锁的 ...
- [转载] zookeeper 分布式锁服务
转载自http://www.cnblogs.com/shanyou/archive/2012/09/22/2697818.html 分布式锁服务在大家的项目中或许用的不多,因为大家都把排他放在数据库那 ...
随机推荐
- web.xml中contextConfigLocation参数的作用
<context-param> <param-name>contextConfigLocation</param-name> <param-value> ...
- bzoj1068
题意: 给你一个未压缩串,要求你把它压缩 问你压缩后最小长度 题解: 区间dp 怎么少就怎么来 代码: #include<bits/stdc++.h> using namespace st ...
- 『转』Emsisoft Anti-Malware 8刷Key教程 - 文字版
先分主机和客机,下载好 EAM8安装包 和 30天重置工具EAM Trial Reset 1.1.exe 1. 主机安装 Emsisoft Anti-Malware 8 并激活30天试用版 如果已 ...
- STL标准库-容器-vector
技术在于交流.沟通,本文为博主原创文章转载请注明出处并保持作品的完整性. 向量容器vector是一个动态数组,内存连续,它是动态分配内存,且每次扩张的原来的二倍. 他的结构如下 一 定义 vector ...
- git 常用命令--抓取分支-为自己记录(二)
二:抓取分支: 多人协作时,大家都会往master分支上推送各自的修改.现在我们可以模拟另外一个同事,可以在另一台电脑上(注意要把SSH key添加到github上)或者同一台电脑上另外一个目录克隆, ...
- Kotlin Reference (十一) Visibility Modifiers
most from reference 类,对象,接口,构造函数,函数,属性及setters具有可见性修饰符(getter总是具有和属性一样的可见性).在kotlin中油4个可视化修饰符:privat ...
- ios系统降级
1.使用PP助手/iTunes备份好文件资料,以防重要信息丢失: 2.设备连接iTunes,按住Shift键之后点击“恢复iPhone”,选择已下载好的iOS8.4.1固件,等待更新完成即可. 注意要 ...
- Opencv中Rect类
转载: Rect_类有些意思,成员变量x.y.width.height,分别为左上角点的坐标和矩形的宽和高.常用的成员函数有Size()返回值为一个Size,area()返回矩形的面积,contain ...
- VMware 11 安装 Mac OS X10.10
一.下载好以下软件--->http://pan.baidu.com/s/1qWDkTbe 1,VMware 11 2,unlocker203(装好VMware11后需要安装补丁unlocker才 ...
- java局部变量和临时变量
局部变量:temp=1, 临时变量:return a+b 临时变量会有一点的性能优势 局部变量会比成员变量和静态成员变量有优势,改进的方法是吧成员变量和静态成员变量赋值在局部变量:https://bl ...