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’,diamondState of Qatar;注:redis.call是我们在剧本中调用redis命令,KEYS和AEscortGV2个数组,分别是键和参数,下标都以从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(100State of Qatar;MapString,
String beanMap = BeanUtil.warp(player卡塔尔国;// 将对象转变到mapString beanKey
= getRedisBeanKey(player.getClass(卡塔尔国,
player.getId(卡塔尔国卡塔尔;System.out.println(“key:” +
beanKeyState of Qatar;jedis.hmset(beanKey, beanMapState of Qatar;// 将游戏者数量保存到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卡塔尔;”;ListString keys = new
ArrayListString(卡塔尔国;keys.add(beanKeyState of Qatar;ListString args = new
ArrayListString(卡塔尔(قطر‎;args.add(“100″State of Qatar;args.add(“100″State of Qatar;//
3.实施脚本jedis.eval(script, keys, argsState of Qatar;

内定键和仿照效法,实施脚本,结果:

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 MapString, String warp(Object bean) { MapString, String
propertyMap = new HashMapString, 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; }}