redis:Redis是开源,内存存储的数据结构服务器,可用做数据库,高速缓存和消息队列代理.
采用单进程单线程模型,并发能力强大,主流的分布式缓存工具。
做用:减去数据库访问的压力。
redis应用:1.token生成2.session共享3.分布式锁4.自增id5.验证码redis
经过setnx向特定的key值写入一个随机值,而且同时设置失效时间,写值成功即加锁成功.spring
注意点数据库
好比:A节点加锁并设置有效时间,A未执行完毕可是锁已经失效了,B节点趁机加锁,此时A节点准备执行解锁动做,若AB节点加锁写入的值相等的话会形成A节点去解锁B节点的锁,显然不行.缓存
maven依赖:tomcat
<dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> <version>1.7.3.RELEASE</version> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> </dependency>
匹配随机值,删除redis上的特定key的数据,要保证删除动做是原子的,即获取数据丶判断一致丶及删除数据三个操做是原子的。执行以下lua脚本:
ARV[1]是value值服务器
if redis.call("get",KEYS[1])==ARGV[1] then
return redis.call("del",KEYS[1])
else
return 0
end
lua脚本丢到服务器上,它认为是一个操做序列不可分开的序列,redis介绍时说过是一个单进程单线程模型,这点要紧紧记住,所以会经过一个线程执行这个脚本以后才会去处理别的请求,所以保证了lua脚本保证了原子性.session
代码实现:
加锁:数据结构
public boolean tryLock() { //随机生成字符串 String uuid= UUID.randomUUID().toString(); //获取redis原始连接 Jedis jedis = redisManager.getJedis(); //使用setnx命令请求写值,并设置有效时间 String ret=jedis.set(KEY,uuid,"NX","PX",1000); if("OK".equals(ret)){ //供给unlock时从threadLocal获取此值,ThreadLocal完成数据共享 local.set(uuid); return true; } return false; }
解锁:mybatis
public void unlock() { //读取lua脚本 String script= FileUtils.readFileByLines("lua脚本路径"); Jedis jedis=redisManager.getJedis(); //连接redis执行Lua脚本,value值没法从unlock方法入参了,所以用threadLocal来获取 jedis.eval(script, Arrays.asList(KEY),Arrays.asList(local.get())); }
这里是简单的代码实现具体讲怎么用jedis执行对应的方法,方法不齐的能够自行查阅资料并发
顺便简单讲下ThreadLoacl //1/作线程级的数据传递,在spring.mybatis随处可见 //2.好比spring的事务传播属性就是经过threadLocal来传递的 //3.tomcat的session也是放在threadLocal的 private static ThreadLocal<String> local = new ThreadLocal<>();