分布式锁

springboot 中单机 redis 实现分布式锁

不打扰是莪最后的温柔 提交于 2020-01-03 11:38:24
在微服务中经常需要使用分布式锁,来执行一些任务。例如定期删除过期数据,在多个服务中只需要一个去执行即可。 以下说明非严格意义的分布式锁,因为 redis 实现严格意义的分布式锁还是比较复杂的,对于日常简单使用使用如下简单方法即可。即偶尔不执行任务不影响业务。 实现要点 1)获得锁、释放锁需要是原子操作。要么获取成功,要么失败。释放要么成功,要么失败 2)任务完成需要自己释放自己的锁,不能释放别人的锁。 3)锁要有过期时间限制,防止任务崩溃没有释放锁,导致其他节点无法获得锁。 4)执行节点超时长时间不释放锁,到下次任务开始执行并行存在的情况 要考虑的风险点 1)获取锁失败,偶尔不执行任务要不影响业务或告警人工干预 2)redis 宕机,导致无法获取锁 方案一:低版本使用 jedis 实现 1 添加依赖,高版本或低版本有些方法可能没有 <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <scope>compile</scope></dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.10.2</version><

redis 的相关知识点

半腔热情 提交于 2020-01-03 02:16:11
1、为什么使用redis 使用redis,主要是从两个角度去考虑:性能和并发。当然,redis还具备可以做分布式锁等其他功能,但是如果只是为了分布式锁这些其他功能,完全还有其他中间件(如zookpeer等)代替,并不是非要使用redis。因此,这个问题主要从性能和并发两个角度去答。 回答:如下所示,分为两点 (一)性能 我们在碰到需要执行耗时特别久,且结果不频繁变动的SQL,就特别适合将运行结果放入缓存。这样,后面的请求就去缓存中读取,使得请求能够迅速响应。 题外话:忽然想聊一下这个迅速响应的标准。其实根据交互效果的不同,这个响应时间没有固定标准。不过曾经有人这么告诉我:"在理想状态下,我们的页面跳转需要在瞬间解决,对于页内操作则需要在刹那间解决。另外,超过一弹指的耗时操作要有进度提示,并且可以随时中止或取消,这样才能给用户最好的体验。 (二)并发 在大并发的情况下,所有的请求直接访问数据库,数据库会出现连接异常。这个时候,就需要使用redis做一个缓冲操作,让请求先访问到redis,而不是直接访问数据库。 2、使用redis有什么缺点 分析:大家用redis这么久,这个问题是必须要了解的,基本上使用redis都会碰到一些问题,常见的也就几个。 回答:主要是四个问题 (一)缓存和数据库双写一致性问题 (二)缓存雪崩问题 (三)缓存击穿问题 (四)缓存的并发竞争问题 3

redis实战(二)

眉间皱痕 提交于 2020-01-02 20:57:43
redis使用场景(String) 上文中我们讲到redis一共有5中数据结构(String,Hash,List,Set,Zset),大家了解到了其底层数据结构以及存储方式,那这五种数据结构怎么使用呢?本期带大家了解下redis各种数据结构的使用场景。 命令介绍 String类型作为我们开发日常使用redis时可谓是最常用的场景,简单的key-value的的存储不仅简单而且方便,常用作缓存某些热点数据(key-Json)、计数器(限流)、分布式锁等。这里只列举常用命令 //缓存热点数据 key-jsonString #设置mykey的值为hello 默认的过时时间-1永久 通过EX 指定超时时间 set mykey hello #获取mykey的值 get mykey (return : hello) //计数器 #设置mykey 10 set mykey 10 #incr 对key的值进行加1操作 incrby x 指定加x操作 incr mykey (return : 11) #程序中如果将redis中key值先拿出来 再加1 会出现线程安全问题 需要使用lua脚本解决此问题(将操作原子化 详情看使用场景) //分布式锁 #setnx 如果key不存在则插入 如果存在不做任何操作 setnx mykey hello (return : 1) setnx mykey world

redis如何实现分布式锁?

