分布式锁

*
数据库

数据库是使用唯一索引不允许重复的特性(或自定义实现如乐观锁). 但持有锁的进程如果释放锁时异常则容易导致死锁.

*
zookeeper

使用临时节点, watcher可以获得节点被删除的通知, 当客户端连接失效后, 临时节点清除, 所以这种情况下不会有死锁发生.

*
redis

setNX实现
// 为了简单就不用配置文件了 @Configuration public class RedisManager { private JedisPool
jedisPool ; public RedisManager(){ JedisPoolConfig jedisPoolConfig = new
JedisPoolConfig(); jedisPoolConfig.setMaxTotal(20);
jedisPoolConfig.setMaxIdle(10); this.jedisPool = new JedisPool(jedisPoolConfig,
"127.0.0.1",6379); } @Bean public Jedis getJedis(){ if (this.jedisPool==null){
return null; } return jedisPool.getResource(); } } // lock, unlock 方法这里没有用异常处理.
@Component public class RedisLock { @Autowired private Jedis jedis; public
String lock(String key, int timeout){ String uuid =
UUID.randomUUID().toString(); long lockTime = System.currentTimeMillis();
while(System.currentTimeMillis()-lockTime<timeout*1000) { long rs =
jedis.setnx(key, uuid); if (rs==1){ jedis.expire(key, (int) timeout); return
uuid; } // 保证key被设置了超时时间 if (jedis.ttl(key)==-1){ jedis.expire(key, (int)
timeout); } } return uuid; } public boolean unlock(String key, String value){
while(true) { jedis.watch(key); String ret = jedis.get(key); if
(value.equals(ret)) { Transaction transaction = jedis.multi();
transaction.del(key); List<Object> transResult = transaction.exec(); if
(transResult == null) { continue; } jedis.unwatch(); return true; }
jedis.unwatch(); break; } return false; } }
lua语言

redis可以使用lua脚本. lua是动态类型语言.

*
减少网络开销

*
原子操作

*
代码可以复用

*
轻量级

安装

tar -zxvf ...
make linux
make install

出现fatal error: readline/readline.h: No such file or directory 则需要运行

sudo apt-get install libreadline-dev

命令

* 全局变量, 局部变量 a=1 print(a) local b=2 print(b) //局部变量,在一条语句 local array =
{"a","b"} //数组定义
*
逻辑表达式

*
*
* / %
不等于使用~=

* 逻辑运算
not (a and/or B)

* 字符串连接
str1..str2

* 字符串长度用#
#"hello"

* 分支
if expression then elseif expression then end

* 循环
while expression do ..... end

for i=1,100 do .... end

for i,v in iparis(array) do ..... end

* 注释
单行使用-- ; 范围使用--[[ ..... ]]

* 函数 function(params...) --...... return a; end
内置对象: String , Table tonumber()

* lua 可以调用redis命令
redis.call() --需要引入库支持, redis内置的lua, 可以在redis内部执行

lua在Redis中的使用

*
执行 eval 'lua script' keynumber key...

*
KEYS[] ARGV[] 入参, 必须大写

*
执行lua脚本文件./redis-cli --eval luafile.lua keyparam1 , valueparam2 vlaueparam3

程序中使用lua
String lua = "local num = redis.call('incr',KEYS[1]) ... "; jedis.eval();
可以使用摘要执行脚本, 这对大脚本文件比较有用.
jedis.evalsha(jedis.scriptLoad(lua),key,value);

友情链接
KaDraw流程图
API参考文档
OK工具箱
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:ixiaoyang8@qq.com
QQ群:637538335
关注微信