分布式锁

一分钱引发的系统设计“踩坑”案例

♀尐吖头ヾ 提交于 2019-12-04 20:50:04
摘要: 阿里妹导读:阿里巴巴的电商业务十分复杂,一方面是市场多样化,业务多样化,另外是消费者,商家的影响面非常广,任何一个小故障都可能引发一些社会问题,所以阿里对产品的质量,对服务的连续性有严格的要求。阿里技术人员在日常的研发运维过程中,积累了丰富的实战经验。 阿里妹导读:阿里巴巴的电商业务十分复杂,一方面是市场多样化,业务多样化,另外是消费者,商家的影响面非常广,任何一个小故障都可能引发一些社会问题,所以阿里对产品的质量,对服务的连续性有严格的要求。阿里技术人员在日常的研发运维过程中,积累了丰富的实战经验。今天,阿里妹将为大家分享一个关于故障,排查,分析和改进的真实案例。他山之石可以攻玉,希望对广大开发和运维工程师带来帮助。 背景说明 某日,做产品X的开发接到客户公司电话,说是对账出了1分钱的差错,无法处理。本着“客户第一”的宗旨,开发立马上线查看情况。查完发现,按照产品X当日的年化收益率,正常情况下用户在转入57元后一共收益3分钱,合计是57.03元。但是该客户当日却有一笔消费57.04元,导致客户公司系统对多出的1分钱处理不了。再进一步分析,发现用户收益结转时多了1分钱的收益,并且已消费…… 也就是说,本来用户只有3分钱收益,结果多发了1分钱给他,也就给公司造成1分钱的损失!用户在产品X里当天收益本应该是0.03元,怎么会变成0.04元呢?多出的1分钱收益从哪里来的呢?

Redis

筅森魡賤 提交于 2019-12-04 20:39:07
1. 为啥在项目里要用缓存呢 用缓存,主要是俩用途,高性能和高并发 高性能 image.png 高并发 image.png 2.介绍 Redis 是一个开源的使用 ANSI C 语言编写、遵守 BSD 协议、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库,并提供多种语言的 API的非关系型数据库。 传统数据库(关系型数据库)遵循 ACID 规则。而 Nosql(非关系型数据库)(Not Only SQL 的缩写,是对不同于传统的关系型数据库的数据库管理系统的统称) 一般为分布式,而分布式一般遵循 CAP 定理。 CAP理论 C:consistency(一致性) A:avalibility(可用性) P:Partition(分区)-tolerence to partition(分区容忍度) 分区:一个分布式系统,网络不通讯,导致连接不通,系统被分割成几个数据区域 原因:数据不连通了,产生数据分区 影响: 查还好一点 数据修改时,必须要求数据一致--加锁,实现数据一致性【需求要求数据一致性】 数据修改时,可以数据不一致--不用加锁【需求不要求数据一致性】 分区容忍度 数据的一致性要求高,容忍度高,加锁 数据的一致性要求低,容忍度低,可以不加锁 预期结果,保持数据的一致 可用性 请求在一定时间段内都应该有响应 为了解决锁一直加着 CP理论:【一致性+分区

五、Curator使用:分布式锁

泄露秘密 提交于 2019-12-04 20:15:18
分布式锁介绍 分布式执行一些不需要同时执行的复杂任务,curator利用zk的特质,实现了这个选举过程。其实就是利用了多个zk客户端在同一个位置建节点,只会有一个客户端建立成功这个特性。来实现同一时间,只会选择一个客户端执行任务 代码 //分布式锁 InterProcessMutex lock = new InterProcessMutex(cc,"/lock_path"); CountDownLatch down = new CountDownLatch(1); for (int i = 0; i < 30; i++) { new Thread(()->{ try { down.await(); lock.acquire(); } catch (Exception e) { e.printStackTrace(); } SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS"); System.out.println(sdf.format(new Date())); try { lock.release(); } catch (Exception e) { e.printStackTrace(); } }).start(); } down.countDown(); InterProcessMutex

分布式锁总结

