分布式异步消息框架构建笔记5——如何避开并行编程中的数据共享陷阱
来源:互联网 发布:店铺宝贝优化 编辑:程序博客网 时间:2024/05/17 11:34
任何多线程/并行/分布式都会面临一个问题,“数据状态共享"。
有经验的开发者会说,要想正确有效的避开避开状态共享,那么就应该别用任何状态共享。
虽然不得不说,这是一个不错的建议,但是没有状态共享,你需要如何才能知道非本地数据的状态?
也许你会说使用消息,使用消息来处理,那么我们丑陋的回调金字塔应该叠的更高了。
不得不说这是一个解决办法,但是为了保持状态不被修改,那么我们还得在远程申请一个写入锁,防止数据被别的任务所修改。
那么流程就是 申请锁-》请求某个消息状态-》释放锁
假设我们一个简单的交易任务,服务A上的玩家1准备和服务器B上的玩家2准备交易。
玩家A需要付出100个金币,玩家B需要把背包里的一把刀给玩家A。
非分布式简单非常简单
if(玩家A.金币>100 && 玩家B.拥有(刀)){
玩家A.金币-=100;
玩家A.获得(刀);
玩家B.失去(刀);
}
防止逻辑失败,如果有个事务出错后回滚一下,这个逻辑就完美了,简单有效.
那么如果是分布式这就显得比较麻烦了, 试着写一个同步办法,远程调用比较费时间,但是至少能正常工作.
sv1.锁定(玩家A)
sv2.锁定(玩家B)
if(sv1.玩家A.金币>100 && sv2.玩家B.拥有(刀)){
sv1.玩家A.金币-=100;
sv2.玩家A.获得(刀);
sv3.玩家B.失去(刀);
}
sv1.释放(玩家A)
sv2.释放(玩家B)
这个时候应该请出异步来优化这次调用了..
sv1.锁定(玩家A,(){
sv2.锁定(玩家B,(){
if(sv1.玩家A.金币>100 && sv2.玩家B.拥有(刀)){
sv1.玩家A.金币(-100,(){
sv2.玩家A.获得(刀,(){
sv3.玩家B.失去(刀,(){
sv1.释放(玩家A,(){
sv2.释放(玩家B,(){
});
});
);
});
});
}
})
});
我好想确定自己是不是来搞笑的..
如果保持之前设想的逻辑:
1.所有对单个对象执行都是单线程的.(数据访问唯一)
2.当对象不在本地,提交到远程执行,并返回结果.
3.获得结果后,继续在本地执行
交易发起会在玩家A这方发起,我们克隆一个玩家B的镜像,并且标记一个有效时间.
所有的修改都有操作标记.然后在玩家A和玩家B的逻辑都在玩家A线程上执行.
但是,因为我们操作的镜像,并不影响原有数据.
操作完逻辑后,并不算成功,我们需要获得操作完成后玩家A/B与交易之前的差异数据
如何获得参考之前的一篇文章,然后到了我们真正要写入的时候.
玩家A置等待锁(也就是暂时不执行别的请求),远程请求玩家B的写入.
完成后,玩家A写入. 释放等待锁.
写入瞬间有一个防误操作的锁,其他时间都不影响其他任何操作.
如果远程服务器在交易发起的瞬间被,修改,那么写入失败,只要丢弃双方差异数据并释放锁即可.
从以上逻辑我们可以看出
1.数据访问唯一让我们无需担心执行过程中被修改,也就是我们可以推算出任何非多步的操作都是成功的.(方法中不包含远程方法,必然会执行成功)
2.线程切换机制,保证我们在编写代码时运行位置的正确性,因为你无需判断是否需要远程执行,仅仅都通过代理调用即可.
3.除非事务,保证双方的操作必须成功,否则,无需任何锁,也就是安全的跨服操作.
- 分布式异步消息框架构建笔记5——如何避开并行编程中的数据共享陷阱
- 分布式异步消息框架构建笔记 1—— 设想
- 分布式异步消息框架构建笔记4——分布式消息路由
- 分布式异步消息框架构建笔记3 —— 自动消息路由
- 分布式异步消息框架构建笔记2——yield机制及单线程多任务系统
- 如何避开MongoDB使用中的一些陷阱
- 如何避开 Go 中的各种陷阱
- 分布式机器学习系统笔记(一)——模型并行,数据并行,参数平均,ASGD
- 分布式服务框架 Zookeeper — 管理分布式环境中的数据
- 分布式服务框架 Zookeeper — 管理分布式环境中的数据
- 分布式服务框架 Zookeeper — 管理分布式环境中的数据
- 分布式服务框架 Zookeeper — 管理分布式环境中的数据
- 并行开发5——异步编程模型
- 分布式异步编程框架 Koper
- 《hadoop实战》笔记1—分布式编程框架
- tensorflow 分布式 数据并行 异步训练 between-graph 实例
- .NET并行编程——并行循环中的“中断”
- 分布式服务框架学习笔记5 消息队列
- 微信定时长服务,处理思路
- LogCat
- undo表空间的作用、收缩及切换
- Codeforces Round 281 div2 C Vasya and Basketball
- Mongodb与Mysql的查询脚本操作对比
- 分布式异步消息框架构建笔记5——如何避开并行编程中的数据共享陷阱
- acmicpc.sdnu.edu.cn 1012区间合并
- Android ViewHolder通用写法(简洁、减少代码量)
- 关于前端开发谈谈单元测试
- One Edit Distance
- 在服务器端判断request来自Ajax请求(异步)还是传统请求(同步)
- javascript考试系统倒计时
- 主页面调用iframe里面匿名Javascript函数的问题
- 心里装着什么,就会得到什么!