分布式锁

[Java复习] 缓存Cache part2

时光毁灭记忆、已成空白 提交于 2019-12-05 06:18:48
7. Redis持久化有哪几种方式?不同的持久化机制都有什么优缺点?持久化机制具体底层是如何实现的? 为什么要持久化? 如果只是存在内存里,如果redis宕机再重启,内存数据就丢失了,所以要用持久化机制。 将数据写入内存的同时,异步的慢慢将数据写入磁盘文件,定期同步或备份到云存储服务上,进行持久化。 如果redis宕机重启,自动从磁盘加载之前持久化的一些数据,也许会丢失少量数据,但至少不会丢所有数据。 Redis 持久化的两种方式: RDB 和 AOF RDB(Redis Database) : 是对redis中的数据执行 周期性 的持久化。 简单说就是每个几分钟或几个小时,生成redis内存中数据的一份全量快照副本。 AOF(Append-Only-File) :是对每条写入命令作为日志,以append-only的模式写入一个日志文件中,在redis重启的时候,可以通过回放AOF日志中的写入指令来重新构建整个数据集。 现在操作系统中,写文件不是直接写磁盘,会先写os cache(linux),然后到一定时间从os cache写到磁盘文件。 如果同时使用 RDB 和 AOF 两种持久化机制,那么在 redis 重启的时候,会使用 AOF 来重新构建数据,因为 AOF 中的数据更加完整。 RDB 优缺点: 优点: 1. 非常适合做冷备份。 RDB生成多个文件

Redis从入门到精通

梦想的初衷 提交于 2019-12-05 05:23:05
常用的 SQL 数据库的数据都是存在磁盘中的,虽然在数据库底层也做了对应的缓存来减少数据库的 IO 压力。 由于数据库的缓存一般是针对查询的内容,而且粒度也比较小,一般只有表中的数据没有发生变动的时候,数据库的缓存才会产生作用。 但这并不能减少业务逻辑对数据库的增删改操作的 IO 压力,因此缓存技术应运而生,该技术实现了对热点数据的高速缓存,可以大大缓解后端数据库的压力。 主流应用架构 客户端在对数据库发起请求时,先到缓存层查看是否有所需的数据,如果缓存层存有客户端所需的数据,则直接从缓存层返回,否则进行穿透查询,对数据库进行查询。 如果在数据库中查询到该数据,则将该数据回写到缓存层,以便下次客户端再次查询能够直接从缓存层获取数据。 缓存中间件 Memcache 和 Redis 的区别 Memcache 的代码层类似 Hash,特点如下: 支持简单数据类型 不支持数据持久化存储 不支持主从 不支持分片 Redis 特点如下: 数据类型丰富 支持数据磁盘持久化存储 支持主从 支持分片 为什么 Redis 能这么快 Redis 的效率很高,官方给出的数据是 100000+QPS,这是因为: Redis 完全基于内存,绝大部分请求是纯粹的内存操作,执行效率高。 Redis 使用单进程单线程模型的(K,V)数据库,将数据存储在内存中,存取均不会受到硬盘 IO 的限制,因此其执行速度极快。

redis面试题

孤街浪徒 提交于 2019-12-05 04:33:39
看你简历上写了你项目里面用到了Redis,你们为啥用Redis? 因为传统的关系型数据库如Mysql已经不能适用所有的场景了,比如秒杀的库存扣减,APP首页的访问流量高峰等等,都很容易把数据库打崩,所以引入了缓存中间件,目前市面上比较常用的缓存中间件有Redis 和 Memcached 不过中和考虑了他们的优缺点,最后选择了Redis。 Redis有哪些数据结构呀? 字符串String、字典Hash、列表List、集合Set、有序集合SortedSet。 如果有大量的key需要设置同一时间过期,一般需要注意什么? 如果大量的key过期时间设置的过于集中,到过期的那个时间点,redis可能会出现短暂的卡顿现象。严重的话会出现缓存雪崩,我们一般需要在时间上加一个随机值,使得过期时间分散一些。 电商首页经常会使用定时任务刷新缓存,可能大量的数据失效时间都十分集中,如果失效时间一样,又刚好在失效的时间点大量用户涌入,就有可能造成缓存雪崩 那你使用过Redis分布式锁么,它是什么回事? 先拿setnx来争抢锁,抢到之后,再用expire给锁加一个过期时间防止锁忘记了释放。 这时候对方会告诉你说你回答得不错,然后接着问如果在setnx之后执行expire之前进程意外crash或者要重启维护了,那会怎么样? 这时候你要给予惊讶的反馈:唉,是喔,这个锁就永远得不到释放了

