Redis分布式锁
Redis分布式锁
分布式锁的由来
在传统单机部署的情况下,可以使用Java并发处理相关的API(如ReentrantLcok或synchronized)进行互斥控制。
但是在分布式系统后,由于分布式系统多线程、多进程并且分布在不同机器上,这将使原单机并发控制锁策略失效,为了解决这个问题就需要一种跨JVM的互斥机制来控制共享资源的访问,这就是分布式锁的由来。
当多个进程不在同一个系统中,就需要用分布式锁控制多个进程对资源的访问。最实际的应用场景应该是控制库存,比如说电商平台防止商品超卖这类场景。
分布式锁需要满足的条件
互斥性:任意时刻,只能有一个客户端获取锁,不能同时有两个客户端获取到锁。
安全性:锁只能被持有该锁的客户端删除,不能由其它客户端删除。
不会死锁:获取锁的客户端因为某些原因(如down机等)而未能释放锁,也能保证后续其他客户端能加锁。
容错:只要大部分的Redis节点正常运行,客户端就可以加锁和解锁。
Redis分布式锁实现一(setnx+expire)
实现命令如下
12seynx key valueexpire key time
setnx其实 ...
Redis与分布式
Redis与分布式
主从复制
基本概念
有多个redis服务器,只有一个主节点(Master),其余均为从节点(Slave),主节点可以进行读写操作,从节点只能进行读操作.数据的复制是单向的,从节点中的内容是由主节点中复制过来的(直接复制/间接复制).
一个主节点可以有多个从节点(也可以没有),一个从节点只能有一个主节点.redis主从复制是异步复制,主节点收到写命令,先写到内部缓冲区,然后异步发送给从节点.
配置
在配置文件中添加从节点信息:
1slaveof 主节点IP 主节点端口
作用
数据冗余:主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式。
故障恢复:当主节点出现问题时,可以由从节点提供服务,实现快速的故障恢复;实际上是一种服务的冗余。
负载均衡:在主从复制的基础上,配合读写分离,可以由主节点提供写服务,由从节点提供读服务(即写Redis数据时应用连接主节点,读Redis数据时应用连接从节点),分担服务器负载;尤其是在写少读多的场景下,通过多个从节点分担读负载,可以大大提高Redis服务器的并发量。
高可用基石:除了上述作用以外,主从复制还是哨兵和集群能够实 ...
分布式理论CAP原则和BASE理论
分布式理论CAP原则和BASE理论
CAP原则
CAP原则又称CAP定理,指的是在一个分布式系统中,存在Consistency(一致性)、Availability(可用性)、Partition tolerance(分区容错性),三者不可同时保证,最多只能保证其中的两者。
一致性(C):在分布式系统中的所有数据备份,在同一时刻都是同样的值(所有的节点无论何时访问都能拿到最新的值)
可用性(A):系统中非故障节点收到的每个请求都必须得到响应(比如服务降级和熔断,其实就是一种维持可用性的措施,虽然服务返回的是没有什么意义的数据,但是不至于用户的请求会被服务器忽略)
分区容错性(P):一个分布式系统里面,节点之间组成的网络本来应该是连通的,然而可能因为一些故障(比如网络丢包等,这是很难避免的),使得有些节点之间不连通了,整个网络就分成了几块区域,数据就散布在了这些不连通的区域中(这样就可能出现某些被分区节点存放的数据访问失败,我们需要来容忍这些不可靠的情况)
总的来说,数据存放的节点数越多,分区容错性就越高,但是要复制更新的次数就越多,一致性就越难保证。同时为了保证一致性,更 ...
面向对象六大设计原则
面向对象六大设计原则
单一职责原则(Single Responsibility Principle)
主要指的是一个类,方法,接口中只实现单一职责,这样能够提升代码可读性,可维护性也大大提高,有效避免了屎山代码的出现(确信),进行功能变更时的风险也会降低.
开闭原则(Open Closed Principle)
对于扩展开放,对于修改封闭.
一个软件实体应该通过扩展来实现变化,而不是通过修改已有的代码实现变化.这是为软件实体的未来事件而制定的对现行开发设计进行约束的一个原则.
比如一个类可能有多方需要调用,有时部分调用方有了新的需求,这时不能直接修改类的代码来更改功能,而是需求方将这个类继承过去再进行添加,修改功能,这样出问题不会影响其他调用方,真正做到高内聚,低耦合.
其实类的例子还不够准确,一般都是先将职责方法抽象成接口,然后再根据各自需求的不同进行具体实现.
里式替换原则(Liskov Substitution Principle)
所有引用基类的地方必须能够透明地使用其子类的对象.
通俗点说,只要父类能出现的地方子类就可以出现,而且替换为子类也不会产生任何异常.但是反过来就不 ...
乐观锁和悲观锁
乐观锁和悲观锁
乐观锁
乐观认为不会有别的线程与它来抢占修改,直接对数据进行修改,在提交的时候进行检查,看是否有别的线程修改过数据,如果修改过,就放弃修改,返回错误或者重试.
乐观锁一般有两种实现方式:版本号机制和CAS算法
版本号机制(redis采用的方案)
一般是在数据表中加上一个数据版本号 version 字段,表示数据被修改的次数。当数据被修改时,version 值会加一。当线程 A 要更新数据值时,在读取数据的同时也会读取 version 值,在提交更新时,若刚才读取到的 version 值为当前数据库中的 version 值相等时才更新,否则重试更新操作,直到更新成功。
CAS算法
CAS 的全称是 Compare And Swap(比较与交换) ,用于实现乐观锁,被广泛应用于各大框架中。CAS 的思想很简单,就是用一个预期值和要更新的变量值进行比较,两值相等才会进行更新。
CAS算法会有一个巨大的问题,就是ABA问题.如果一个变量 V 初次读取的时候是 A 值,并且在准备赋值的时候检查到它仍然是 A 值,那我们就能说明它的值没有被其他线程修改过了吗?很明显是不能的,因为在 ...
经典组合问题
经典组合问题
在Leetcode刷过回溯算法的同学应该都知道,组合问题是回溯算法中经典的一种题型
本篇博客给大家介绍的就是组合问题三兄弟:
39.数组总和
40.数组总和II
216.数组总和III
为什么我想说说这三道题呢,因为这三道题的本质就是套回溯算法的模版
属于只要弄明白了,那么组合问题就一定没问题了,甚至大部分的回溯算法问题也能够解决
回溯法(back tracking)(探索与回溯法)是一种选优搜索法,又称为试探法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回到上一步,重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。
回溯算法的关键在于找到终止条件,无论是子过程结束的终止条件,还是回退到上一步的终止条件.
例如 39数组总和 这道题中子过程的终止条件为
1234if(target==0){ ans.add(new ArrayList<>(list)); return;}
回退到上一步的终止条件为
123if(target-candidates ...