持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第2天,点击查看活动详情
在研究数据结构之前,我们介绍几种Redis的全局命令,并说说数据结构的内部编码实现。
1 全局命令
1.1 查看所有键
我们可以通过keys * 来查看所有的键。
127.0.0.1:6379> set user1 luke
OK
127.0.0.1:6379> set user2 cedric
OK
127.0.0.1:6379> set user3 josh
OK
127.0.0.1:6379> keys *
1) "user2"
2) "user1"
3) "111"
4) "user3"
127.0.0.1:6379>
1.2 查看所有的键总数
使用dbsize命令可以查看所有键的总数,这个命令不会遍历所有的键,而是直接读取了Redis内置的键总数变量
而keys命令会遍历所有的键,当redis保存了大量的数据时,禁用。
127.0.0.1:6379> dbsize
(integer) 4
1.3 检查键是否存在
exists key这个命令会返回键是否存在,存在返回1,不存在返回0
127.0.0.1:6379> EXISTS user1
(integer) 1
127.0.0.1:6379> EXISTS user4
(integer) 0
1.4 删除键
del key 这个命令不管key的value是什么样的数据,都会删除键以及对应的value
127.0.0.1:6379> del user1
(integer) 1
127.0.0.1:6379> EXISTS user1
(integer) 0
同时也支持删除多个键
127.0.0.1:6379> del user2 user3
(integer) 2
1.5 键过期
expire key seconds这个命令可以给键添加过期时间,当时间到了之后,会主动删除键以及value。
127.0.0.1:6379> set luke student
OK
127.0.0.1:6379> expire luke 20
(integer) 1
ttl key可以查看键剩余时间
127.0.0.1:6379> ttl luke
(integer) 15
当时间到了之后,键会被删除
127.0.0.1:6379> EXISTS luke
(integer) 0
ttl key还可能返回-1和-2,当返回-1时,表示这个key尚未设置过期时间。当返回-2时,表示已经过期删除了。
127.0.0.1:6379> ttl luke
(integer) -2
1.6 键的数据结构类型
type key命令可以查看键对哦应value的数据类型,分别是string 字符串,hash 哈希,list 列表, set 集合,zset 有序集合
127.0.0.1:6379> set luke student
OK
127.0.0.1:6379> TYPE luke
string
127.0.0.1:6379> rpush mylist a s d f g h
(integer) 6
127.0.0.1:6379> TYPE mylist
list
2 数据结构
虽然redis对外的数据结构只有5种,但其实每种数据结构都有自己的内部编码实现,并且不只一种,redis会适时切换内部编码而使用最适合的编码实现。如下图所示,每个数据结构都有多种实现。
可以使用object encoding key查看内部编码
127.0.0.1:6379> OBJECT encoding luke
"embstr"
127.0.0.1:6379> OBJECT encoding mylist
"quicklist"
quick list是3.2新增的数据类型,他结合了ziplist和linkedlist两者的优势。
3 单线程模型的好处
再来说一说单线程模型的好处吧
由于redis是单线程模型,当有命令到达redis的时候,是不会立即执行的,而是进入到一个命令队列中,在这个队列中的命令会逐一被执行。
当有多个客户端的时候,命令的顺序是不被保证的,但不会并发是可以保证的。当多个客户端进行加减数据的时候,最后的结果一定是我们想要的。同时redis使用了I/O的多路复用来解决I/O的问题。
但是单线程还这么快,是不是有点匪夷所思? 原因有3
- 第一肯定是内存型数据库,纯内存访问,内存的响应时间是极快的。
- 第二则是非阻塞I/O,redis使用epoll作为I/O多路复用技术的实现。redis自身的事件处理模型会把epoll中的连接,读写,关闭都转换为事件,不会在网络I/O上浪费过多的时间。
- 第三则是单线程不会引起线程的争抢,不会在线程争抢和线程间切换浪费时间。