数据类型

一共4种

synchronous shared maps (local)

asynchronous maps (local or cluster-wide)

asynchronous locks (local or cluster-wide)

asynchronous counters (local or cluster-wide)

synchronous shared maps (local)

数据结构: Map<key,Map<key,value>> , LocalMapImpl 类, 注意scope:vertx instances Global Map,  生命周期结束后或Application临界点时调用remove、clean,close方法,防止内存泄露等问题

  1. private final ConcurrentMap<String, LocalMap<?, ?>> maps;
  2. private final String name;
  3. private final ConcurrentMap<K, V> map = new ConcurrentHashMap<>();//储存的数据结构
  4.  
  5. LocalMapImpl(String name, ConcurrentMap<String, LocalMap<?, ?>> maps) {
  6. this.name = name;
  7. this.maps = maps;
  8. }

asynchronous maps (local or cluster-wide) cluster: zookeeper

利用zookeeper作集中式存储,V 采用序列化/反序列化, cluster模式效率不是很高

  1. public <K, V> void getAsyncMap(String name, Handler<AsyncResult<AsyncMap<K, V>>> resultHandler) {
  2. Objects.requireNonNull(name, "name");
  3. Objects.requireNonNull(resultHandler, "resultHandler");
  4. if (clusterManager == null) {//是否启用集群
  5. /**
  6. * local: Map<key,Map<key,Holder<V>>>
  7. * 新增了插入时间单位纳秒,和TTL有效时间防止内存越来越大,连续内存不足导致内存溢出
  8. */
  9. getLocalAsyncMap(name, resultHandler);
  10. } else {
  11.  /**
  12.   * 获取name,不存在创建zk path
  13.   */
  14. clusterManager.<K, V>getAsyncMap(name, ar -> {
  15. if (ar.succeeded()) {
  16. // Wrap it
  17. resultHandler.handle(Future.succeededFuture(new WrappedAsyncMap<K, V>(ar.result())));
  18. } else {
  19. resultHandler.handle(Future.failedFuture(ar.cause()));
  20. }
  21. });
  22. }
  23. }

cluster model:

  1. public void put(K k, V v, Handler<AsyncResult<Void>> completionHandler) {
  2. put(k, v, Optional.empty(), completionHandler);
  3. }
  4.  
  5. public void put(K k, V v, long timeout, Handler<AsyncResult<Void>> completionHandler) {
  6. put(k, v, Optional.of(timeout), completionHandler);
  7. }
  8.  
  9. /**
  10. * 添加数据 key/value
  11. */
  12. private void put(K k, V v, Optional<Long> timeoutOptional, Handler<AsyncResult<Void>> completionHandler) {
  13. assertKeyAndValueAreNotNull(k, v)//数据不为null
  14. .compose(aVoid -> checkExists(k))//检查key是否存在
  15. .compose(checkResult -> checkResult ? setData(k, v):create(k, v))//存在就赋值,不存在就创建
  16. .compose(aVoid -> {
  17. //keyPath 方法 k转化为字节流再 Base64 编码
  18. JsonObject body = new JsonObject().put(TTL_KEY_BODY_KEY_PATH, keyPath(k));
  19.  
  20. if (timeoutOptional.isPresent()) {//数据是否有生存时效
  21. asyncMapTTLMonitor.addAsyncMapWithPath(keyPath(k), this);
  22. body.put(TTL_KEY_BODY_TIMEOUT, timeoutOptional.get());
  23. } else body.put(TTL_KEY_IS_CANCEL, true);
  24.  
  25. //publish 所有node 消息
  26. vertx.eventBus().publish(TTL_KEY_HANDLER_ADDRESS, body);
  27.     
  28.     
  29. Future<Void> future = Future.future();
  30. future.complete();
  31. return future;
  32. })
  33. .setHandler(completionHandler);/**处理完成回调*/
  34. }
  35.  
  36. /**
  37. * 先查询再删除
  38. */
  39. public void remove(K k, Handler<AsyncResult<V>> asyncResultHandler) {
  40. assertKeyIsNotNull(k).compose(aVoid -> {
  41. Future<V> future = Future.future();
  42. get(k, future.completer()); //获取数据
  43. return future;
  44. }).compose(value -> {
  45. Future<V> future = Future.future();
  46. if (value != null) {
  47. return delete(k, value); //删除
  48. } else {
  49. future.complete();
  50. }
  51. return future;
  52. }).setHandler(asyncResultHandler);/**处理完成回调*/
  53. }
  54.  
  55. /**
  56.  * 获取data
  57.  */
  58. public void get(K k, Handler<AsyncResult<V>> asyncResultHandler) {
  59. assertKeyIsNotNull(k) //检查k不为null
  60. .compose(aVoid -> checkExists(k)) //检查是否存在
  61. .compose(checkResult -> {
  62. Future<V> future = Future.future();
  63. if (checkResult) {
  64.  //获取data
  65. ChildData childData = curatorCache.getCurrentData(keyPath(k));
  66. if (childData != null && childData.getData() != null) {
  67. try {
  68. V value = asObject(childData.getData());//反序列化
  69. future.complete(value);
  70. } catch (Exception e) {
  71. future.fail(e);
  72. }
  73. } else {
  74. future.complete();
  75. }
  76. } else {
  77. //ignore
  78. future.complete();
  79. }
  80. return future;
  81. })
  82. .setHandler(asyncResultHandler);/**处理完成回调*/
  83. }

