分布式锁

zookeeper 分布式锁

99封情书 提交于 2020-03-18 14:56:00
zookeeper 分布式锁 分布式锁的概念,大家应该都已经理解,在此不会细讲。 分布式锁简单来说就是服务器集群环境下出现用户高并发访问同一个资源时,对该资源访问进行加锁等待,以保证资源的准确性。 zookeeper的分布式锁是并发的多线程通过循环的请求创建zk节点来竞争锁的占有权,待取得占有权后,其他线程进入等待。待释放占有权后,其他线程再进行循环竞争。 本编文章,主要讲解zk分布式锁,如何使用,具体逻辑还需根据实际场景进行调整。 代码是在本地建设,为了方便测试,所以里面都是静态方法。真正的开发环境都是基于webservlet或微服务工程,使用bean的方式进行类对象或者方法的调用。大家可以根据自己的工程业务做zk分布式锁的封装。 重点提醒下: 如果使用zk的watcher监听通知,节点创建后并瞬间删除,zkServer将会监听失败。因为zkServer的监听有延迟,当执行监听的时候,他发现并无该节点的stat信息,故不执行监听。 1.客户端创建    zk是支持集群的,所以这里两种客户端形式,代码操作是一样的,唯有连接地址略有差异。 package com.qy.zk.lock; import org.apache.curator.RetryPolicy; import org.apache.curator.framework.CuratorFramework; import

3.【Redis系列】Redis的高级应用-分布式锁

醉酒当歌 提交于 2020-03-18 02:28:15
原文: 3.【Redis系列】Redis的高级应用-分布式锁 在进行分布式应用逻辑开发时,经常会遇到并发问题。 比如我们在修改一个用户的信息,首先需要获取用户信息,再内存中修改后,再存回去。这个过程如果有其他线程同时操作,着就会产生并发问题,因为读取和存储都不是原子性的。我们需要通过分布式锁限制程序的并发执行。 1.分布式锁 分布式锁本质上就是在Redis里面占一个车位,当有新的车辆过来时,发现已经有一辆车停在车位上,只能是放弃或者稍后再来。 我们用命令模拟下: > setnx lock:qqsir true OK ...do something ... >del lock:qqsir 但是这样有一个问题,如果中间的逻辑出现问题,导致没有执行del,这样就会陷入死锁,锁永远不能被释放。 改进1: 我们可以对key设置一个过期时间,这样即使后面逻辑报错,时间到期后也可以将锁是释放掉 > setnx lock:qqsir true OK >expire lock:qqsir 5 ...do something ... >del lock:qqsir 以上的逻辑其实还是存在问题,假设setnx和expire之间突然断电,没有执行,这样锁还是无法释放。这个问题的根本原因就是setnx和expire的操作不是原子性的。 为了解决这个问题,开源社区出现了一堆分布式锁的library

zookeeper实现分布式锁

╄→尐↘猪︶ㄣ 提交于 2020-03-17 11:53:15
思考:分布式锁实现的逻辑 1.争抢锁,只有一个线程可以获得锁。 2.获得锁的线程挂了,产生死锁。解决:使用临时节点(伴随客户端的session,session删除时临时节点也会删除)。 3.获得锁的线程执行成功,释放锁。 4.上面两点,锁被删除或者释放,其他线程如何知道。 (1.主动轮询,弊端:延迟,压力 。 2.watch,解决延迟问题,弊端:压力) 5.sequence(序列节点) + watch:watch前一个,最小的获得锁,一旦最小的释放锁,只给watch他的那个发事件回调。 public class WatchCallBack implements Watcher ,AsyncCallback.StringCallback ,AsyncCallback.Children2Callback ,AsyncCallback.StatCallback { ZooKeeper zk ; String threadName; CountDownLatch cc = new CountDownLatch(1); String pathName; public String getPathName() { return pathName; } public void setPathName(String pathName) { this.pathName = pathName; }

Redis分布式缓存&分布式锁

生来就可爱ヽ(ⅴ<●) 提交于 2020-03-15 11:51:31
1.背景 由于业务需求最近准备将系统中原有的memcached改造为Redis,实现多数据类型的分布式缓存。 2.分布式缓存: 3.集成改造 1) Pom依赖 vcsp-genericProfessionServer\pom.xml <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> <version>2.4.2</version> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> <version>1.7.10.RELEASE</version> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.8.1</version> </dependency> View Code 2) application-*.properties #redis配置********************* spring.redis.hostName

