2019独角兽企业重金招聘Python工程师标准>>>

redis被大量用在分布式的环境中,自然而然分布式环境下的锁如何解决,立马成为一个问题。例如我们当前的手游项目,服务器端是按业务模块划分服务器的,有应用服,战斗服等,但是这两个vm都有可能同时改变玩家的属性,这如果在同一个vm下面,就很容易加锁,但如果在分布式环境下就没那么容易了,当然利用redis现有的功能也有解决办法,比如redis的脚本。

redis在2.6以后的版本中增加了Lua脚本的功能,可以通过eval命令,直接在RedisServer环境中执行Lua脚本,并且可以在Lua脚本中调用Redis命令。
使用脚本的好处:
1.减少网络开销:可以把一些要批量处理的功能,发在一个脚本里面执行,减少客户端和redis的交互次数
2.原子操作:这主要就是我们在这边主要利用的功能,在分布式环境下保证数据的原子性。
3.复用:客户端发送的脚本会永久的存储在redis中,这就意味着其他客户端可以复用这一脚本而不需要使用代码完成同样的逻辑。

下面先看一段lua脚本:

local food=redis.call('hget',KEYS[1],'food');
food=food+ARGV[1];
redis.call('hset',KEYS[1],'food',food);
local diamond=redis.call('hget',KEYS[1],'diamond');
diamond=diamond+ARGV[2];
redis.call('hset',KEYS[1],'diamond',diamond);

注:redis.call是我们在脚本中调用redis命令,KEYS和ARGV2个数组,分别是键和参数,下标都是从1开始的,不是0。
这段脚本的功能是取出 KEYS指定的玩家food(粮草)和diamond(玉石),然后就行修改,最后保存在redis中,脚本的执行,保证了整个操作的原子性。

下面我们用java代码来看看具体的实现过程

Jedis jedis = new Jedis("192.168.128.128", 6379);
// 1.初始玩家数据到redis中
GamePlayer player = new GamePlayer();
player.setId(1001);
player.setName("ksfzhaohui");
player.setFood(100);
player.setDiamond(100);Map<String, String> beanMap = BeanUtil.warp(player);// 将对象转换成map
String beanKey = getRedisBeanKey(player.getClass(), player.getId());
System.out.println("key:" + beanKey);
jedis.hmset(beanKey, beanMap);// 将玩家数据保存到redis中

首先模拟了一个玩家将玩家信息保存在redis中,这边的Id随便写了一个,正常的情况下都是通过redis的命令incr生成一个id
结果:

String script = "local food=redis.call('hget',KEYS[1],'food');"+ "food=food+ARGV[1];"+ "redis.call('hset',KEYS[1],'food',food);"+ "local diamond=redis.call('hget',KEYS[1],'diamond');"+ "diamond=diamond+ARGV[2];"+ "redis.call('hset',KEYS[1],'diamond',diamond);";
List<String> keys = new ArrayList<String>();
keys.add(beanKey);
List<String> args = new ArrayList<String>();
args.add("100");
args.add("100");
// 3.执行脚本
jedis.eval(script, keys, args);

指定键和参考,执行脚本,结果:

BeanUtil代码:

public class BeanUtil {private static Logger logger = Logger.getLogger(BeanUtil.class);private static final String CLASS = "class";/*** 将指定的对象数据封装成map* * @param bean*            对象数据* @return*/@SuppressWarnings("all")public static Map<String, String> warp(Object bean) {Map<String, String> propertyMap = new HashMap<String, String>();try {PropertyDescriptor[] ps = Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();for (PropertyDescriptor propertyDescriptor : ps) {String propertyName = propertyDescriptor.getName();if (propertyName != null && !propertyName.equals(CLASS)) {Method getter = propertyDescriptor.getReadMethod();if (getter != null) {propertyMap.put(propertyName,String.valueOf(getter.invoke(bean, null)));}}}} catch (Exception e) {logger.error(e);}return propertyMap;}}

当然网上还有一些其他的方法,如: 用SETNX实现分布式锁
可以参考:http://phl.iteye.com/blog/2029944

个人博客:http://codingo.xyz

转载于:https://my.oschina.net/OutOfMemory/blog/366268