谁说我不能喝 提交于 2020-01-02 08:07:51
1.分布式锁需要解决的问题 互斥性:任意时刻只能有一个客户端拥有锁,不能同时多个客户端获取 安全性:锁只能被持有该锁的用户删除,而不能被其他用户删除 死锁:获取锁的客户端因为某些原因而宕机,而未能释放锁,其他客户端无法获取此锁,需要有机制来避免该类问题的发生 容错:当部分节点宕机,客户端仍能获取锁或者释放锁 2.如何通过Redis实现分布式锁:(非完善方法) SETNX key value :如果key不存在,则创建并赋值 时间复杂度: 0(1) 返回值:设置成功,返回1;设置失败,返回0。 但是此时我们获取的key是长期有效的,所以我们应该如何解决长期有效的问题呢? 如何解决SETNX长期有效的问题 EXPIRE key seconds 设置key的生存时间,当key过期时(生存时间为0) ,会被自动删除 缺点:原子性得不到满足 下面是伪代码 //该程序存在危险,如果执行到第二行就崩溃了,则此时key会被一直占用而无法被释放 RedisService redisService = SpringUtils.getBean(Redi sService.class); long status = redisService.setnx(key, "1"); if(status == 1) { redisService.expire(key, expire); //执行独占资源逻辑

java操作redis学习笔记

