数据类型

一共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方法,防止内存泄露等问题

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

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

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

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

cluster model:

public void put(K k, V v, Handler<AsyncResult<Void>> completionHandler) {
put(k, v, Optional.empty(), completionHandler);
} public void put(K k, V v, long timeout, Handler<AsyncResult<Void>> completionHandler) {
put(k, v, Optional.of(timeout), completionHandler);
} /**
* 添加数据 key/value
*/
private void put(K k, V v, Optional<Long> timeoutOptional, Handler<AsyncResult<Void>> completionHandler) {
assertKeyAndValueAreNotNull(k, v)//数据不为null
.compose(aVoid -> checkExists(k))//检查key是否存在
.compose(checkResult -> checkResult ? setData(k, v):create(k, v))//存在就赋值,不存在就创建
.compose(aVoid -> {
//keyPath 方法 k转化为字节流再 Base64 编码
JsonObject body = new JsonObject().put(TTL_KEY_BODY_KEY_PATH, keyPath(k)); if (timeoutOptional.isPresent()) {//数据是否有生存时效
asyncMapTTLMonitor.addAsyncMapWithPath(keyPath(k), this);
body.put(TTL_KEY_BODY_TIMEOUT, timeoutOptional.get());
} else body.put(TTL_KEY_IS_CANCEL, true); //publish 所有node 消息
vertx.eventBus().publish(TTL_KEY_HANDLER_ADDRESS, body);
    
    
Future<Void> future = Future.future();
future.complete();
return future;
})
.setHandler(completionHandler);/**处理完成回调*/
} /**
* 先查询再删除
*/
public void remove(K k, Handler<AsyncResult<V>> asyncResultHandler) {
assertKeyIsNotNull(k).compose(aVoid -> {
Future<V> future = Future.future();
get(k, future.completer()); //获取数据
return future;
}).compose(value -> {
Future<V> future = Future.future();
if (value != null) {
return delete(k, value); //删除
} else {
future.complete();
}
return future;
}).setHandler(asyncResultHandler);/**处理完成回调*/
} /**
 * 获取data
 */
public void get(K k, Handler<AsyncResult<V>> asyncResultHandler) {
assertKeyIsNotNull(k) //检查k不为null
.compose(aVoid -> checkExists(k)) //检查是否存在
.compose(checkResult -> {
Future<V> future = Future.future();
if (checkResult) {
 //获取data
ChildData childData = curatorCache.getCurrentData(keyPath(k));
if (childData != null && childData.getData() != null) {
try {
V value = asObject(childData.getData());//反序列化
future.complete(value);
} catch (Exception e) {
future.fail(e);
}
} else {
future.complete();
}
} else {
//ignore
future.complete();
}
return future;
})
.setHandler(asyncResultHandler);/**处理完成回调*/
}

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

/**
* 获取锁
*/
public void getLock(String name, Handler<AsyncResult<Lock>> resultHandler) {
Objects.requireNonNull(name, "name");
Objects.requireNonNull(resultHandler, "resultHandler");
//默认超时 10s
getLockWithTimeout(name, DEFAULT_LOCK_TIMEOUT, resultHandler);
} public void getLockWithTimeout(String name, long timeout, Handler<AsyncResult<Lock>> resultHandler) {
Objects.requireNonNull(name, "name");
Objects.requireNonNull(resultHandler, "resultHandler");
Arguments.require(timeout >= , "timeout must be >= 0");
if (clusterManager == null) {//是否是集群模式
getLocalLock(name, timeout, resultHandler);
} else {
clusterManager.getLockWithTimeout(name, timeout, resultHandler);
}
}

local model:

/**
* 释放lock
*/
public synchronized void release() {
LockWaiter waiter = pollWaiters();
if (waiter != null) {
waiter.acquire(this);//queue中的下一个 owner getLock
} else {
owned = false;
}
} /**
* Queue poll
*/
private LockWaiter pollWaiters() {
//使用while用途:getlock超时情况
while (true) {
LockWaiter waiter = waiters.poll();
if (waiter == null) {
return null;
} else if (!waiter.timedOut) {
return waiter;
}
}
} /**
* 获取锁
* 采用状态来判断,存在并发问题所以采用 synchronized
*/
public void doAcquire(Context context, long timeout, Handler<AsyncResult<Lock>> resultHandler) {
synchronized (this) {
if (!owned) {
// 获取得到 lock
owned = true;
lockAcquired(context, resultHandler);
} else {
//添加到wait Queue 中,并添加延时任务getLockTimeOut
waiters.add(new LockWaiter(this, context, timeout, resultHandler));
}
}
}

