分布式锁

Redis面试必知必会

廉价感情. 提交于 2020-03-04 20:22:00
1. 在项目中缓存是如何使用的? 结合自己的公司的项目, 回答以下问题: 项目哪里用了缓存? 为什么要用? 用了可能会带来什么问题? 怎么解决这些问题? 项目的缓存架构是怎么样的? 如果面试官没有问这些问题, 我们也要主动和面试官聊聊. 2. 为什么要在项目中用缓存? (1) 高性能 如果不使用缓存, 每次请求都有较大的延迟, 比如600ms, 而如果每次请求都走缓存, 可能2ms就搞定了. (2) 高并发 在高并发场景下, 比如秒杀之类的促销活动, 如果所有请求都直接查询数据库, 会导致数据库宕机, 这个时候就需要缓存来分担数据库的压力. 3. 用了缓存之后可能会带来什么问题? 如何解决? (1) 缓存与数据库双写不一致 我们先了解下最经典的缓存和数据库的读写模式: 读的时候先读缓存, 再读数据库. 如果缓存中没有, 则从数据库中读取数据写入缓存. 修改数据的时候, 先删除对应的缓存, 再更新数据库. (或者先更新数据库, 再删除缓存) 从上面这个读写模式中我们可以发现, 在修改数据的时候, 只会更新数据库, 而不会同步更新缓存, 缓存是下次读的时候再更新. 这样做的原因是更新缓存的代价比较大, 比如对于一些比较复杂的业务场景, 缓存数据可能涉及到多张表的查询计算, 同时这个缓存数据还不一定会被频繁的访问, 所以综合考虑, 修改数据的时候直接删除缓存,

面经2020.3.3

不想你离开。 提交于 2020-03-04 00:08:10
1、介绍下自己? 2、dubbo如何解决接口幂等性?幂等性如何产生的? 3、分布式锁的使用?锁产生异常如何处理的? 4、数据库的数据重新迁移到另台服务器上如何操作? 5、高并发情况下,MySQL数据中三张表。查询是多表关联查询还是单表? 来源: CSDN 作者: WXF_Sir 链接: https://blog.csdn.net/WXF_Sir/article/details/104636861

Redis(1)