Redis

廉价感情. 提交于 2020-03-14 01:50:56
1 、 Redis 是什么???? 是一个由 C 语言开发的一个开源的(遵从 BSD 协议)高性能键值对的内存数据库,可以用做数据库、缓存、消息中间件等。 Ps : BSD 开源协议 是一个给予 使用 者很大自由的协议。基本上使用者可以 " 为所欲为 ", 可以自由的 使用 ,修改源代码,也可以将修改后的代码作为开源或者专有软件再发布。 性能优秀,数据在内存中,读写速度非常快,支持并发 10W QPS 。单进程单线程,是线程安全的,采用 IO 多路复用机制。丰富的数据类型,支持字符串( strings )、散列( hashes )、列表( lists )、集合( sets )、有序集合( sorted sets )等。支持数据持久化。可以将内存中数据保存在磁盘中,重启时加载。主从复制,哨兵,高可用。可以用作分布式锁。可以作为消息中间件使用,支持发布订阅。 2、 五种数据类型 String 是 Redis 最基本的类型,可以理解成与 Memcached 一模一样的类型,一个 Key 对应一个 Value 。 Value 不仅是 String ,也可以是数字。 String 类型是二进制安全的,意思是 Redis 的 String 类型可以包含任何数据,比如 jpg 图片或者序列化的对象。 String 类型的值最大能存储 512M 。 Hash 是一个键值( key-value

Redis 事务(8)

放肆的年华 提交于 2020-03-13 21:35:10
为什么要用事务 Redis的单个命令是原子性的(比如get set mget mset),如果涉及到多个命令的时候,需要把多个命令作为一个不可分割的处理序列,就需要用到事务。 例如我们之前说的用setnx实现分布式锁,我们先set,然后设置对key设置expire,防止del发生异常的时候锁不会被释放,业务处理完了以后再del,这三个动作我们就希望它们作为一组命令执行。 Redis的事务有两个特点: 按进入队列的顺序执行。 不会受到其他客户端的请求的影响。 Redis的事务涉及到四个命令: 命令 说明 multi 开启事务 exec 执行事务 discard 取消事务 watch 监视 事务用法 案例:张三(zhangsan)和李四(lisi)各有100元,张三需向李四转账50元。张三账户余额减少50元,李四的账户余额增加50元。 127.0.0.1:6379> set zhangsan 100 OK 127.0.0.1:6379> set lisi 100 OK 127.0.0.1:6379> multi OK 127.0.0.1:6379> decrby zhangsan 50 QUEUED 127.0.0.1:6379> incrby lisi 50 QUEUED 127.0.0.1:6379> exec 1) (integer) 50 2) (integer) 150

redis知识点

时光毁灭记忆、已成空白 提交于 2020-03-08 21:38:20
1 redis特点   内存数据库,读写速度快,被应用于缓存。   数据类型丰富,支持事务、持久化、LUA脚本、LRU驱动事件、多种集群方案。   丰富的特性:缓存,消息,过期,自动删除 2 数据类型:   hash: k-v集合,适用于存储对象。 由于组合式的压缩,内存利用率更高。   字符串:一个键最大能存 512MB   列表:按照插入顺序排序。      异步队列: rpush为生产消息, lpop为消费消息。但是消费者下线时,生产消息会丢失。   set集合: string类型的无序集合,通过哈希表实现,增删查的复杂度是 O( 1)。   zset:有序集合,且不重复。 3 存储结构:   redis通讯协议 RESP格式的命令文本存储。是 redis客户端和服务端之前使用的一种通讯协议。特点:实现简单、快速解析、可读性好。 4 redis做缓存的原因   高性能:   a 假如用户第一次访问数据库中的某些数据。这个过程会比较慢,因为是从硬盘上读取的。b 将该用户访问的数据存在缓存中,这样下一次再访问这些数据的时候就可以直接从缓存中获取了。操作缓存就是直接操作内存,所以速度相当快。c 如果数据库中的对应数据改变的之后, 同步改变缓存中相应的数据即可 !   高并发:   直接操作缓存能够承受的请求是远远大于直接访问数据库的

