redis分布式锁

JAVA面试——Redis

…衆ロ難τιáo~ 提交于 2019-12-01 02:25:07
1、Redis是什么?都有哪些使用场景? Redis是一个使用C语言开发的高速缓存数据库。 Redis使用场景: 1)记录帖子点赞数、点击数、评论数; 2)缓存近期热帖; 3)缓存文章详情信息; 4)记录用户会话信息。 2、Redis有哪些功能? 1)数据缓存功能; 2)分布式锁的功能; 3)支持数据持久化; 4)支持事务; 5)支持消息队列。 3、Redis和memcache有什么区别? 1)存储方式不同:memcache把数据全部存在内存之中,断电后会挂掉,数据不能超过内存大小;Redis有部分存在硬盘上,这样能保证数据的持久性。 2)数据支持类型:memcache对数据类型支持相对简单;Redis有复杂的数据类型。 3)使用底层模式不同:它们之间底层实现方式,以及与客户端之间通信的应用协议不一样,Redis自己构建了vm机制,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求。 4)value值大小不同:Redis最大可以达到1GB;memcache只要1MB。 4、Redis为什么是单线程的? 因为cpu不是Redis的瓶颈,Redis的瓶颈最有可能是机器内存或者网络宽带。既然单线程容易实现,而且cpu又不会成为瓶颈,那就顺理成章地采用单线程的方案了。 关于Redis的性能,官方网站也有,普通笔记本轻松处理每秒几十万的请求。

Redis优雅实现分布式锁

試著忘記壹切 提交于 2019-11-30 22:09:05
文章原创于公众号:程序猿周先森。本平台不定时更新,喜欢我的文章,欢迎关注我的微信公众号。 在实际项目开发中经常会遇到这样一个业务场景:如果同一台机器有多个线程抢夺同一个共享资源,同一个线程多次执行会出现异常,这种情况下就会出现非线程安全。我们解决方法通常使用锁来解决。但是如果有多台机器呢?这时候我们通常使用分布式锁来解决分布式环境下共享资源的同步问题。实现分布式锁常见有Redis,zookeeper等,今天主要就是讲讲如何使用Redis实现分布式锁。 使用Redis实现分布式锁的方案其实很简单,首先我们先实现一个方案一:每次执行请求的时候,机器先查询Redis中是否存在分布式锁的key,如果不存在锁的key,就以该锁为key,value取随机数写入到Redis中,然后开始执行请求。 方案一看起来很简单,但是这样的处理逻辑不可避免的存在两个致命的BUG:第一:如果一个进程成功取到锁,但是这时候这个机器出现故障宕机了,分布式的锁没有得到释放,就造成了死锁的产生了。第二:如果同一时间存在两个机器同时查询Redis,都发现Redis不存在锁的key,于是都成功获得了锁。 这时候我们可以这么处理改善方案一实现方案二:Redis有提供一个原子写入操作的命令:setnx,setnx只有在锁的key不存在的情况下才允许设置key值

通过 Redis 实现分布式锁

生来就可爱ヽ(ⅴ<●) 提交于 2019-11-30 20:58:17
当多个进程在不同的系统中,就需要使用分布式锁控制多个进程对同一个资源的访问。本篇介绍的是通过 Redis 实现的分布式锁。 为了确保分布式锁的可用性,我们至少要确保锁的实现同时满足以下四个条件: 互斥性; 不会发生死锁,即使有一个客户端在持有锁的期间崩溃而没有主动解锁,也能保证后续其他客户端能加锁; 具有容错性,只要大部分的 Redis 节点正常运行,客户端就可以加锁和解锁; 加锁和解锁必须是同一个客户端,客户端自己不能把别人加的锁给解了。 分布式锁实现方案: 数据库乐观锁; 通过 Redis 实现分布式锁,利用 Redis 的 setnx 命令来实现分布式锁; 通过 Zookeeper 实现分布式锁,利用 Zookeeper 的顺序临时节点实现分布式锁和等待队列; 优缺点: 分布式锁 优点 缺点 Redis set 和 del 指令的性能较高。 1、实现复杂,需要考虑超时、原子性、误删等情况; 2、没有等待的队列,只能在客户端自旋来等锁,效率低下。 Zookeeper 1、有封装好的框架,容易实现; 2、有等待锁的队列,大大提升抢锁效率。 添加和删除节点性能较低。 通过 Redis 实现分布式锁的流程图: 占用 不占用 访问资源 获得锁 判断锁是否被占用 等待释放 创建key 当前线程拥有该锁 释放锁,即删除key Redis 没有等待锁的队列,只能在客户端自旋来等锁。这里