asynchronous locks (local or cluster-wide) cluster: zookeeper

  1. /**
  2. * 获取锁
  3. */
  4. public void getLock(String name, Handler<AsyncResult<Lock>> resultHandler) {
  5. Objects.requireNonNull(name, "name");
  6. Objects.requireNonNull(resultHandler, "resultHandler");
  7. //默认超时 10s
  8. getLockWithTimeout(name, DEFAULT_LOCK_TIMEOUT, resultHandler);
  9. }
  10.  
  11. public void getLockWithTimeout(String name, long timeout, Handler<AsyncResult<Lock>> resultHandler) {
  12. Objects.requireNonNull(name, "name");
  13. Objects.requireNonNull(resultHandler, "resultHandler");
  14. Arguments.require(timeout >= , "timeout must be >= 0");
  15. if (clusterManager == null) {//是否是集群模式
  16. getLocalLock(name, timeout, resultHandler);
  17. } else {
  18. clusterManager.getLockWithTimeout(name, timeout, resultHandler);
  19. }
  20. }

local model:

  1. /**
  2. * 释放lock
  3. */
  4. public synchronized void release() {
  5. LockWaiter waiter = pollWaiters();
  6. if (waiter != null) {
  7. waiter.acquire(this);//queue中的下一个 owner getLock
  8. } else {
  9. owned = false;
  10. }
  11. }
  12.  
  13. /**
  14. * Queue poll
  15. */
  16. private LockWaiter pollWaiters() {
  17. //使用while用途:getlock超时情况
  18. while (true) {
  19. LockWaiter waiter = waiters.poll();
  20. if (waiter == null) {
  21. return null;
  22. } else if (!waiter.timedOut) {
  23. return waiter;
  24. }
  25. }
  26. }
  27.  
  28. /**
  29. * 获取锁
  30. * 采用状态来判断,存在并发问题所以采用 synchronized
  31. */
  32. public void doAcquire(Context context, long timeout, Handler<AsyncResult<Lock>> resultHandler) {
  33. synchronized (this) {
  34. if (!owned) {
  35. // 获取得到 lock
  36. owned = true;
  37. lockAcquired(context, resultHandler);
  38. } else {
  39. //添加到wait Queue 中,并添加延时任务getLockTimeOut
  40. waiters.add(new LockWaiter(this, context, timeout, resultHandler));
  41. }
  42. }
  43. }

cluster model:

  1. /**
  2. * 利用ZK curator客户端自带实现的 DistributedLock
  3. */
  4. public void getLockWithTimeout(String name, long timeout, Handler<AsyncResult<Lock>> resultHandler) {
  5. ContextImpl context = (ContextImpl) vertx.getOrCreateContext();//获取context
  6. // 在 internalBlocking Pool 执行有序阻塞任务,利用Queque保证有序(FIFO)
  7. context.executeBlocking(() -> {
  8. ZKLock lock = locks.get(name);
  9. if (lock == null) {
  10. //初始不可重入的互斥锁
  11. InterProcessSemaphoreMutex mutexLock = new InterProcessSemaphoreMutex(curator, ZK_PATH_LOCKS + name);
  12. lock = new ZKLock(mutexLock);
  13. }
  14. try {
  15.  //获取锁直到 timeout
  16. if (lock.getLock().acquire(timeout, TimeUnit.MILLISECONDS)) {
  17. locks.putIfAbsent(name, lock);
  18. return lock;
  19. } else {
  20. throw new VertxException("Timed out waiting to get lock " + name);
  21. }
  22. } catch (Exception e) {
  23. throw new VertxException("get lock exception", e);
  24. }
  25. }, resultHandler);
  26. }
  27.  
  28. public void release() {
  29. // 使用 worker Pool 释放锁
  30. vertx.executeBlocking(future -> {
  31. try {
  32. lock.release();
  33. } catch (Exception e) {
  34. log.error(e);
  35. }
  36. future.complete();
  37. }, false, null);
  38. }

asynchronous counters (local or cluster-wide) cluster: zookeeper

local model: counters 采用 AtomicLong

  1. private void getLocalCounter(String name, Handler<AsyncResult<Counter>> resultHandler) {
  2.   //获取计数器,AsynchronousCounter类对AtomicLong的封装
  3. Counter counter = localCounters.computeIfAbsent(name, n -> new AsynchronousCounter(vertx));
  4. Context context = vertx.getOrCreateContext();
  5. context.runOnContext(v -> resultHandler.handle(Future.succeededFuture(counter)));
  6. }