别等时光非礼了梦想. 提交于 2019-12-04 16:12:34
0 前言 可以先看下之前写的实现分布式锁的方案 分布式锁的实现 然后再来看下下面的总结。 1 设置锁超时时间 redis、数据库等实现的分布式锁,需要设置锁超时时间的原因在于:其他客户端无法得知已经获取锁的客户端的状态 是挂了呢,还是正在执行。所以只能傻傻的设置一个超时,认为超时之后就 简单的 判定获取锁的客户端挂了。 一旦锁设定了超时时间,可能获取锁的客户端因各种原因执行业务操作的时候耗时较长,超出了锁的超时时间,这时其他客户端就可以再次获取锁了,所以就会带来并发问题。 2 消除锁超时时间 为了消除这个锁超时,就需要由服务器来作为代理来通知, 如ZooKeeper,一旦客户端挂了,就会删除对应的临时节点,然后通知watch该节点的其他客户端。所以客户端不需要设置锁超时,就等待通知即可。 从这点来说ZooKeeper是更可靠的,降低了因锁超时带来的并发问题。 3 方案的高可用问题 redis、数据库等方案要想实现高可用,则必须有对应的高可用方案。如最简单的主从架构,又引入了一致性的问题,又会有很多的坑。 ZooKeeper方案本身可以做到高可用、一致性,所以ZooKeeper方案也更简单一些。 4 连接的单点问题 这个单点不是说redis或zookeeper的单点问题,而是客户端和服务器端的这个连接的单点问题。先来举个例子: 如ZooKeeper还是会出现并发问题的

redis分布式锁(一)———springboot 整合 redisson

给你一囗甜甜゛ 提交于 2019-12-04 15:23:24
   前段时间项目中大量用到了redis的分布式锁,近期总结一下,先从springboot整合redisson说起。    Redisson是一个在Redis的基础上实现的Java驻内存数据网格(In-Memory Data Grid)。它不仅提供了一系列的分布式的Java常用对象,还提供了许多分布式服务。其中包括( BitSet , Set , Multimap , SortedSet , Map , List , Queue , BlockingQueue , Deque , BlockingDeque , Semaphore , Lock , AtomicLong , CountDownLatch , Publish / Subscribe , Bloom filter , Remote service , Spring cache , Executor service , Live Object service , Scheduler service ) Redisson提供了使用Redis的最简单和最便捷的方法。 一、添加maven依赖 在pom.xml加入如下配置 <dependency> <groupId>org.redisson</groupId> <artifactId>redisson-spring-boot-starter</artifactId>

Redis 分布式锁的正确实现方式(Java版)[转]

▼魔方 西西 提交于 2019-12-04 11:07:53
本文来源: https://www.cnblogs.com/linjiqin/p/8003838.html 前言 分布式锁一般有三种实现方式: 数据库乐观锁; 基于Redis的分布式锁; 基于ZooKeeper的分布式锁 本篇博客将介绍第二种方式,基于Redis实现分布式锁。 虽然网上已经有各种介绍Redis分布式锁实现的博客,然而他们的实现却有着各种各样的问题,为了避免误人子弟,本篇博客将详细介绍如何正确地实现Redis分布式锁。 可靠性 首先,为了确保分布式锁可用,我们至少要确保锁的实现同时满足以下四个条件: 互斥性 。在任意时刻,只有一个客户端能持有锁。 不会发生死锁 。即使有一个客户端在持有锁的期间崩溃而没有主动解锁,也能保证后续其他客户端能加锁。 具有容错性 。只要大部分的Redis节点正常运行,客户端就可以加锁和解锁。 解铃还须系铃人 。加锁和解锁必须是同一个客户端,客户端自己不能把别人加的锁给解了。 代码实现 组件依赖 首先我们要通过Maven引入Jedis开源组件,在pom.xml文件加入下面的代码: < dependency> < groupId>redis.clientsgroupId> < artifactId>jedisartifactId> < version>2.9.0version> > 加锁代码 正确姿势 Talk is cheap, show me

《吊打面试官》系列-Redis常见面试题(带答案)

限于喜欢 提交于 2019-12-04 09:11:21
你知道的越多,你不知道的越多 点赞再看,养成习惯 GitHub 上已经开源 https://github.com/Java… ,有面试点思维导图,欢迎 Star 和 完善 前言 Redis 在互联网技术存储方面使用如此广泛,几乎所有的后端技术面试官都要在 Redis 的使用和原理方面对小伙伴们进行360°的刁难。 作为一个在互联网公司面一次拿一次Offer的面霸,打败了无数竞争对手,每次都只能看到无数落寞的身影失望的离开,略感愧疚( 请允许我使用一下夸张的修辞手法 )。 于是在一个寂寞难耐的夜晚,我痛定思痛,决定开始写 《吊打面试官》 系列,希望能帮助各位读者以后面试势如破竹,对面试官进行360°的反击,吊打问你的面试官,让一同面试的同僚瞠目结舌,疯狂收割大厂Offer! 絮叨 上一期因为是在双十一一直在熬夜的大环境下完成的,所以我自己觉得质量明显没之前的好,我这不一睡好就加班加点准备补偿大家,来点干货。(熬夜太容易感冒了,这次 点个赞 别白嫖了!) 顺带提一嘴,我把我准备写啥画了一个思维导图,以后总不能每篇都放个贼大的图吧,就开源到了我的 GitHub ,大家有兴趣可以去完善和 Star 。 这篇我就先放出来大家看看,感觉还是差点意思,等大家完善了。 回望过去 上一期吊打系列我们提到了 Redis 相关的一些知识,还没看的小伙伴可以回顾一下 《吊打面试官》系列-Redis基础