redis

社会主义新天地 提交于 2019-11-30 16:17:59
1.redis支持的数据类型 1)String:string类型是Redis最基本的数据类型 2)Hash:hash是一个string类型的field和value的映射表,hash特别适合用于存储对象。 3)List:列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边) 4)Set:Redis的Set是string类型的无序集合。 5)zset: Redis zset 和 set 一样也是string类型元素的集合,且不允许重复的成员。 不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。 2.redis持久化与优缺点 1)RDB(默认)与AOF RDB:在指定的时间间隔能对你的数据进行快照存储。 AOF:记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据。 2)优缺点分析 aof文件比rdb更新频率高,优先使用aof还原数据。 aof比rdb更安全也更大 rdb性能比aof好 如果两个都配了优先加载AOF 3.redis架构 1)单节点 特点:简单 问题: 1、内存容量有限 2、处理能力有限 3、无法高可用。 2)哨兵 特点: 1、master/slave 角色 2、master/slave 数据相同 3、降低 master 读压力在转交从库 问题:

redis 基础(一)

南笙酒味 提交于 2019-11-30 15:48:24
Redis 的特点 性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。 Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。 Redis支持数据的备份,即master-slave模式的数据备份。 丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。 原子 – Redis的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过MULTI和EXEC指令包起来。 高可用和分布式:哨兵机制实现高可用,保证redis节点故障发现和自动转移 丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。 Redis 的五种数据类型 string string 数据类型是最常用、简单的key-value类型,普通的key/value 存储都可以归为此类。value不仅可以是字符串,也可以是数字,图片(base64),对象(序列化); 使用场景 : 做缓存数据的功能 spring-boot-starter-data-redis 存储 session 信息 spring-session-data-redis 做分布式锁

基于RedisTemplate的Redis工具类