基于zookeeper实现分布式锁

隐身守侯 提交于 2019-12-05 04:26:14
前言:2016春节之后一直比较忙,因此博客N个没有更新,现在也是忙里偷闲,偷偷的更新一篇! 一、分布式锁介绍 分布式锁主要用于在分布式环境中保护跨进程、跨主机、跨网络的共享资源实现互斥访问,以达到保证数据的一致性。 二、架构介绍 在介绍使用Zookeeper实现分布式锁之前,首先看当前的系统架构图 解释: 左边的整个区域表示一个Zookeeper集群,locker是Zookeeper的一个 持久节点 ,node_1、node_2、node_3是locker这个持久节点下面的 临时顺序节点 。client_1、client_2、client_n表示多个客户端,Service表示需要互斥访问的共享资源。 三、分布式锁获取思路 1. 获取分布式锁的总体思路 在获取分布式锁的时候在locker节点下创建临时顺序节点,释放锁的时候删除该临时节点。客户端调用createNode方法在locker下创建临时顺序节点, 然后调用getChildren(“locker”)来获取locker下面的所有子节点,注意此时不用设置任何Watcher。客户端获取到所有的子节点path之后,如果发现自己在之 前创建的子节点序号最小,那么就认为该客户端获取到了锁。如果发现自己创建的节点并非locker所有子节点中最小的,说明自己还没有获取到锁, 此时客户端需要找到比自己小的那个节点,然后对其调用exist()方法

Redis实现分布式锁

試著忘記壹切 提交于 2019-12-05 04:26:04
Redis实现分布式锁 在集群等多服务器中经常要使用到同步处理一下业务,这时普通的事务是满足不要业务需求,需要分布式锁。分布式锁的实现方式有多种,如redis实现分布式锁,zookeeper实现分布式锁等,这篇先实现redis分布式锁。 实现原理 1、通过setnx(lock_timeout)实现,如果设置了锁返回1,已经有值没有设置成功返回0。 2、死锁问题:通过时间来判断是否过期,如果已经过期,获取到过期时间get(lockKey),然后getset(lock_timeout)判断是否和get相同,相同则证明已经加锁成功,因为可能会导致多个线程同时执行getset(lock_timeout)方法。这是可能导致多个线程都只需getset后,对于判断加锁成功的线程,再加expire(lockKey, LOCK_TIMEOUT, TimeUnit.MILLISECONDS)过期时间,防止多个线程同时叠加时间,导致锁时效时间翻倍。 3、针对集群服务器时间不一致问题,可以从调用redis的time()获取当前时间。 代码实现 分布式锁接口 DistributionLock.java /** * 创建时间:2016年12月8日 下午6:51:51 * * 分布式锁 * * @author andy * @version 2.2 */ public interface

使用Redis实现分布式锁

☆樱花仙子☆ 提交于 2019-12-05 04:25:45
1.实现分布式锁的几种方案 1.Redis实现 (推荐) 2.Zookeeper实现 3.数据库实现 Redis实现分布式锁 * * 在集群等多服务器中经常使用到同步处理一下业务,这是普通的事务是满足不了业务需求,需要分布式锁 * * 分布式锁的常用3种实现: * 0.数据库乐观锁实现 * 1.Redis实现 --- 使用redis的setnx()、get()、getset()方法,用于分布式锁,解决死锁问题 * 2.Zookeeper实现 * 参考:http://surlymo.iteye.com/blog/2082684 * http://www.jb51.net/article/103617.htm * http://www.hollischuang.com/archives/1716?utm_source=tuicool&utm_medium=referral * 1、实现原理: 基于zookeeper瞬时有序节点实现的分布式锁,其主要逻辑如下(该图来自于IBM网站)。大致思想即为:每个客户端对某个功能加锁时,在zookeeper上的与该功能对应的指定节点的目录下,生成一个唯一的瞬时有序节点。判断是否获取锁的方式很简单,只需要判断有序节点中序号最小的一个。当释放锁的时候,只需将这个瞬时节点删除即可。同时,其可以避免服务宕机导致的锁无法释放,而产生的死锁问题。 2、优点

redis实现分布式锁