cluster model:

/**
* 利用ZK curator客户端自带实现的 DistributedLock
*/
public void getLockWithTimeout(String name, long timeout, Handler<AsyncResult<Lock>> resultHandler) {
ContextImpl context = (ContextImpl) vertx.getOrCreateContext();//获取context
// 在 internalBlocking Pool 执行有序阻塞任务,利用Queque保证有序(FIFO)
context.executeBlocking(() -> {
ZKLock lock = locks.get(name);
if (lock == null) {
//初始不可重入的互斥锁
InterProcessSemaphoreMutex mutexLock = new InterProcessSemaphoreMutex(curator, ZK_PATH_LOCKS + name);
lock = new ZKLock(mutexLock);
}
try {
 //获取锁直到 timeout
if (lock.getLock().acquire(timeout, TimeUnit.MILLISECONDS)) {
locks.putIfAbsent(name, lock);
return lock;
} else {
throw new VertxException("Timed out waiting to get lock " + name);
}
} catch (Exception e) {
throw new VertxException("get lock exception", e);
}
}, resultHandler);
} public void release() {
// 使用 worker Pool 释放锁
vertx.executeBlocking(future -> {
try {
lock.release();
} catch (Exception e) {
log.error(e);
}
future.complete();
}, false, null);
}

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

local model: counters 采用 AtomicLong

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

cluster model:

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

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. 深度学习结合SLAM研究总结

    博客转载自:https://blog.csdn.net/u010821666/article/details/78793225 原文标题:深度学习结合SLAM的研究思路/成果整理之 1. 深度学习跟S ...

  2. postgresql 基本使用及常见问题

    基本使用参考 https://www.yiibai.com/postgresql/postgresql-insert.html 关于编码问题: 这是一个很复杂,但弄懂之后还是很迷的问题. postgr ...

  3. Java代码的编译与反编译那些事儿

    原文:Java代码的编译与反编译那些事儿 编程语言 在介绍编译和反编译之前,我们先来简单介绍下编程语言(Programming Language).编程语言(Programming Language) ...

  4. 【CF932E】Perpetual Subtraction(NTT,线性代数)

    [CF932E]Perpetual Subtraction(NTT,线性代数) 题面 洛谷 CF 题解 设\(f_{i,j}\)表示\(i\)轮之后这个数恰好为\(j\)的概率. 得到转移:\(\di ...

  5. PLSQL Developer中文乱码问题

    前言 使用PLSQL工具进行连接远程oracle时,中文乱码 解决过程 1 查看服务器端编码 select userenv('language') from dual; 2 查看客户端编码 执行语句 ...

  6. spring boot集成FastDFS

    官方文档:https://github.com/happyfish100/fastdfs-client-java 一.首先,maven工程添加依赖 <!--fastdfs--> <d ...

  7. DirectX11 With Windows SDK--27 计算着色器:双调排序

    前言 上一章我们用一个比较简单的例子来尝试使用计算着色器,但是在看这一章内容之前,你还需要了解下面的内容: 章节 26 计算着色器:入门 深入理解与使用缓冲区资源(结构化缓冲区/有类型缓冲区) Vis ...

  8. 深入浅出mybatis之缓存机制

    目录 前言 准备工作 MyBatis默认缓存设置 缓存实现原理分析 参数localCacheScope控制的缓存策略 参数cacheEnabled控制的缓存策略 总结 前言 提到缓存,我们都会不约而同 ...

  9. webpack打包理解

    webpack打包理解(将所有依赖文件打包到一个文件中) 由于前端代码变得越来越多,越来越复杂, 纯粹脚本化的代码书写方式已经不能满足工程化得需求. 前端模块被抽象出来, 不仅仅包括js模块, 其它如 ...

  10. Swift 4 关于Darwin这个Module

    大家在做app或者framework的时候经常会用到生成随机数的方法arc4random系列,或者取绝对值abs()等.所以我有一次好奇的想看看在Developer Document里 是怎么描述这些 ...