目录
一、redis常用的全局命令
对于键来说Redis的5种数据结构有一些通用的命令
1.查看所有键:keys * (不建议使用,redis单线程模式会造成堵塞)
将所有的键输出keys命令 会遍历所有键,所以它的时间复杂度是O(n),当Redis保存了大量键 时,线上环境禁止使用。
2.查看键总数:dbsize
将返回当前数据库中键的总数,不会遍历所有键,而是直接获取Redis内置的键总数变量,所以dbsize命令的时间复杂度是O(1)
3.检查键是否存在:exists key
键存在则返回1,不存在则返回0
4.删除键:del key [key ...]
返回结果为成功删除键的个数,支持一条命令删除多个,删除不存在的键就会返 回0
5.键设置过期时间:expire key seconds
超过过期时间后,会自动删除 键,例如为键hello设置了10秒过期时间,十秒之后自动删除:
> set hello world #设置键
> expire hello 10 #给键添加过期时间
6.查看键剩余过期时间:ttl key
返回键的剩余过期时间,三种返回值类型:
·大于等于0的整数:键剩余的过期时间
·-1:键没设置过期时间
·-2:键不存在
7.键的数据结构类型:type key
如果键不存在,则返回none,存在返回键的数据结构类型,五种数据结构的其中一种
在文章开头我们简单讲键的几个通用命令,在下面文章里我们将会按照单个键、遍历键、数据库管理三个维度对剩余的一些通用命令进行介绍。
二、Redis数据结构对应的内部编码以及使用场景
1.五种数据结构类型
string(字符串)、hash(哈希)、list(列表)、set(集合)、zset(有序集合)
2.五种数据结构对应的内部编码
type命令查询键的数据类型实际返回的是当前键对外的数据结构类型:string(字符串)、hash(哈希)、list(列表)、set(集合)、zset(有 序集合),实际上每种数据结构都有自己底层的内部编码实现,而且是多种实现;
Redis会在合适的场景选择合适的内部编码,每种数据结构都有两种以上的内部编码实现,同时有些内部编码,例如 ziplist,可以作为多种外部数据结构的内部实现,可以通过object encoding命令查询键的内部编码:object encoding key;
Redis这样设计有两个好处:
- 1、当redis改进内部编码进行内部编码的升级时,对外的数据结构和命令是没有影响的,对外部用户来说基本是无感知的;
- 2、多种内部编码实现可以在不同场景下发挥各自的优势,例如ziplist比较节省内存,但是在列表元素比较多的情况下,性能会有所下降,这时候Redis会根据配置选项将 列表类型的内部实现转换为linkedlist
3.五种数据结构常见的使用场景
string(字符串):缓存功能、计数、共享Session、限速
hash(哈希):存储用户信息(数据库)
list(列表):消息队列、文章列表(分页查询)
set(集合):标签、社交
zset(有序集合):排行榜系统、社交
三、Redis的单线程架构
Redis使用了单线程架构和I/O多路复用模型来实现高性能的内存数据库服务
1.redis的命令执行流程
因为Redis是单线程来处理命令的,所以一条命令从客户端达到服务端不会立刻被执行,所有命令都会进入一 个队列中,然后逐个被执行。
命令执行流程:
所以上面3个客户端命令的执行顺序是不确定的,但是可以确定不会有两条命令被同时执行 ;所以两条incr命令无论怎么执行最终结果都是2,不会产生并发问题,这就是Redis单线程的基本模型。
2.redis的单线程如何做到快速响应的
redis单线程还能这么快的原因总结以下三点:
第一,纯内存访问,Redis将所有数据放在内存中,内存的响应时 长大约为100纳秒,这是Redis达到每秒万级别访问的重要基础。
第二,非阻塞I/O,Redis使用epoll作为I/O多路复用技术的实现,再 加上Redis自身的事件处理模型将epoll中的连接、读写、关闭都转换为 事件,不在网络I/O上浪费过多的时间
第三,单线程避免了线程切换和竞态产生的消耗
- 单线程可以简化数据结构和算法的实现;
- 单线程避免了线程切换和竞态产生的消耗,对于服务端开发来说,锁和线程切换通常是性能杀手;但是单线程会有一个问题:对于每个命令的执行时间是有要求的。 如果某个命令执行过长,会造成其他命令的阻塞,对于Redis这种高性 能的服务来说是致命的,所以Redis是面向快速执行场景的数据库。
四、string(字符串)类型
字符串类型是Redis最基础的数据结构,redis中键都是字符串类型;字符串类型的值实际可以是字符串(简单的字符串、复杂的字符串(例如JSON、 XML))、数字(整数、浮点数),甚至是二进制(图片、音频、视 频),但是值最大不能超过512MB。
1.常用命令
设置值:set key value [ex seconds] [px milliseconds] [nx|xx]
·ex seconds:为键设置秒级过期时间。
·px milliseconds:为键设置毫秒级过期时间。
·nx:键必须不存在,才可以设置成功,用于添加。
·xx:与nx相反,键必须存在,才可以设置成功,用于更新。
Redis还提供了setex和setnx两个命令,它们的作用和ex和nx选项是一样的;
在实际使用中有什么应用场景吗?以setnx命令为例 子,由于Redis的单线程命令处理机制,如果有多个客户端同时执行 setnx key value,根据setnx的特性只有一个客户端能设置成功,setnx可 以作为分布式锁的一种实现方案,Redis官方给出了使用setnx实现分布 式锁的方法:http://redis.io/topics/distlock 。
获取值:get key
如果要获取的键不存在,则返回nil(空)
批量设置值:mset key value [key value ...]
> mset a 1 b 2 c 3 d 4
批量获取值:mget key [key ...]
> mget a b c d
如果有些键不存在,那么它的值为nil(空)
计数:incr key
incr命令用于对值做自增操作,返回结果分为三种情况:
·值不是整数,返回错误。
·值是整数,返回自增后的结果。
·键不存在,按照值为0自增,返回结果为1。
Redis提供了decr(自减)、incrby(自增指定数字)、decrby(自减指定数字)、incrbyfloat(自增浮点数):
decr key
incrby key increment
decrby key decrement
incrbyfloat key increment
追加值:append key value
字符串长度:strlen key(每个中文占用3个字节)
设置并返回原值:getset key value(set一样会设置值,但是它同时会返回键原来的值)
设置指定位置的字符:setrange key offeset value
获取部分字符串:getrange key start end
各命令的时间复杂度:
2.批量处理命令的优点
批量操作命令可以有效提高开发效率,假如没有mget这样的命令, 要执行n次get命令需要按照下图的方式来执行:
使用mget命令后,要执行n次get命令操作方式: