分布式系列十一: Redis进阶
分布式锁
数据库
数据库是使用唯一索引不允许重复的特性(或自定义实现如乐观锁). 但持有锁的进程如果释放锁时异常则容易导致死锁.
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);
分布式系列十一: Redis进阶的更多相关文章
- 分布式系列十: Redis安装和命令
redis是一个开源的, 内存数据结构存储, 一般用来作为数据库,缓存和消息代理. Redis的优势 多种数据结构 字符类型String 散列类型Hash 列表类型List 集合类型Set 有序集合类 ...
- 分布式缓存技术redis学习系列
分布式缓存技术redis学习系列(一)--redis简介以及linux上的安装以及操作redis问题整理 分布式缓存技术redis学习系列(二)--详细讲解redis数据结构(内存模型)以及常用命令 ...
- 【分布式缓存系列】Redis实现分布式锁的正确姿势
一.前言 在我们日常工作中,除了Spring和Mybatis外,用到最多无外乎分布式缓存框架——Redis.但是很多工作很多年的朋友对Redis还处于一个最基础的使用和认识.所以我就像把自己对分布式缓 ...
- Redis进阶实践之十三 Redis的Redis-trib.rb文件详解
一.简介 事先说明一下,本篇文章不涉及对redis-trib.rb源代码的分析,只是从使用的角度来阐述一下,对第一次使用的人来说很重要.redis-trib.rb是redis官方推出的管理re ...
- Redis系列(一):Redis的简介与安装
原文链接(转载请注明出处):Redis系列(一):Redis的简介与安装 什么是 Redis Redis 是一个使用ANSI C 编写的开源.支持网络协议.基于内存.可选持久性的键值对数据库,它是一个 ...
- Redis进阶实践之十三 Redis的Redis-trib.rb脚本文件使用详解
转载来源:http://www.cnblogs.com/PatrickLiu/p/8484784.html 一.简介 事先说明一下,本篇文章不涉及对redis-trib.rb源代码的分析,只是从使用的 ...
- Redis进阶实践之七Redis和Lua初步整合使用(转载 7)
Redis进阶实践之七Redis和Lua初步整合使用 一.引言 Redis学了一段时间了,基本的东西都没问题了.从今天开始讲写一些redis和lua脚本的相关的东西,lua这个脚本是一个好东西,可以运 ...
- Redis进阶实践之四Redis的基本数据类型(转载4)
Redis进阶实践之四Redis的基本数据类型 一.引言 今天正式开始了Redis的学习,如果要想学好Redis,必须先学好Redis的数据类型.Redis为什么会比以前的Memchaed等内存缓存软 ...
- Java分布式:分布式锁之Redis实现
Java分布式:分布式锁之Redis实现 分布式锁系列教程重点分享锁实现原理 Redis锁原理 核心命令 Redis分布式锁的原理是基于其SETNX命令,我们来看SETNX的解释. 实现过程 使用SE ...
随机推荐
- QTableWidget class
Help on class QTableWidget in module PyQt5.QtWidgets: class QTableWidget(QTableView) | QTableWidge ...
- RabbitMQ的一些有用教程
最近学习了一些RabbitMQ的知识,现在对所阅读过的一些非常优秀的教程进行总结,感谢各位博主和大神的无私奉献. 一.原理篇 https://blog.51cto.com/lookingdream/2 ...
- 2018年NGINX最新版高级视频教程
2018年NGINX最新版高级视频教程,想要的联系我,QQ:1844912514
- linux定时备份学习笔记
1.iterm2链接远程中文乱码 shh端vi ~/.bash_profile export LC_CTYPE=en_US.UTF-8 source ~/.bash_profile 2.WARNI ...
- 【tool】VLC播放rtmp协议
您的输入无法被打开: VLC 无法打开 MRL「rtmp://112.35.3.71:47201/api/6276-0.1546939632724.flv」.详情请检查日志.
- ThunderBird配置邮箱后无法发送邮件
今天遇到的问题是在ThunderBird配置邮箱后无法发送邮件.用户名和密码都验证过去了.但一直无法发送邮件. 1.首先imap 和smtp 服务器都是通的. telnet imap.base-fx. ...
- Oracle查看表实际占用空间和实际行数
select t.table_name,t.num_rows from user_tables t ORDER BY NUM_ROWS DESC;//实际行数 analyze table emp co ...
- debian apt sources
deb http://debian.csie.ntu.edu.tw/debian/ sid main contrib non-free deb-src http://debian.csie.ntu.e ...
- 归并排序-JAVA实现
package com.iloveu.xxx; public class MergeSort { static final int SIZE = 15; static void mergeOne(in ...
- Ubuntu 16.04 RabbitMq 安装与运行(安装篇)
Ubuntu 16.04 RabbitMq 安装与运行(安装篇) 2018年08月15日 15:05:24 我跟吴彦祖四六开 阅读数:1966 前言 目前公司用阿里云 + redis 的方式实现的 ...