别等时光非礼了梦想. 提交于 2019-12-05 02:25:21
在单体中,大部分使用synchronize来加锁,但是这个锁只是在一个jvm中起作用,而现在大体是分布式,这个时候就可以考虑使用redis加锁了。 主要思想: 1.唯一key,可锁性 2.不论什么情况要保证锁的释放(redis过期时间,删除key) 3.主线程的执行时间比rdis的过期时间长 解决方案:加钟。开一个子线程写一个定时器,去检查主线程执行完了没有,如果没有的话,就重新设置redis的过期时间。 (已经有一个redisson(类似于jedis)的工具实现了,前者多用于分布式中) 4.redisson的使用方式 pom引入相关依赖 来源: https://www.cnblogs.com/qq-7895/p/11844138.html

Redis分布式锁的实现方式

烂漫一生 提交于 2019-12-05 02:23:47
前言 分布式锁一般有3中实现方式: 数据库乐观锁; 基于Redis的分布式锁; 基于ZooKeeper的分布式锁。 以下将详细介绍如何正确地实现Redis分布式锁。 可靠性 首先,为了确保分布式锁的可用,我们至少要确保锁的实现的同时,要满足以下四个条件: 互斥性。 在任意时刻,只有一个客户端持有锁。 不会发生死锁。 即使一个客户端在持有锁的期间发生崩溃而没有主动释放锁,也能保证后续其他客户端能加锁。 具有容错性。 只要大部分的 Redis 节点正常运行,客户端就可以加锁和解锁。 解铃还须系铃人。 加锁和解锁必须是同一个客户端,客户端自己不能把别人加的锁给解了。 代码实现  组件依赖   首先我们通过 Maven 引入 Jedis 开源组件,在 pom.xml 文件加入以下代码: 1 <dependency> 2 <groupId>redis.clientsgroupId</groupId> 3 <artifactId>jedisartifactId</artifactId> 4 <version>2.9.0version</version> 5 </dependency>  加锁代码   先放代码,后面再解释为什么这样实现: 1 public class RedisTool { 2 3 private static final String LOCK_SUCCESS = "OK";

数据库优化方案整理

有些话、适合烂在心里 提交于 2019-12-04 23:05:13
一:优化说明 A:有数据表明,用户可以承受的最大等待时间为8秒。数据库优化策略有很多,设计初期,建立好的数据结构对于后期性能优化至关重要。因为数据库结构是系统的基石,基础打不好,使用各种优化策略,也不能达到很完美的效果。 B:数据库优化的几个方面 ​​ 可以看出来,数据结构、SQL、索引是成本最低,且效果最好的优化手段。 C:性能优化是无止境的,当性能可以满足需求时即可,不要过度优化。 二:优化方向 1. SQL以及索引的优化 首先要根据需求写出结构良好的SQL,然后根据SQL在表中建立有效的索引。但是如果索引太多,不但会影响写入的效率,对查询也有一定的影响。 2. 合理的数据库是设计 根据数据库三范式来进行表结构的设计。设计表结构时,就需要考虑如何设计才能更有效的查询。 数据库三范式: 第一范式:数据表中每个字段都必须是不可拆分的最小单元,也就是确保每一列的原子性; 第二范式:满足一范式后,表中每一列必须有唯一性,都必须依赖于主键; 第三范式:满足二范式后,表中的每一列只与主键直接相关而不是间接相关(外键也是直接相关),字段没有冗余。 注意:没有最好的设计,只有最合适的设计,所以不要过分注重理论。三范式可以作为一个基本依据,不要生搬硬套。 有时候可以根据场景合理地反规范化: A:分割表。 B:保留冗余字段。当两个或多个表在查询中经常需要连接时,可以在其中一个表上增加若干冗余的字段

Redis实战--Jedis实现分布式锁

孤街醉人 提交于 2019-12-04 23:01:33
echo编辑整理,欢迎转载,转载请声明文章来源。欢迎添加echo微信(微信号:t2421499075)交流学习。 百战不败,依不自称常胜,百败不颓,依能奋力前行。——这才是真正的堪称强大!!! 分布式锁的基本要求 互斥 没有死锁 我持有的锁只能被我释放 分布式锁的释放和获取代码实现 package com.example.echo.redis.distlock; import redis.clients.jedis.Jedis; import java.util.Collections; /** * @author XLecho * Date 2019/11/18 0018 * Time 21:14 */ public class DistLock { private static final String LOCK_SUCCESS = "OK"; private static final String SET_IF_NOT_EXIST = "NX"; private static final String SET_WITH_EXPIRE_TIME = "PX"; private static final Long RELEASE_SUCCESS = 1L; /** * 尝试获取分布式锁 * * @param jedis redis客户端 * @param lockKey 锁 *