妖精的绣舞 提交于 2020-03-03 05:31:31
1 性能测试 测试环境: RHEL 6.3 / HP Gen8 Server/ 2 * Intel Xeon 2.00GHz(6 core) / 64G DDR3 memory / 300G RAID-1 SATA / 1 master(writ AOF), 1 slave(write AOF & RDB) 数据准备: 预加载两千万条数据,占用10G内存。 测试工具:自带的redis-benchmark,默认只是基于一个很小的数据集进行测试,调整命令行参数如下,就可以开100条线程(默认50),SET 1千万次(key在0-1千万间随机),key长21字节,value长256字节的数据。 1 redis-benchmark -t SET -c 100 -n 10000000 -r 10000000 -d 256 测试结果(QPS): 1.SET:4.5万, 2.GET:6万 , 3.INCR:6万, 4.真实混合场景: 2.5万SET & 3万GET 单条客户端线程时6千TPS,50与100条客户端线程差别不大,200条时会略多。 Get/Set操作,经过了LAN,延时也只有1毫秒左右,可以反复放心调用,不用像调用REST接口和访问数据库那样,每多一次外部访问都心痛。 资源监控: 1.CPU: 占了一个处理器的100%,总CPU是4%(因为总共有2CPU 6核 超线程 =

分布式锁专题

那年仲夏 提交于 2020-03-02 14:26:10
分布式锁 如果你觉得我写的不错, 或者想和我多交流, 就扫一扫关注我吧, 本人公众号: stormling 1. 什么是分布式锁 分布式锁是控制分布式系统之间同步访问共享资源的一种方式。在 分布式系统 中,常常需要协调他们的动作。如果不同的系统或是同一个系统的不同主机之间共享了一个或一组资源,那么访问这些资源的时候,往往需要互斥来防止彼此干扰来保证 一致性 ,在这种情况下,便需要使用到分布式锁。 2. 为什么要使用分布式锁 为了保证一个方法或属性在高并发情况下的同一时间只能被同一个线程执行,在传统单体应用单机部署的情况下,可以使用Java并发处理相关的API(如ReentrantLock或Synchronized)进行互斥控制。在单机环境中,Java中提供了很多并发处理相关的API。但是,随着业务发展的需要,原单体单机部署的系统被演化成分布式集群系统后,由于分布式系统多线程、多进程并且分布在不同机器上,这将使原单机部署情况下的并发控制锁策略失效,单纯的Java API并不能提供分布式锁的能力。为了解决这个问题就需要一种跨JVM的互斥机制来控制共享资源的访问,这就是分布式锁要解决的问题! 举个例子: 机器A , 机器B是一个集群, A, B两台机器上的程序都是一样的, 具备高可用性能. A, B机器都有一个定时任务, 每天晚上凌晨2点需要执行一个定时任务,

SpringBoot 结合 Spring Cache 操作 Redis 实现数据缓存

此生再无相见时 提交于 2020-03-02 10:59:09
系统环境: Redis 版本:5.0.7 SpringBoot 版本:2.2.2.RELEASE 参考地址: Redus 官方网址:https://redis.io/ 博文示例项目 Github 地址:https://github.com/my-dlq/blog-example/tree/master/springboot/springboot-redis-cache-example 一、缓存概念知识 1、是什么缓存 我们日常生活中,经常会接触听到缓存这个词,例如,浏览器清空缓存,处理器缓存大小,磁盘缓存等等。经过分类,可以将缓存分为: 硬件缓存: 一般指的是机器上的 CPU、硬盘等等组件的缓存区间,一般是利用的内存作为一块中转区域,都通过内存交互信息,减少系统负载,提供传输效率。 客户端缓存: 一般指的是某些应用,例如浏览器、手机App、视频缓冲等等,都是在加载一次数据后将数据临时存储到本地,当再次访问时候先检查本地缓存中是否存在,存在就不必去远程重新拉取,而是直接读取缓存数据,这样来减少远端服务器压力和加快载入速度。 服务端缓存: 一般指远端服务器上,考虑到客户端请求量多,某些数据请求量大,这些热点数据经常要到数据库中读取数据,给数据库造成压力,还有就是 IO、网络等原因有一定延迟,响应客户端较慢。所以,在一些不考虑实时性的数据中,经常将这些数据存在内存中(内存速度非常快)

用Redis构建分布式锁

烂漫一生 提交于 2020-03-01 17:09:47
原文地址 原文链接 译者: yy-leo 校对:方腾飞(红体标记重点) 用Redis构建分布式锁 在不同进程需要互斥地访问共享资源时,分布式锁是一种非常有用的技术手段。 有很多三方库和文章描述如何用Redis实现一个分布式锁管理器,但是这些库实现的方式差别很大,而且很多简单的实现其实只需采用稍微增加一点复杂的设计就可以获得更好的可靠性。 这篇文章的目的就是尝试提出一种官方权威的用Redis实现分布式锁管理器的算法,我们把这个算法称为RedLock ,我们相信这个算法会比一般的普通方法更加安全可靠。我们也希望社区能一起分析这个算法,提供一些反馈,然后我们以此为基础,来设计出更加复杂可靠的算法,或者更好的新算法。 实现 在描述具体的算法之前,下面是已经实现了的项目可以作为参考: Redlock-rb (Ruby实现)。还有一个Redlock-rb的分支,添加了一些特性使得实现分布式锁更简单 Redlock-py (Python 实现). Redlock-php (PHP 实现). PHPRedisMutex (PHP 更完整的实现) Redsync.go (Go 实现). Redisson (Java 实现). Redis::DistLock (Perl 实现). Redlock-cpp (C++ 实现). Redlock-cs (C#/.NET 实现). node-redlock

Redis 都不会?那就别去面试了

老子叫甜甜 提交于 2020-03-01 11:54:32
前不久,有一个读者在后台留言,说他面试 Java 开发工程师岗位时,居然大部分的面试问题都是关于 Redis ,他都差点都忘记了自己应聘的是 Java 工程师了。而然这种现象在现在的后端面试中很常见,对 Redis 的掌握已经变成了一项后端工程师必须具备的基础技能了。 当我们翻开那些大厂的招聘要求,你就知道 Redis 真的是一个后端通用技术,俗称通货膨胀下的硬通货。 Redis 作为一个高性能的分布式内存型数据库,被国内外几乎所有的大小型公司所使用,例如 Twitter、Stack Overflow、Github、阿里巴巴、腾讯、新浪微博等,它也早已成为互联网公司的标配,所以对 Redis 的掌握也成为后端工程师必备的基础技能,无论是面试还是实际工作中,我们每时每刻都需要和 Redis 打交道。 Redis 之所以如此流行,是因为它的高效性和简洁性,官方提供的 QPS(Query Per Second,每秒查询率)已经超过 10 万了,以下是官方提供的测试结果图: 其中横轴是连接数,纵轴是 QPS,有兴趣的同学可以去尝试一下 Redis 的基准测试程序。 但是除了高性能之外,Redis 还有一个重要的优点,它的版本更新速度很快,并且功能也越来越强大。比如之前只有 5 种数据类型,而到现在已经有 9 种数据类型。 之前最常用的功能是把它作为缓存数据库

php redis实现秒杀功能

倾然丶 夕夏残阳落幕 提交于 2020-03-01 11:36:28
主要针对并发情况下,通过redis的分布式锁和队列的方式进行处理的代码 Queue:{商品ID}: 数据类型是有序集合(zset),成员是用户ID,score是用户入队的时间戳 Lock:Queue:{商品ID}: 数据类型是字符串(string),存储的是该锁的过期时间 goods:{商品ID}:stock: 存储的是商品的库存数量 简单介绍demo代码中的实现思路: 将当前秒杀的商品id作为一个队列名称 $queue_name = “Queue:{商品ID}”; 对$queue_name进行加锁 通过setnx(满足原子性)实现加锁 :$redis->setnx("Lock:Queue:{商品ID}", $expire time) 加锁成功,给该锁设置一个过期时间,主要是为了防止死锁 如果加锁失败,通过设置休眠时间,进行循环请求 加锁成功后,判断队列中的成员数是否超过指定的大小 $count = $this->redis->zCard("Queue:{$name}"); if($count >= $this->redis->get("goods:{$name}:stock")) { $this->lockModel->unlock("Queue:$name"); return '超过指定集合数量'; } 判断用户ID是否存在队列中,如不存在则加入队列(score

基于Redis实现分布式锁

混江龙づ霸主 提交于 2020-03-01 10:44:18
背景 在很多互联网产品应用中,有些场景需要加锁处理,比如:秒杀,全局递增ID,楼层生成等等。大部分的解决方案是基于DB实现的,Redis为单进程单线程模式,采用队列模式将并发访问变成串行访问,且多客户端对Redis的连接并不存在竞争关系。其次Redis提供一些命令SETNX,GETSET,可以方便实现分布式锁机制。 Redis命令介绍 使用Redis实现分布式锁,有两个重要函数需要介绍 SETNX命令(SET if Not eXists) 语法: SETNX key value 功能: 当且仅当 key 不存在,将 key 的值设为 value ,并返回1;若给定的 key 已经存在,则 SETNX 不做任何动作,并返回0。 GETSET命令 语法: GETSET key value 功能: 将给定 key 的值设为 value ,并返回 key 的旧值 (old value),当 key 存在但不是字符串类型时,返回一个错误,当key不存在时,返回nil。 GET命令 语法: GET key 功能: 返回 key 所关联的字符串值,如果 key 不存在那么返回特殊值 nil 。 DEL命令 语法: DEL key [KEY …] 功能: 删除给定的一个或多个 key ,不存在的 key 会被忽略。 兵贵精,不在多。分布式锁,我们就依靠这四个命令。但在具体实现,还有很多细节

Redis分布式锁 基于GETSET SETNX REDISSON 的实现

不问归期 提交于 2020-03-01 10:12:42
Redis分布式锁的应用 有些场景需要加锁处理,比如:秒杀,全局递增ID,楼层生成等等。大部分的解决方案是基于DB实现的,Redis为单进程单线程模式,采用队列模式将并发访问变成串行访问,且多客户端对Redis的连接并不存在竞争关系。其次Redis提供一些命令SETNX,GETSET,可以方便实现分布式锁机制。 GETSET方式 http://doc.redisfans.com/string/getset.html public final class RedisLockUtil { private static final int defaultExpire = 60; /** * 加锁 * @param key redis key * @param expire 过期时间,单位秒 * @return true:加锁成功,false,加锁失败 */ public static boolean lock(String key, int expire) { RedisService redisService = SpringUtils.getBean(RedisService.class); long status = redisService.setnx(key, "1"); //如果状态等于一 则 成功 返回值成功 if(status == 1) { redisService