做~自己de王妃 提交于 2019-11-30 13:31:27
package com.common.util; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.DataAccessException; import org.springframework.data.redis.connection.RedisConnection; import org.springframework.data.redis.core.RedisCallback; import org.springframework.data.redis.core.RedisTemplate; import java.time.OffsetDateTime; import java.util.*; import java.util.concurrent.TimeUnit; /** * @author E */ public class RedisUtils { private static final String LOCK_PREFIX = "PROJECT_NAME_"; private static final Long LOCK_EXPIRE = 1000L; @Autowired RedisTemplate

laravel中redis的分布式锁实现与使用

好久不见. 提交于 2019-11-30 12:23:04
laravel的缓存类的store的redis实现,位于命名空间 Illuminate\Cache\RedisStore其中实现了LockProvider,可获取锁实例,锁实例为Illuminate\Cache\RedisLock类的实例,RedisLock类是Illuminate\Cache\Lock抽象类的实现 调用方法get()获取锁时(RedisLock->get()),首先调用$this->acquire(),具体代码为 public function acquire(){ $result = $this->redis->setnx($this->name, $this->owner); if ($result === 1 && $this->seconds > 0) { $this->redis->expire($this->name, $this->seconds); } return $result === 1;}其中使用redis的setnx命令,只有当key不存在时才能设置成功,通过此种方式实现分布式锁的获取,当get()方法中传入过期时间(秒数)时,此时会设置过期时间,以避免意外造成死锁的情况当需要等待锁释放时,可以使用这个类中的block方法,该方法具体代码为: public function block($seconds, $callback = null

为什么使用 Redis及其产品定位

£可爱£侵袭症+ 提交于 2019-11-30 10:39:59
传统MySQL+ Memcached架构遇到的问题 实际MySQL是适合进行海量数据存储的,通过Memcached将热点数据加载到cache,加速访问,很多公司都曾经使用过这样的架构,但随着业务数据量的不断增加,和访问量的持续增长,我们遇到了很多问题: MySQL需要不断进行拆库拆表,Memcached也需不断跟着扩容,扩容和维护工作占据大量开发时间。 Memcached与MySQL数据库数据一致性问题。 Memcached数据命中率低或down机,大量访问直接穿透到DB,MySQL无法支撑。 跨机房cache同步问题。 众多NoSQL百花齐放,如何选择 最近几年,业界不断涌现出很多各种各样的NoSQL产品,那么如何才能正确地使用好这些产品,最大化地发挥其长处,是我们需要深入研究和思考的问 题,实际归根结底最重要的是了解这些产品的定位,并且了解到每款产品的tradeoffs,在实际应用中做到扬长避短,总体上这些NoSQL主要用于解决 以下几种问题 少量数据存储,高速读写访问。此类产品通过数据全部in-momery 的方式来保证高速访问,同时提供数据落地的功能,实际这正是Redis最主要的适用场景。 海量数据存储,分布式系统支持,数据一致性保证,方便的集群节点添加/删除。 这方面最具代表性的是dynamo和bigtable 2篇论文所阐述的思路。前者是一个完全无中心的设计

asp.net core 从单机到集群

亡梦爱人 提交于 2019-11-30 10:29:49
asp.net core 从单机到集群 Intro # 这篇文章主要以我的活动室预约的项目作为示例,看一下一个 asp.net core 应用从单机应用到分布式应用需要做什么。 示例项目 # 活动室预约提供了两个版本, 集群版 和 单机版 单机版方便部署,不依赖其他环境,数据库使用的是 sqlite,详细部署文档可以参考: https://github.com/WeihanLi/ActivityReservation/blob/dev/docs/deploy/standalone.md 集群版,目前依赖的组件有 mysql(数据库)/redis(缓存)/elasticsearch(日志) 日志 # 日志原来是输出到文件中的,单机部署没有什么问题,可以直接 ssh 到机器上查看文件内容,但是如果部署到集群上,日志再输出到文件的话,排查起来可就有点麻烦了,日志是分散在多台机器上,只看某一台机器上的日志可能并不能解决问题。 基于日志这个痛点让我把日志迁移到 elasticsearch 上,日志统一输出到 es,并通过 kibana 来搜索/分析日志。 日志组件一直用的 log4net,日志输出到 es ,自己写了一个 es 的 Appender, 但是后来越来越觉得 log4net使用起来不够灵活,后来日志组件换成了 serilog,使用 serilog 就可以方便的扩展

为什么分布式一定要有redis,redis的一些优缺点

ε祈祈猫儿з 提交于 2019-11-30 10:24:50
2019-09-24 1、为什么使用redis 分析:博主觉得在项目中使用redis,主要是从两个角度去考虑:性能和并发。当然,redis还具备可以做分布式锁等其他功能,但是如果只是为了分布式锁这些其他功能,完全还有其他中间件(如zookpeer等)代替,并不是非要使用redis。因此,这个问题主要从性能和并发两个角度去答。 回答:如下所示,分为两点 (一)性能 如下图所示,我们在碰到需要执行耗时特别久,且结果不频繁变动的SQL,就特别适合将运行结果放入缓存。这样,后面的请求就去缓存中读取,使得请求能够迅速响应。 题外话:忽然想聊一下这个迅速响应的标准。其实根据交互效果的不同,这个响应时间没有固定标准。不过曾经有人这么告诉我:"在理想状态下,我们的页面跳转需要在瞬间解决,对于页内操作则需要在刹那间解决。另外,超过一弹指的耗时操作要有进度提示,并且可以随时中止或取消,这样才能给用户最好的体验。" 那么瞬间、刹那、一弹指具体是多少时间呢? 根据《摩诃僧祗律》记载 一刹那者为一念,二十念为一瞬,二十瞬为一弹指,二十弹指为一罗预,二十罗预为一须臾,一日一夜有三十须臾。 那么,经过周密的计算,一瞬间为0.36 秒,一刹那有 0.018 秒.一弹指长达 7.2 秒。 (二)并发 如下图所示,在大并发的情况下,所有的请求直接访问数据库,数据库会出现连接异常。这个时候