redis分布式锁

redis面试题

懵懂的女人 提交于 2020-03-05 00:53:06
什么是redis? Redis全称为:Remote Dictionary Server(远程数据服务),是一个基于内存的高性能key-value数据库。 Redis的数据类型? Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。 Redis相比Memcached有哪些优势? (1) Memcached所有的值均是简单的字符串,redis作为其替代者,支持更为丰富的数据类型 (2) Redis的速度比Memcached快很多 (3) Redis可以持久化其数据 Redis是单进程单线程的? Redis是单进程单线程的,redis利用队列技术将并发访问变为串行访问,消除了传统数据库串行控制的开销。 一个字符串类型的值能存储最大容量是多少? 512M MySQL里有2000w数据,redis中只存20w的数据,如何保证redis中的数据都是热点数据? redis内存数据集大小上升到一定大小的时候,就会施行数据淘汰策略。 Redis 有哪几种数据淘汰策略? volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰 volatile-ttl:从已设置过期时间的数据集(server.db[i].expires

Redis面试必知必会

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

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核 超线程 =

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 实现分布式锁

感情迁移 提交于 2020-03-01 07:41:33
锁是我们在设计和实现大多数系统时绕不过的话题。一旦有竞争条件出现,在没有保护的操作的前提下,可能会出现不可预知的问题。 而现代系统大多为分布式系统,这就引入了分布式锁,要求具有在分布各处的服务上保护资源的能力。 而实现分布式锁,目前大多有以下三种方式: 使用数据库实现。 使用 Redis 等缓存系统实现。 使用 Zookeeper 等分布式协调系统实现。 其中 Redis 简便灵活,高可用分布式,且支持持久化。本文即介绍基于 Redis 实现分布式锁。 SETNX 语义 使用 Redis 实现分布式锁,根本原理是 SETNX 指令。其语义如下: SETNX key value 命令执行时,如果 key 不存在,则设置 key 值为 value(同set);如果 key 已经存在,则不执行赋值操作。并使用不同的返回值标识。命令描述文档 还可以通过 SET 命令的 NX 选项使用: SET key value [expiration EX seconds|PX milliseconds] [NX|XX] NX - 仅在 key 不存在时执行赋值操作。命令描述文档 而如下文所述,通过SET的NX选项使用,可同时使用其它选项,如EX/PX设置超时时间,是更好的方式。 SETNX 实现分布式锁 下面我们对比下几种具体实现方式。 方案1:SETNX + delete 伪代码如下: setnx

Redis分布式锁解决超卖问题

感情迁移 提交于 2020-02-27 02:47:50
redis事物介绍 1. redis事物是可以一次执行多个命令,本质是一组命令的集合。 2. 一个事务中的所有命令都会序列化,按顺序串行化的执行而不会被其他命令插入 作用:一个队列中,一次性、顺序性、排他性的执行一系列命令 multi 指令基本使用 1. 下面指令演示了一个完整的事物过程,所有指令在exec前不执行,而是缓存在服务器的一个事物队列中 2. 服务器一旦收到exec指令才开始执行事物队列,执行完毕后一次性返回所有结果 3. 因为redis是单线程的,所以不必担心自己在执行队列是被打断,可以保证这样的“原子性” 注:redis事物在遇到指令失败后,后面的指令会继续执行        # Multi 命令用于标记一个事务块的开始事务块内的多条命令会按照先后顺序被放进一个队列当中,最后由 EXEC 命令原子性( atomic )地执行 > multi(开始一个redis事物) incr books incr books > exec (执行事物) > discard (丢弃事物) 在命令行 测试redis事物 [ root@redis ~ ] # redis-cli 127.0 .0 .1 : 6379 > multi OK 127.0 .0 .1 : 6379 > set test 123 QUEUED 127.0 .0 .1 : 6379 > exec 1 ) OK