cluster model:

  1. /**
  2.  * 使用ZK curator客户端自带实现的 DistributedAtomicLong
  3.  */
  4. public void getCounter(String name, Handler<AsyncResult<Counter>> resultHandler) {
  5. //使用worker Pool执行阻塞任务
  6. vertx.executeBlocking(future -> {
  7. try {
  8. Objects.requireNonNull(name);
  9. future.complete(new ZKCounter(name, retryPolicy));
  10. } catch (Exception e) {
  11. future.fail(new VertxException(e));
  12. }
  13. }, resultHandler);
  14. }

vertx的ShardData共享数据的更多相关文章

  1. iOS: 在iPhone和Apple Watch之间共享数据: App Groups

    我们可以在iPhone和Apple Watch间通过app groups来共享数据.方法如下: 首先要在dev center添加一个新的 app group: 接下来创建一个新的single view ...

  2. 应用间共享数据方法(一)---sharepreferce

    SharedPreferences类,它是一个轻量级的存储类,特别适合用于保存软件配置参数. SharedPreferences保存数据,其背后是用xml文件存放数据,文件存放在/data/data/ ...

  3. controller共享数据

    刚开始使用angularjs,能感受到他的强大,也在学习的途中遇到一些问题 一般我们在angularjs中共享数据使用DI的方法,具体代码如下: <script> angular.modu ...

  4. python 进程间共享数据 (二)

    Python中进程间共享数据,除了基本的queue,pipe和value+array外,还提供了更高层次的封装.使用multiprocessing.Manager可以简单地使用这些高级接口. Mana ...

  5. python 进程间共享数据 (一)

    def worker(num, mystr, arr): num.value *= 2 mystr.value = "ok" for i in range(len(arr)): a ...

  6. Java线程与并发库高级应用-线程范围内共享数据ThreadLocal类

    1.线程范围内共享变量 1.1 前奏: 使用一个Map来实现线程范围内共享变量 public class ThreadScopeShareData { static Map<Thread, In ...

  7. Angularjs调用公共方法与共享数据

    这个问题场景是在使用ionic开发页面的过程中发现,多个页面对应的多个controller如何去调用公共方法,比如给ionic引入了toast插件,如何将这个插件的调用变成公共方法或者设置成工具类,因 ...

  8. 无废话Android之listview入门,自定义的数据适配器、采用layoutInflater打气筒创建一个view对象、常用数据适配器ArrayAdapter、SimpleAdapter、使用ContentProvider(内容提供者)共享数据、短信的备份、插入一条记录到系统短信应用(3)

    1.listview入门,自定义的数据适配器 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/and ...

  9. Nodejs中cluster模块的多进程共享数据问题

    Nodejs中cluster模块的多进程共享数据问题 前述 nodejs在v0.6.x之后增加了一个模块cluster用于实现多进程,利用child_process模块来创建和管理进程,增加程序在多核 ...

随机推荐

  1. 【DeepLearning】深入理解dropout正则化

    本文为转载,作者:Microstrong0305 来源:CSDN 原文:https://blog.csdn.net/program_developer/article/details/80737724 ...

  2. Java 获取当前线程、进程、服务器ip

    /** * 获取当前线程id */ private Long getThreadId() { try { return Thread.currentThread().getId(); } catch ...

  3. Redis读取出错,JSON序列化的问题

    报错 org.springframework.web.util.NestedServletException: Request processing failed; nested exception ...

  4. numba学习教程

    一.对于python的基础介绍 Python是一种高效的动态编程语言,广泛用于科学,工程和数据分析应用程序..影响python普及的因素有很多,包括干净,富有表现力的语法和标准数据结构,全面的“电池包 ...

  5. (数组) leetcode 66. Plus One

    Given a non-empty array of digits representing a non-negative integer, plus one to the integer. The ...

  6. libiconv交叉编译提示arm-none-linux-gnueabi-gcc

    title: libiconv交叉编译提示arm-none-linux-gnueabi-gcc date: 2019/3/6 17:45:48 toc: true --- libiconv交叉编译提示 ...

  7. Haproxy 安装及配置

    Haproxy介绍 HAProxy是一个特别适用于高可用性环境的TCP/HTTP开源的反向代理和负载均衡软件.实现了一种事件驱动,单一进程模型,支持非常大的并发连接,是因为事件驱动模型有更好的资源和时 ...

  8. JDK环境部署

    JDK环境部署 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 说起JDK想必大家并不陌生,作为运维的小伙伴,谁不层接触过Java程序员呢?而且在搭建服务上时也必须得接触他,比如to ...

  9. HBase海量数据存储

    1.简介 HBase是一个基于HDFS的.分布式的.面向列的非关系型数据库. HBase的特点 1.海量数据存储,HBase表中的数据能够容纳上百亿行*上百万列. 2.面向列的存储,数据在表中是按照列 ...

  10. mysql远程连接很慢问题解决

    mysql开启远程访问发现从远程连接每次都在5秒以上,从本机连接很快. 解决方案: [mysqld] 标签下添加一行配置 skip-name-resolve 重启mysqld服务, 问题解决!