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 分布式锁服务在大家的项目中或许用的不多,因为大家都把排他放在数据库那 ...
随机推荐
- maven中jar、war、pom的区别
一.maven的三种packaging方式 pom是maven依赖文件 jar是java普通项目打包 war是java web项目打包 pom:打出来可以作为其他项目的maven依赖,在工程A中添加工 ...
- Bitdefender Total Security 2014 Free 6 Months & 12 month License Key
German Only – Bitdefender Total Security 2014 Free 6 Months Serial License Keyhttp://www.bitdefender ...
- 面试题总结(一)、TCP协议
声明:本文主要探讨当TCP协议出现在面试笔试场合可能会涉及的问题,每一个知识点讨论力求简洁,便于记忆,但讨论深度有限,如要深入研究可点击参考链接,希望对正在找工作的同学有点帮助. 一.TCP协议简介 ...
- javascript 与vbscript 互相调用
在 VBScript 的function 中可以直接编写 javascript 代码 但是只能返回一个字符串给变量 <html><head> <script type=& ...
- 回首C语言关键字(~回首向来萧瑟处~)
开篇废话: 本文意在回顾 C 语言中的关键字,整理文件发现当时做的这些笔记还是蛮用心的,有临摹 前辈的足迹也有自己的理解和体会.时至今日2018已经跨过一半,对不起过去半年,今天 拿这篇关键字开篇,开 ...
- adb命令安装apk
1.将需要安装的apk放在platform-tools下 2.将手机和电脑连接,在cmd中输入 adb devices查看 3.使用adb命令安装apk,在cmd中输入:adb install apk ...
- centos7 中将执行文件python链接为python3后 如何保证 yum 功能不受影响
1. 查看 /usr/bin 中 python 执行文件的 链接情况 2. 设置 python 命令的可执行文件 链接为 python3 3. 此时 , yum 文件中的p ...
- HDU - 4676 :Sum Of Gcd (莫队&区间gcd公式)
Given you a sequence of number a 1, a 2, ..., a n, which is a permutation of 1...n. You need to answ ...
- 屏幕录制专家【Bandicam】
BANDICAM是一款屏幕游戏录制工具. 今天给大家详细介绍下它的下载和破解使用. 安装方法: 一.准备工作 1.官网下载最新版. https://www.bandicam.com/cn/ 2.下载注 ...
- Window 查看端口进程使用
1. 查看所有端口占用 netstat -ano 2. 查看指定端口占用 netstat -ano | findstar "8080" 其中11152 对应为进程号 3. 查看进程 ...