Redis的基本全局命令以及数据类型和内部编码

基本全局命令

Redis提供了5种数据类型,都是键值对的形式,对于键来说有一些通用的命令

KEYS命令

语法:

shell 复制代码
KEYS pattern

功能:返回所有满足样式的key。支持如下统配样式:

  • h?llo :表示可以匹配在?位置为任意一个字符,如hallo/hbllo/hcllo
  • h*llo:表示可以匹配在*位置为任意个字符,如hllo/hello/heeello
  • h[ae]llo:表示可以匹配[]内的任意一个字符,如hello/hallo
  • h[^e]llo:表示可以匹配除了[]内的任意一个字符,如hallo/hbllo
  • h[a-b]llo:表示可以ab内的任意一个字符,如hallo/hbllo

命令有效版本:1.0.0版本以后

时间复杂度:O(N)

返回值:匹配pattern的所有key

演示:

shell 复制代码
127.0.0.1:6379> set hello 1
OK
127.0.0.1:6379> set hbllo 2
OK
127.0.0.1:6379> keys h?llo
1) "hbllo"
2) "hello"
127.0.0.1:6379> keys h[^a]llo
3) "hbllo"
4) "hello"
127.0.0.1:6379> keys h[^b]llo
5) "hello"
127.0.0.1:6379> 

注意:

尽量不要在生产环境 使用命令keys *,这个指令会返回所有的key,如果key很多,redis执行这个命令会消耗比较多的时间,又因为redis为单线程程序,会导致其他功能被迫等待。

EXISTS命令

语法:

shell 复制代码
EXISTS key [key ...]

功能:判断某个key是否存在

时间复杂度:O(1)

返回值:key存在的个数

演示:

shell 复制代码
127.0.0.1:6379> exists hello
(integer) 1
127.0.0.1:6379> exists hello hbllo
(integer) 2
127.0.0.1:6379> 

注意:

exists支持一次性检测多个key是否存在的目的是减少网络通信的次数。

DEL命令

语法:

shell 复制代码
DEL key [key ...]

功能:

删除指定的key

命令有效版本:1.0.0以后

时间复杂度:O(1)

返回值:删除掉的key的个数

演示:

shell 复制代码
127.0.0.1:6379> DEL hello
(integer) 1
127.0.0.1:6379> exists hello
(integer) 0
127.0.0.1:6379> 

EXPIRE命令

语法:

shell 复制代码
EXPIRE key seconds

功能:

为指定的key添加秒级的过期时间

命令有效版本:1.0.0以后

时间复杂度:O(1)

返回值:1表示设置成功。0表示设置失败

演示:

shell 复制代码
127.0.0.1:6379> set example "test"
OK
127.0.0.1:6379> expire example 20
(integer) 1
127.0.0.1:6379> exists example
(integer) 1
127.0.0.1:6379> exists example
(integer) 1
127.0.0.1:6379> exists example
(integer) 0
127.0.0.1:6379> 

TTL命令

语法:

shell 复制代码
TTL key

功能:

获取指定key的过期时间,秒级

命令有效版本:1.0.0以后

时间复杂度:O(1)

返回值:剩余过期时间。-1表示没有关联过期时间,-2表示key不存在

演示:

shell 复制代码
127.0.0.1:6379> set ttl_example "test"
OK
127.0.0.1:6379> expire ttl_example 20
(integer) 1
127.0.0.1:6379> ttl ttl_example
(integer) 13
127.0.0.1:6379> 

注意:

如果你需要更高级别的时间控制,可以使用PEXPIRE和PTTL,这两个指令都支持毫秒级别的控制。

redis的定时器的核心:升序有序的过期字典 + 惰性删除 + 定时删除

TYPE命令

语法:

shell 复制代码
TYPE key

功能:

返回key对应value的数据类型

命令有效版本:1.0.0以后

时间复杂度:O(1)

演示:

shell 复制代码
127.0.0.1:6379> set hello 111
OK
127.0.0.1:6379> type hello
string
127.0.0.1:6379> lpush key1 111 222
(integer) 2
127.0.0.1:6379> type key1
list
127.0.0.1:6379> sadd key2 111 222
(integer) 2
127.0.0.1:6379> type key2
set
127.0.0.1:6379> 

lpush相当于列表插入,sadd相对于集合插入,此处作为了解即可。

小结

  • keys:用于查看匹配规则的key
  • exists:用于检查指定的key是否存在
  • del:删除指定的key
  • expere:给key设置过期时间
  • ttl:检查指定key的过期时间
  • type:查询指定key对应的value的类型

数据类型和内部编码

