redis默认有16个数据库, 默认使用的是第0个

数据库切换

1
2
3
4
127.0.0.1:6379> select 3 #切换数据库
OK
127.0.0.1:6379[3]> DBSIZE #查看DB大小
(integer) 0

查询当前库的键总数

1
dbsize 

查看当前库的所有key

1
2
3
127.0.0.1:6379[3]> keys *
1) "name"
127.0.0.1:6379[3]>

dbsize 和keys * 的区别

dbsize不会遍历所有键,而是直接获取Redis内置的键总数变量,时间复杂度O(1)
keys命令会遍历所有键,时间复杂度O(n),当Redis里面保存了大量的键时,线上环境禁止使用

删除键

1
del key

清空当前数据库 FLUSHDB

1
2
3
4
5
127.0.0.1:6379[3]> FLUSHDB
OK
127.0.0.1:6379[3]> keys *
(empty array)
127.0.0.1:6379[3]>

清空全部数据库 FLUSHALL

1
2
3
127.0.0.1:6379[3]> FLUSHALL
OK
127.0.0.1:6379[3]>

Redis是单线程的

因为Redis是基于内存的操作,CPU不是Redis的瓶颈,Redis的瓶颈最有可能是机器内存的大小或者网络带宽。既然单线程容易实现,而且CPU不会成为瓶颈,那就顺理成章地采用单线程的方案了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
127.0.0.1:6379[3]> set name aaa #设置值
OK

set命令有几个选项:
ex seconds:为键设置秒级过期时间
px milliseconds :为键设置毫秒级过期时间
nx:键必须不存在,才可以设置成功,添加,相关命令setnx
xx:键必须存在,才可以设置成功,更新相关命令setxx

因为Redis是单线程命令处理机制,如果有多个客户端同时执行setnx,只有一个能设置成功
setnx可以作为分布式锁的一种实现方式

127.0.0.1:6379[3]> keys *
1) "name"
127.0.0.1:6379[3]> move name 1 #移动key到另一个数据库
(integer) 1
127.0.0.1:6379[3]> keys *
(empty array)
127.0.0.1:6379[3]> select 1
OK
127.0.0.1:6379[1]> keys *
1) "name"
127.0.0.1:6379[1]> type name #查看当前key类型
string
127.0.0.1:6379[3]> set name bbb
OK
127.0.0.1:6379[3]> keys *
1) "name"
127.0.0.1:6379[3]> get name #获取值
"bbb"
127.0.0.1:6379[3]> EXPIRE name 10 #设置key有效时间(秒)
(integer) 1
127.0.0.1:6379[3]> ttl name #获取key的有效时间(秒)
(integer) 6
127.0.0.1:6379[3]> ttl name
(integer) 5
127.0.0.1:6379[3]> ttl name
(integer) 4
127.0.0.1:6379[3]> ttl name
(integer) 2
127.0.0.1:6379[3]> ttl name
(integer) 1
127.0.0.1:6379[3]> EXISTS name #查看当前key是否存在
(integer) 0
127.0.0.1:6379[3]> get name
(nil)
127.0.0.1:6379[3]> mset a 1 b 2 c 3 #批量设置值
OK
127.0.0.1:6379[3]> mget a b c #批量获取值
1) "1"
2) "2"
3) "3"

数据结构和内部编码

type命令实际上返回的就是当前键的数据结构类型,他们分别是:

  • string(字符串)
  • hash(哈希)
  • list(列表)
  • set(集合)
  • zset(有序集合)

但是这只是Redis对外的数据结构
实际上每种数据结构都有自己底层内部的编码实现
可以通过object encoding 命令查询内部编码

1
2
3
4
5
6
7
8
127.0.0.1:6379> set hello aaa
OK
127.0.0.1:6379> object encoding hello
"embstr"
127.0.0.1:6379> rpush mylist a
(integer) 1
127.0.0.1:6379> object encoding mylist
"quicklist"
这么设计的好处:
  1. 可以改进内部编码,而对外的数据结构和命令没有影响。
  2. 多种内部编码实现可以在不同场景下发挥各自的优势。

Redis客户端和服务端请求过程

Redis为什么单线程这么快

  1. 纯内存访问
  2. 非阻塞IO,Redis使用epoll作为IO多路复用技术的实现,不在网络上浪费过多的时间
  3. 单线程避免了多线程线程切换和竞争产生的消耗
采用单线程的好处
  1. 简化数据结构算法的实现
  2. 避免了多线程线程切换和竞争产生的消耗