[经典面试题] redis虽然是单线程模型,为什么效率还这么高?速度这么快呢?
原因:1、redis主要访问内存,数据库则是主要访问硬盘。
2、redis的核心功能,比数据库的核心功能更简单。数据库对于数据的CRUD,都有更复杂的功能支持。这样的功能势必要花费更多的开销。
3、redis采取了单线程模型,避免了一些不必要的线程竞争开销。redis的每个基本操作,都是短平快的,不会特别消耗cpu资源。
4、redis在处理网络IO的时候,使用了epoll这样的IO多路复用机制。
注:IO多路复用:让一个线程可以管理多个socket。针对TCP来说,服务器这边每次要服务一个客户端,都要给这个客户端安排一个socket。但是很多情况下,每个客户端和服务器之间的通信并不频繁。此时socket大部分时间都是静默的,上面是没有数据需要传输的。同一时刻,只有少数socket是活跃的。
String相关命令
注:redis中,所有的key默认都是String类型,而value则有各种各样的类型(整数,字符串,JSON.....)
关于set命令:
将 string 类型的 value 设置到 key 中。如果 key 之前存在,则覆盖,⽆论原来的数据类型是什么。之前关于此 key 的 TTL 也全部失效。
EX: set key value ex 10 就相当于set key value 和 expire key 10两个命令组合起来。即创建键值对同时设置键值对的过期时间。单位是秒
PX: 同上,单位是ms
NX:如果key不存在(创建新的键值对),才设置。如果key存在,则不设置(返回nil)
XX:如果key存在,才设置(相当于更新key的value)。如果key不存在,则不设置(返回nil)
MSET/MGET
可以一次操作多组键值对。通过一次网络通信完成多个键值对操作,减少网络通信时间。
如:mset key1 111 key2 222 key3 333 mget key1 key2 key3
时间复杂度:O(n) n是key的数量
SETNX/SETEX/PSETEX
针对set的一些常见方法,进行了缩写。
SETNX: 即set命令搭配NX。
SETEX: set命令搭配EX。设置过期时间。
PSETEX:set命令搭配PX,单位ms。
时间复杂度:O(1)
incr/incrby/decr/decrby/incrbyfloat
这组命令是针对value为整数类型进行修改的。返回值就是 修改之后的值。
incr: 针对value +1
incrby: 针对value + n, n可以手动指定
decr:针对value -1
decrby: 针对 value - n
incrbyfloat: 针对value + / - 小数。上述命令都针对整数,incrbyfloat可以操作浮点数
注:incr操作的key如果不存在,就会把这个key的value当做0来使用。
时间复杂度:O(1)
append/getrange/setrange/srtlen
append:如果key存在并且是一个string,命令会将value追加到原有string的后边。如果key不存在,则效果等同于set命令。返回值是追加完成后字符串的长度(字节)。
注:redis的字符串,不会对字符编码做任何处理。redis中存储的都是二进制数据。
若要在redis中存储中文,可以在启动redis客户端的时候,加上一个--raw选项。就可以使redis客户端能够自动的把二进制数据尝试翻译。
getrange: 获取字符串当中的一部分。start和end表示获取的范围(左闭右闭)。支持下标为负数。-1表示倒数第一个字符。
setrange: 覆盖字符串的一部分,从指定的偏移开始。返回值是替换后字符串的长度。如果key不存在,就创建一个新键值对,在offset之前的内容填充成0x00。
strlen:获取字符串的长度。单位是字节。当value不是字符串类型,就会报错。当key不存在,返回0
String内部的编码方式
string内部有三种编码方式:
1、int 64位/8字节的整数
2、embstr 压缩字符串,适用于表示比较短的字符串。redis存储小数,本质上是当作字符串来存储。
3、raw 普通字符串,适用于表示更长的字符串,只是单纯的持有字节数组。
String的应用场景
缓存功能
应用服务器访问数据的时候,先查询redis,如果redis上数据存在了,就直接从redis取数据交给应用服务器,不继续访问数据库了。如果redis上的数据不存在,再读取MySQL的结果,返回给应用服务器,并把热点数据写入到redis中。由于 Redis 具有⽀撑⾼并发的特性,所以缓存通常能起到加速读写和降低后端压⼒的作⽤。
如果redis中存储的数据过多怎么办:1、在把数据写给redis时,给这个key设置一个过期时间。
2、redis也在内存不足的时候,提供了淘汰策略。
计数功能
多应⽤都会使⽤ Redis 作为计数的基础⼯具,它可以实现快速计数、查询缓存的功能,同时数
据可以异步处理或者落地到其他数据源。如下视频的播放次数,每次+1就可以使用redis实现。
共享会话
如果每个应用服务器,维护自己的会话数据,此时彼此之间不共享,用户请求访问到不同的服务器上,就可能回出现一些不能正确处理的情况。
为了解决这个问题,可以使⽤ Redis 将⽤⼾的 Session 信息进⾏集中管理。在这种模式下,只要保证 Redis 是⾼可⽤和可扩展性的,⽆论⽤⼾被均衡到哪台 Web 服务器上,都集中从Redis 中查询、更新 Session 信息。
手机验证码
很多应⽤出于安全考虑,会在每次进⾏登录时,让⽤⼾输⼊⼿机号并且配合给⼿机发送验证码,
然后让⽤⼾再次输⼊收到的验证码并进⾏验证,从⽽确定是否是⽤⼾本⼈。为了短信接⼝不会频繁访问,会限制⽤⼾每分钟获取验证码的频率。在设置验证码的过期时间时,可以使用redis的ex过期时间。
以上,关于redis,希望对你有所帮助。