天大地大妈咪最大 提交于 2020-01-02 05:11:15
一、 jedis 操作: 1、POM依赖: 1 <dependency> 2 <groupId>redis.clients</groupId> 3 <artifactId>jedis</artifactId> 4 <version>2.5.0</version> 5 </dependency> 2、 建一个连接 redis 数据库的工具类: 1 public class RedisUtil { 2 3   //服务器IP地址 4 private static String ADDR = "x.x.x.x"; 5    6   //端口 7 private static int PORT = 6379; 8   //密码 9 private static String AUTH = "123456"; 10   //连接实例的最大连接数 11 private static int MAX_ACTIVE = 1024; 12    13   //控制一个pool最多有多少个状态为idle(空闲的)的jedis实例,默认值也是8。 14 private static int MAX_IDLE = 200; 15    16 //等待可用连接的最大时间,单位毫秒,默认值为-1,表示永不超时。如果超过等待时间,则直接抛出JedisConnectionException 17 private

每秒上千订单场景下的分布式锁高并发优化实践!

假装没事ソ 提交于 2020-01-01 21:21:43
本文转载自 石杉的架构笔记 背景引入 首先,我们一起来看看这个问题的背景? 前段时间有个朋友在外面面试,然后有一天找我聊说:有一个国内不错的电商公司,面试官给他出了一个场景题: 假如下单时,用分布式锁来防止库存超卖,但是是每秒上千订单的高并发场景,如何对分布式锁进行高并发优化来应对这个场景? 他说他当时没答上来,因为没做过没什么思路。其实我当时听到这个面试题心里也觉得有点意思,因为如果是我来面试候选人的话,应该会给的范围更大一些。 比如,让面试的同学聊一聊电商高并发秒杀场景下的库存超卖解决方案,各种方案的优缺点以及实践,进而聊到分布式锁这个话题。 因为库存超卖问题是有很多种技术解决方案的,比如悲观锁,分布式锁,乐观锁,队列串行化,Redis原子操作,等等吧。 但是既然那个面试官兄弟限定死了用分布式锁来解决库存超卖,我估计就是想问一个点:在高并发场景下如何优化分布式锁的并发性能。 我觉得,面试官提问的角度还是可以接受的,因为在实际落地生产的时候,分布式锁这个东西保证了数据的准确性,但是他天然并发能力有点弱。 刚好我之前在自己项目的其他场景下,确实是做过高并发场景下的分布式锁优化方案,因此正好是借着这个朋友的面试题,把分布式锁的高并发优化思路,给大家来聊一聊。 库存超卖现象是怎么产生的? 先来看看如果不用分布式锁,所谓的电商库存超卖是啥意思?大家看看下面的图: 这个图,其实很清晰了

redis基础

笑着哭i 提交于 2020-01-01 14:31:36
文章目录 Redis 常见问题 关于的知识点总结成了思维导图 1、什么是 Redis? 2、Redis 的数据类型? 3、使用 Redis 有哪些好处? 4、Redis 相比 Memcached 有哪些优势? 5、Memcache 与 Redis 的区别都有哪些? 6、Redis 是单进程单线程的? 7、一个字符串类型的值能存储最大容量是多少? 8、Redis 的持久化机制是什么?各自的优缺点? 9、Redis 常见性能问题和解决方案: 10、redis 过期键的删除策略? 11、Redis 的回收策略(淘汰策略)? 12、为什么 edis 需要把所有数据放到内存中? 13、Redis 的同步机制了解么? 14、Pipeline 有什么好处,为什么要用 pipeline? 15、是否使用过 Redis 集群,集群的原理是什么? 16、Redis 集群方案什么情况下会导致整个集群不可用? 17、Redis 支持的 Java 客户端都有哪些?官方推荐用哪个? 18、Jedis 与 Redisson 对比有什么优缺点? 19、Redis 如何设置密码及验证密码? 20、说说 Redis 哈希槽的概念? 21、Redis 集群的主从复制模型是怎样的? 22、Redis 集群会有写操作丢失吗?为什么? 23、Redis 集群之间是如何复制的? 24、Redis 集群最大节点个数是多少? 25

秒杀

廉价感情. 提交于 2020-01-01 00:22:58
秒杀方案: 1:拦截秒杀的高配刷新操作 解决方案:对秒杀商品页面独立设计,减少动态内容,页面内容静态化,用户请求不需要经过应用服务。 2:减库存操作 在应用端增加redis库存,通过redis分布式锁方式,库存的扣减和回滚在redis中处理,提高性能,当高并发的时候我们可以通过分片思想,将一个sku的库存分成N片,redis分布式锁只需要随机获取其中一片锁就可以了,N个分片可以支持N个锁,锁之间是隔离的,扣减的时候优先获取库存多的分片锁,回滚的时候优先获取库存少的锁,通过调整权重值的方式实现 3:秒杀服务隔离 1)通过直接改商品价格为秒杀价的方式处理,不再调用营销中心结算和创建订单 2)商品改为单品单售,这样可以去除很多业务场景,让整个下单业务逻辑变的简单,整个下单的io降到最低 4:提供性能方案 1)涉及到数据库查询类的操作,尽量改为redis或者本地缓存 2)部分影响性能的IO操作,在不影响主流程时,可以通过MQ的方式削峰填谷,使得接口处理能够尽量平稳 5:架构设计 6:redis分布式事务和库存扣减 1)redis分布式事务 @Component @Slf4j public class JedisLockUtil { private static final Long RELEASE_SUCCESS = 1 L ; private static final String

Redis常见面试题

房东的猫 提交于 2019-12-31 23:44:52
1、什么是Redis?   Redis 是一个基于内存的高性能key-value数据库,不过在系统中一般充当高速缓存的角色。 2、为什么Redis需要把所有数据放到内存中?    访问内存的速度远高于访问硬盘的速度,如果不将数据放在内存中,磁盘I/O速度将严重影响Redis的性能。在内存越来越便宜的今天,Redis将会越来越受欢迎。 3、对Redis的访问为什么是单进程单线程的   Redis利用队列技术将并发访问变为串行访问,消除了传统数据库串行控制的开销。Redis的开发者认为Redis的性能瓶颈不在CPU,而是网络等因素。所以采取单线程的方式是最快的。单线程能够有效避免CPU切换的开销,另外I/O多路复用技术也有效的提升了访问速度。 4、Reids的特点(Redis的好处) 访问速度快。原因归结为三个方面:一是数据存储在内存中;二是对数据的访问是单线程操作,避免了不必要的IO开销;三是底层的数据结构合理,类似于hashMap,存取的时间复杂度为O(1)。 拥有丰富数据类型。支持string,list,hash ,set,sorted set五种类型 支持事务。拥有与传统数据库不同的独特的事务特性。在Redis中,一个事务中所有命令操作具有原子性 可以持久化缓存数据。拥有AOF和RDB两种持久化方式,保证系统重启数据不丢失 拥有成熟的可扩展,高可用的分布式解决方案。像Redis

Redis安装和使用

核能气质少年 提交于 2019-12-30 04:29:29
简介 Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、一个高性能的key-value数据库。并提供多种语言的API。说到Key-Value数据库NoSQL数据库可以想到MongoDB。 和Memcached类似,但是它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。 用redis就要有数据丢失的准备。 通过homebrew安装redis brew install redis 安装的文件保存在/usr/local/bin下 运行 sudo redis-server 检测 运行后自动在后台运行,关闭后也会继续运行。可以使用端口检测命令来查看。 lsof -i tcp:6379    连接redis redis-cli 存值 set name pgy    设置缓存时间