Redis脚本实现分布式锁相关推荐

  1. 基于 Redis + Lua 脚本实现分布式锁,确保操作的原子性

    为了保证数据的争用安全,通常要采用锁机制控制. 如果是单应用部署,直接通过synchronized关键字修改方法,就能解决,但是如果是分布式的部署 该方法就不能解决这个问题啦,此时就引出了一个分布式锁 ...

  2. Redlock——Redis集群分布式锁

    欢迎关注方志朋的博客,回复"666"获面试宝典 前言 分布式锁是一种非常有用的技术手段.实现高效的分布式锁有三个属性需要考虑: 安全属性:互斥,不管什么时候,只有一个客户端持有锁 ...

  3. 阿里JAVA面试题剖析:一般实现分布式锁都有哪些方式?使用 Redis 如何设计分布式锁?...

    面试原题 一般实现分布式锁都有哪些方式?使用 redis 如何设计分布式锁?使用 zk 来设计分布式锁可以吗?这两种分布式锁的实现方式哪种效率比较高? 面试官心理分析 其实一般问问题,都是这么问的,先 ...

  4. Redis 集群分布式锁与 API 网关分布式限流

    https://www.infoq.cn/article/FoQGIk*BzdQWJJ0tKqrJ Redis 集群的历史 Redis 在 3.0 前一般有两种集群方案,一是 proxy(Twempr ...

  5. Redis进阶- Redisson分布式锁实现原理及源码解析

    文章目录 Pre 用法 Redisson分布式锁实现原理 Redisson分布式锁源码分析 redisson.getLock(lockKey) 的逻辑 redissonLock.lock()的逻辑 r ...

  6. Redis进阶-细说分布式锁

    文章目录 Pre 引 分布式锁演进 V1 分布式锁演进 V2 分布式锁演进 V3 分布式锁演进 V4 分布式锁演进 V5 终极版-分布式锁演进(Redisson ) V6 Code Redisson分 ...

  7. redis系列:分布式锁

    1 介绍 这篇博文讲介绍如何一步步构建一个基于Redis的分布式锁.会从最原始的版本开始,然后根据问题进行调整,最后完成一个较为合理的分布式锁. 本篇文章会将分布式锁的实现分为两部分,一个是单机环境, ...

  8. 小王,在 Java 中如何利用 redis 实现一个分布式锁服务呢???

    作者:杨高超 juejin.im/post/5a4984af6fb9a0450b66bc57 在现代的编程语言中,接触过多线程编程的程序员多多少少对锁有一定的了解.简单的说,多线程中的锁就是在多线程环 ...

  9. 【Redis笔记】一起学习Redis | 如何利用Redis实现一个分布式锁?

    一起学习Redis | 如何利用Redis实现一个分布式锁? 前提知识 什么是分布式锁? 为什么需要分布式锁? 分布式锁的5要素和三种实现方式 实现分布式锁 思考思考 基础方案 改进方案 保证setn ...

  10. redis ,redisson 分布式锁深入剖析

    目录 为什么要用分布式锁? 分布式锁所遵循的原则? redis 分布式锁 redis 原始分布式锁实现 加锁 释放锁 redis 分布式锁存在的问题 redisson  实现分布式锁 redisson ...

最新文章

  1. axure谷歌浏览器插件_都说谷歌浏览器好用,网页翻译插件插件必不可少
  2. ubuntu idea桌面快捷方式无法启动_每个 Ubuntu 用户都应该知道的键盘快捷键
  3. effective java ---读书笔记一
  4. 程序员修神之路--分布式系统设计理念这么难学?
  5. 如何建立MSSQL数据库
  6. 性能测试流程与性能测试分析和问题定位分享
  7. c语言上机作业题及答案,2017计算机二级C语言上机测试题附答案
  8. python语法学习第十一天--模块
  9. 大学生必学练习题 - C 语言经典50例
  10. java 手机号码归属地_Java获取手机号码归属地
  11. shell中各种括号(),[],(()),[[]],{}等的作用大全及示例
  12. 社团部部长工作计划计算机学院,社团部长的工作计划(共9篇).doc
  13. 同步光网络(SONET,Synchronous Optical Networking)简介
  14. 英特尔傲腾DC P4800X有哪些适用场景?
  15. 有什么拍照识别植物的软件?建议收藏这几个软件
  16. 江南爱窗帘十大品牌 窗帘发展状况怎么样
  17. 西瓜书课后题——第七章(贝叶斯分类器)
  18. 关于Floyd算法 和 Dijkstra算法
  19. 你遇到过开机没反应的现像吗?
  20. WinCE系统深度定制汇总

热门文章

  1. 有趣的算法(八):3分钟看懂选择排序(C语言实现)
  2. 机器学习之特征选择(feature_selection)
  3. python转行符-python实现readline去掉换行符 等特殊字符
  4. PTA 程序设计天梯赛(161~180题)
  5. Fluter拓展 图标库
  6. C++ Gotchas: Avoiding Common Problems in Coding and Design
  7. 对此人的嚣张你们怎么看
  8. 数据结构和算法:线性表链式存储的简单实现
  9. 快速排序及快速选择问题
  10. Hadoop2.x集群动态添加删除数据节点