type命令实际返回的就是当前键的数据类型,他们分别为:string(字符串)list(列表)hash(哈希)set(集合)zset(有序集合)

如下图所示:

实际上这些只是Redis对外表示的数据结构,真实情况是Redis针对每种数据类型都有自己的底层内部编码实现,而且一种数据结构可能对应多种实现,Redis对根据合适的场景选择对应的内部编码。

数据类型 内部编码
string raw
string int
string embstr
hash hashtable
hash ziplist
list linkedlist
list ziplist
set hashtable
set intset
zset skiplist
zset ziplist

从表格中可以看出,每种数据类型都有至少两种及以上的内部编码实现,例如list就包含了linkedlist和ziplist两种内部编码。

在什么情况下会使用对应的内部编码

核心原则:数据量小 / 简单时用「紧凑编码」节省内存,数据量大 / 复杂时用「高效编码」保证读写性能

  • string
    • raw : 存储字符串长度较长
    • int :存储的字符串内容为纯整数且在long long内表示的范围内。
    • embstr :存储的字符串长度较短
  • hash
    • hashtable :存储的键值对数量较大
    • ziplist :存储的键值对数量较小
  • list
    • linkedlist :存储数量较多时
    • ziplist :存储数量较少时
  • set
    • hashtable:存储非整数元素或者存储整数较多
    • intset :存储整数元素且存储整数较少
  • zset
    • skiplist :存储元素较多
    • ziplist :存储元素较少

注意:

  1. 在redis 3.2版本以后 list的内部编码变为quicklist,是ziplist + linkedlist 的结合体

  2. 编码切换是不可逆的:Redis 所有数据类型的内部编码,都只有 「从紧凑编码 → 高效编码」的升级没有降级

如何查看这些内部编码呢

使用 object encoding命令

shell 复制代码
127.0.0.1:6379> set key1 value1
OK
127.0.0.1:6379> lpush mylist a b c
3
127.0.0.1:6379> object encoding key1
embstr
127.0.0.1:6379> object encoding mylist
quicklist
127.0.0.1:6379> 

单线程结构

Redis使用单线程结构来实现高性能的内存数据库服务

为什么Redis使用单线程还这么快

并不是单线程就一定比多线程慢,多线程仅在 CPU 密集型任务和 IO 密集型任务中优势最大,而 Redis 的运行场景完美避开了这两个场景的短板,因此 Redis 单线程依然能做到极致的性能,核心原因有三点:

  • 纯内存访问:Redis 将所有数据放在内存中,内存的响应时间为 100ns 左右,速度远快于磁盘,所有命令都是内存操作,无磁盘 IO 的耗时,这是高性能的基础;

  • 非阻塞 IO:Redis 使用 epoll 作为 IO 多路复用技术的实现,再加上 Redis 自身的事件处理模型,将 epoll 中的连接、读写、关闭等操作都转化为事件统一处理,能高效监听和处理大量客户端连接,不在网络 IO 上浪费过多的时间;

  • 单线程避免了线程切换和竞态的消耗:单线程可以简化数据结构和算法的实现,让程序模型更简单,同时彻底避免了多线程下线程竞争共享资源的切换开销、锁等待开销,也无需处理线程安全问题,最大化节省 CPU 资源。

总结

Redis的基本全局命令包括:KEYS、EXISTS、DEL、EXPIRE、TTL、TYPE

Redis有5种数据类型包括:string(字符串)list(列表)hash(哈希)set(集合)zset(有序集合)。这5种数据类型的底层至少有两种编码实现。

虽然Redsi使用单线程来实现高性能的内存数据库服务,但是由于纯内存访问、非阻塞IO、单线程避免了线程竞争等等优势导致Redis的速度依旧很快。

相关推荐
抠脚学代码2 小时前
Qt与Linux
linux·数据库·qt
xb11322 小时前
WinForms 多窗体应用程序详解
数据库·microsoft·c#
天码-行空2 小时前
达梦数据库(DM8)详细安装教程
linux·运维·数据库
霖霖总总2 小时前
[小技巧36]MySQL 配置参数全解:参数含义、作用域与运维建议
运维·数据库·mysql
是三好2 小时前
Sharding Sphere
数据库·sharding sphere
超级数据查看器2 小时前
超级数据查看器 更新日志(包含的功能)
android·java·数据库·sqlite·安卓
哲霖软件2 小时前
机械设备ERP选型指南:5款产品技术特性与落地要点
运维·数据库
茁壮成长的露露2 小时前
MongoDB分片集群部署
数据库·mongodb
indexsunny2 小时前
互联网大厂Java面试实战:Spring Boot与微服务在电商场景中的应用解析
java·数据库·spring boot·微服务·maven·flyway·电商