redis原理及应用

大兔子大兔子 提交于 2019-12-04 07:01:19
一、redis来源 二、数据类型 三、主流的应用场景 四、特性 五、补充 一、 redis来源 redis作者:Salvatore Sanfilippo (antirez),男,意大利人. 需求:一个访客信息追踪网站,网站可以通过JavaScript脚本,将访客的IP地址、所属国家、阅览器信息、被访问页面的地址等数据传送给LLOOGG. com。然后LLOOGG.com会将这些浏览数据通过web页面实时地展示给用户,并储存起最新的5至10,000条浏览记录以便进行查阅。 redis解决方案 每当某个被追踪的网站新增一条浏览记录时,LLOOGG.com就会将这条新的浏览记录推入(push)到与该网站相对应的列表里面,当列表的长度超过用户指定的最大长度时,程序每向列表推入一条新的记录,就需要从列表中弹出(pop)一条最旧的记录。 现在已经被广泛使用: Twitter使用Redis来储存用户时间线(user timeline)。 StackOverflow使用Redis来进行缓存和消息分发。 Pinterest使用Redis来构建关注模型(follow model)和兴趣图谱(interest graph)。 Flickr使用Redis来构建队列。 Github使用Redis作为持久化的键值对数据库,并使用Resque来实现消息队列。 新浪微博使用Redis来实现计数器、反向索引、排行榜

《吊打面试官》系列-Redis终章_凛冬将至、FPX_新王登基

和自甴很熟 提交于 2019-12-04 06:06:18
你知道的越多,你不知道的越多 点赞再看,养成习惯 前言 Redis 在互联网技术存储方面使用如此广泛,几乎所有的后端技术面试官都要在 Redis 的使用和原理方面对小伙伴们进行360°的刁难。作为一个在互联网公司面一次拿一次offer的面霸( 请允许我使用一下夸张的修辞手法 ),打败了无数竞争对手,每次都只能看到无数落寞的身影失望的离开,略感愧疚,在一个寂寞难耐的夜晚,我痛定思痛,决定开始写 《吊打面试官》 系列,希望能帮助各位读者以后面试势如破竹,对面试官进行360°的反击,吊打问你的面试官,让一同面试的同僚瞠目结舌,疯狂收割大厂offer! 絮叨 男儿何不带吴钩,收取关山五十州 FPX 🐂B,LPL两年连冠🏆 🐂B! 看着金色的雨落下,我到窗边,发现天有点蓝,风有点绵,我的眼角又湿了! 最近双十一讲道理有点忙的说,直接肝爆,就是这样作为 暖男 的我,还是给你们挤出时间搞出终章,忍不住给自己 点赞 👍 放个双十一照片证明真的忙,希望别取关!!! 现在你们在看的时候,我应该还在睡觉哈哈。困🛌 之前跟你们说的, 限流 , 降级 ,是不是在双十一又应验了,下单接口其实没挂,牺牲部分用户体验,保住服务器,你多点几下是可以成功的,等流量高峰过去了,所有的用户全部都恢复正常访问,服务器也没啥事。 去年退款接口被打崩了,今年阿里明显也聪明了很多。 正文

Springboot集成Redisson分布式锁

China☆狼群 提交于 2019-12-04 05:49:53
pom文件添加Redisson依赖 <dependency> <groupId>org.redisson</groupId> <artifactId>redisson</artifactId> <version>3.6.5</version> </dependency> application配置redis信息:我的redis没有设置密码,你们有的可以加一个password填上自己的密码 spring: redis: host: localhost port: 6379 timeout: 1000 写一个Redisson配置类生成bean: package com.hengtong.led.config; import org.redisson.Redisson; import org.redisson.api.RedissonClient; import org.redisson.config.Config; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration