Redis的作用,数据类型,缓存穿透,击穿和雪崩,Redis的索引模式,Redis怎么测试【杭州多测师_王sir】
Redis的介绍-菜鸟教程:https://www.runoob.com/redis/redis-tutorial.html
一、Redis的作用:
1.缓存数据,存在内存当中,效率非常高,比存储型数据快上千倍
2.计数器,比如用户访问了多少次,点赞数统计
3.可以限制 IP 的访问频率
4.可以设置失效时间,可以用来设置优惠券到期时间
5.任务队列:比如到货通知,内容更新
6.排行榜:redis 的有序集合类型非常适合处理榜单和排序
7.好友关系处理:redis 的集合类型可以处理交集并集,筛选共同好友,共同爱好之类的一些操作
二、Redis的基本数据类型:
string(字符串)
hash(哈希散列)
list(列表)
set(集合)
zset(sorted set:有序集合)
三、redis 的使用会遇到的问题:
1.缓存穿透
缓存穿透:指在redis缓存中不存在数据,这个时候只能去访问持久层数据库(MySQL,断电数据也不会消失),当用户很多时,缓存都没有命中就会造成很大压力
解决方案 :
1)布隆过滤器(对可能查询的数据先用hash存储)
2)缓存空对象:在没有的数据中存一个空,而这些空的对象会设置一个有效期
2.缓存击穿
缓存击穿:指在同一个时间内访问一个请求的请求数过多,而在这个时候缓存某个key失效了,这个时候就会冲向数据库照成缓存击穿
解决方案:
1)设置缓存永远不过期
2)加互斥锁,使用分布式锁,保证每个key只有一个线程去查询后端服务,而其他线程为等待状态。这种模式将压力转到了分布式锁上
3.缓存雪崩
缓存雪崩:在某个时间段,缓存集体过期、redis宕机
解决方案:给key的失效时间设置为随机时间,避免集体过期,双缓存,加互斥锁
四、redis的索引:
redis的索引模式基本是基于sorted set的,因sorted set有数值,数值就是索引,你可以根据它找到其他值。
Redis的索引模式有如下几种:
1.sorted set
2.字典排序
3.地理信息
4.文本查询
5.redis search
6.jredisearch
五、Redis应用场景
数据类型:String
比如:我想知道什么时候封锁一个IP(某一个IP地址在某一段时间内访问的特别频繁,那有可能这个IP可能存在风险,所以对它进行封锁),使用Incrby命令记录当前IP访问次数
存储用户信息【id,name,age】
存储方式:set(userKey,用户信息字符串)
数据类型:Hash
存储用户信息【id,name,age】
存储方式:Hset(key,filed,value)
hset(userKey,id,101)
hset(userKey,name,"admin")
hset(userKey,age,23)
这样存储的好处:当修改用户信息某一项属性值时,直接通过filed取值,并修改值
-----修改案例------
hget(userKey,id)
hset(userKey,id,102)
------------------------------
为什么不使用String存储?
获取方式:get(userKey)
会把参数为userKey对应的用户信息字符串全部进行反序列号,而用户信息字符串包含了用户所有的信息
如果我只修改用户的ID,那反序列化的其他信息其实是没有任何意义的
序列化与反序列化是由IO进行操作的,使用String类型存储增加了IO的使用次数,降低了程序的性能
对值为某类信息时不建议使用String类型存储
数据类型:List
实现最新消息的排行,还可以利用List的push命令,将任务存在list集合中,同时使用另一个pop命令将任务从集合中取出
Redis-list数据类型来模拟消息队列。
比如:电商中的秒杀就可以采用这种方式来完成一个秒杀活动
数据类型:set
特殊之处:可以自动排重。
比如微博中将每个人的好友存在集合(Set)中
如果求两个人的共同好友的操作,我们只需要求交集即可。(交/并集命令)
数据类型:Zset
有序集合(sorted set),以某一个条件为权重,进行排序。
比如:京东看商品详情时,都会有一个综合排名,还有可以安装价格、销量进行排名
六、Redis是怎么测试的?【超级重点】
redis要怎么测试?首先我们需要知道,redis是什么?它能做什么?
redis是一个key-value类型的高速存储数据库。
redis常被用做:缓存、队列、发布订阅等。
所以,“redis要怎么测试?”这个问题就可以转化为:
缓存怎么测试?
队列怎么测试?
订阅怎么测试?
在我所接触的技术栈中,发布订阅很少用redis的,我们主要说一说缓存和队列。
01缓存的分类
缓存有几种类型:文件缓存、数据库缓存、内存缓存、浏览器缓存。
浏览器缓存指的是浏览器自身的缓存能力。现代浏览器为了加快页面加载速度,往往会把css、js等资源文件下载一次之后缓存一段时间,直到缓存失效或者请求明确告知需要更新。
通过后端语言直接渲染、smarty等模板渲染方式输出界面的,一般都会选择文件类型缓存。
随着大前端技术迅速发展,前后端分离越来越流行,smarty渲染的方式使用越来越少,对后端服务的接口响应时间要求也越来越高,文件缓存不再适用这种场景,数据库缓存越来越流行。
数据库缓存目前最常见的:redis和memcached。它们都是分布式的key-value高速缓存系统。
内存缓存跟数据库缓存也是类似的,但受技术栈限制,比如Java可以使用,并且Java中使用非常频繁,但PHP无法使用。内存缓存比数据库缓存更快,但因为内存不可能一直增加,所以限制更多,稍不注意就会出现内存泄漏等问题。
在实际的使用过程中,Java接口往往会将部分高频数据塞到内存缓存中作为一级缓存,次高频数据塞到redis中作为二级缓存,最后再从db查询数据。
缓存的作用:
从上面的内容你可能已经知道,缓存最重要的两个作用:加快访问速度、减少服务器和db压力。
02缓存的使用场景
你可能会问,上面这些跟测试没啥关系啊?不,我认为了解上面的内容对测试还是有帮助的。你知道在技术实现上,什么时候应该加缓存,什么时候不应该加缓存吗?这就是对一个接口的技术把控,不光开发需要知道,测试人员也一样。
如果一个应该添加缓存的接口没有添加缓存在压测之前被你提前发现了,你不觉得自豪吗?其实跟缓存的作用一一对应,当接口的qps较高(比如超过100)或者对响应速度有要求,或者服务器性能、db性能较差的,都可以尝试使用缓存解决问题。
我举几个例子说明:
1、微信新版本中,个人中心多了一个“状态”功能。
微信的用户体量非常庞大,访问qps非常高,几十万人在同一秒访问,不可能每次都去查询数据库。
类似这种需求,一般会是这样的做法:先把用户的状态数据缓存在app中(浏览器缓存),在某个时间段通过主动推或者被动拉的方式调用后端接口请求“状态”数据;接口从redis/memcached的缓存中读取数据并返回;如果数据量不那么庞大,接口可以直接从内存缓存中读取数据并返回;数据返回后,再把用户app中的缓存更新。
2、有一个小型电商的商品管理后台列表页面,访问人数不多,sku改动频次很低,可能3天才被访问几十次。这种场景一不需要使用缓存,二在商品信息被更新之后需要立即看到更新后的数据,不适合使用缓存,所以不建议使用缓存。
3、同样的电商管理后台,这次是一个统计页面,统计昨天/今天/近一周的商品销售情况。
这个场景可以分情况来看,有多种不同的解决方案。
(我们抛开大数据统计的各类技术方案,简单实现一个系统的统计功能)
不需要实时统计
只需要定时统计一次即可,比如只看昨天一天统计数据:可以由定时脚本统计之后直接存储在db,需要查看统计数据时直接查询db即可
需要查询实时统计数据
但需要查询的各个统计sql执行效率满足预期:每次查看数据直接查询db即可,此时db压力不大
需要查询实时统计数据
且因业务数据庞大,各个统计sql执行效率非常低或无法直接统计:可以汇总各个指标,将统计值维护在缓存中,比如需要销量信息,每售出一件商品,销量统计值缓存+1,查看统计数据时查询此时的缓存即可
03缓存的生成方式
了解到缓存的使用场景之后,我们来说说缓存的生成方式。
一般来说缓存有两种使用方式,我简单概括为:外面和里面。
先来说说一个接口的请求到了程序里,是怎么处理的:
这是一个典型的MVC,由Controller接收和处理请求数据,由Service处理Model中获取的数据,再由View输出。
对不同场景,我们可以采取多种方式,在多个节点增加不同的缓存,来解决不同的问题。
比如,针对请求参数多变,返回的数据如果跟请求参数强相关,适合在“外面”(请求参数过滤之后)缓存查询到的数据。这类数据一般缓存时间短,比如缓存5分钟。主要应对相同请求参数在短时间内的重复请求。如果遇到请求攻击,即使这个缓存有效期只有1秒,也是很有效的,能挡住大量的请求。
比如,针对请求参数变化不大,返回的数据跟db中存储的数据很接近的情况,适合在“里面”缓存数据,也就是在更新db的同时更新缓存,这种情况最优的状态下,只需要读缓存就够了,不需要跟db直接交互,能大大缓解db压力。这种缓存有效期可以设置很长。
04缓存的更新方式
说完生成,再来说说缓存的更新。缓存在生成之后,正常都不会一成不变,所以需要对缓存进行更新。
有几种更新方式:
过期后自动更新:这是最懒的更新方式。通过设置缓存有效期,让缓存失效后通过新的请求自动创建新的缓存。
删除缓存:在更新db数据后,直接删除缓存,通过新的请求自动创建新的缓存。
重新设置缓存:在更新db数据后,直接重新设置缓存。
05redis缓存测试点
1、性能测试角度
缓存增加/更新功能是否正确,查看缓存数据是否正确
增加相关日志,查看日志
后门接口工具
使用命令行,memcached和reids可以登录后,直接查看
缓存删除
缓存有效,验证相关业务功能
缓存被删除,验证相关业务功能
缓存过期失效,memcached 和redis 可以设置失效时间,查看失效时间有没有,对不对
超量淘汰机制:缓存达到上限怎么处理
缓存穿透
缓存雪崩
redis缓存服务停掉
缓存超时
缓存数据被误修改后,快速恢复到指定版本
缓存数据被误删除后,快速恢复数据
2、Redis功能测试角度
redis数据生效时,读取是否正确
redis数据不存在,能否正常从db中读取到正确的值,并正确写入Redis和返回给上层
数据在redis和db中都不存在时的表现是否正常
删除数据时,redis和db的数据是否一致