redis语法与命令

给你一囗甜甜゛ 提交于 2020-03-08 19:04:36
一、简述 Redis支持的键值类型有:String字符类型、map散列类型、list列表类型、set集合类型、sortedset有序集合类型。接下来对这些键值类型在使用上进行总结,并介绍下Keys命令,虽然语法简单,但由于数量过多,还需要我们多多实践。 二、String字符类型 1、赋值 语法:SET key value 127.0.0.1:6379> set test 123 OK 2、取值 语法:GET key 127.0.0.1:6379> get test "123“ 3、取值并赋值 语法:GETSET key value 127.0.0.1:6379> getset s2 222 "111" 127.0.0.1:6379> get s2 "222" 4、设置/获取多个键值 语法: MSET key value [key value …] MGET key [key …] 127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3 OK 127.0.0.1:6379> get k1 "v1" 127.0.0.1:6379> mget k1 k3 1) "v1" 2) "v3" 5、删除 语法:DEL key 127.0.0.1:6379> del test (integer) 1 6、数值增减 a. 递增数字 当存储的字符串是整数时

Redis复习篇

橙三吉。 提交于 2020-03-08 15:15:31
1.Redis(简单的,高效的,分布式,基于内存的缓存机制) 1.1 性能极高: 读 110000次/s 写 81000次/s 1.2 丰富的数据类型: String,List,Hash,Set,Ordered Set 1.3 Redis操作都是具有原子性的 1.4 Redis单个Key能存入512M大小 2.Redis 数据类型 2.1 String 2.1.1 String类型常用命令: 赋值语法: set key value:设置Key的值,如果key已经存在则覆盖。 ++setnx key value:只有key不存在时设置key的值(解决分布式锁方案之一)。++ 取值语法: get key : 获取key对应的值,如果key不存在则返回nil。 getrange key start end :对获取key对应的值进行截取。 getbit key offset :对key所存储的字符串值,获取指定偏量上的位(bit)。 mget [key1,key2…] : 获取给定一个或多个key的值。 getset key value : 该语法用于设定key的值并返回旧值。 strlen key :返回key存储字符串的长度。 删除语法: del key : 删除指定的key,如果存在返回数字类型。 自增自减: incr key : incr命令将key的值增一。如果key不存在

谁有115资源分享

℡╲_俬逩灬. 提交于 2020-03-08 08:40:08
基于 Redis 实现 CAS 操作 Intro 在 .NET 里并发情况下我们可以使用 Interlocked.CompareExchange 来实现 CAS (Compare And Swap) 操作,在分布式的情景下很多时候我们都会使用 Redis ,最近在改之前做的一个微信小游戏项目,之前是单机运行的,有些数据存储是基于内存的,直接基于对象操作的,最近要改成支持分布式的,于是引入了 redis,原本基于内存的数据就要迁移到 redis 中存储,原来的代码里有一些地方使用了 Interlocked.CompareExchange 来实现 CAS 操作,迁移到 redis 中之后也需要类似的功能,于是就想基于 redis 实现 CAS 操作。 CAS CAS (Compare And Swap) 通常可以使用在并发操作中更新某一个对象的值,CAS 是无锁操作,CAS 相当于是一种乐观锁,而直接加锁相当于是悲观锁,所以相对来说 CAS 操作 是会比直接加锁更加高效的。 Redis Lua redis 从 2.6.0 版本开始支持 Lua 脚本,Lua 脚本的执行是原子性的,所以我们在实现基于 redis 的分布式锁释放锁的时候或者下面要介绍的实现CAS 操作的,要执行多个操作但是希望操作是原子操作的时候就可以借助 Lua 脚本来实现(也可以使用事务来做) 基于 Redis Lua