Redis使用教程与指令解析 | 青训营

84 阅读7分钟

Redis

Redis(Remote Dictionary Server)是一个开源的内存数据存储系统,也可以被看作是一个键值(key-value)存储数据库。它支持多种数据结构,如字符串(String)、哈希(Hash)、列表(List)、集合(Set)、有序集合(Sorted Set)等,并且提供了丰富的操作命令。另外,出于码字方便以及redis指令均为小写等原因,下文中Redis均写作redis,不喜勿喷。

redis基本理解和工作原理

redis可以一个特殊的数据库,它运行在内存之中,只有两个字段:键和值。其中的值可以是多种数据类型。

redis和数据库一样,都需要配置访问权限,默认的访问权限为本地主机,即127.0.0.1,默认端口是6379。

redis工作原理

  • AOF文件(Append-Only File):用于实现数据的持久化,包含一系列的Redis命令,每个命令都以一种特定的格式写入到文件中,这些命令表示了Redis服务器接收到的写操作,新的命令会不断地追加到文件末尾。当服务器崩溃时,就可以重放AOF文件恢复数据。
  • RDB文件(Redis Database):将数据库某个时间节点的状态保存到一个二进制文件中,相当于备份。如果服务器崩溃,在最后一次生成 RDB 文件和崩溃之间的数据可能会丢失。这时候就需要AOF文件来进一步保护和恢复数据。

看完上述两个持久化的方法之后,我相信善于思考的你对redis持久化已经有了初步的想法了。其基本工作流程基本如下:

在每一次的写操作中,往AOF文件添加操作记录,当保存了RDB文件之后,就及时清除AOF文件,防止其文件体积过大。当发生崩溃的时候,先加载RDB文件,然后重现AOF文件,最终恢复redis。这个过程就好像数据库的恢复系统,可以比较记忆。

配置,启动,操作,关闭redis

redis配置

  • 控制访问权限:在配置文件中修改bind属性,一般来说配置文件位于/etc/redis.conf
  • redis也可以设置账号密码,在Redis配置文件中,找到并编辑requirepass属性。如果该属性被注释掉了(以#开头),需要取消注释,并在等号后面设置一个密码。例如,可以设置requirepass mypassword,其中mypassword是你想要设置的密码。

redis启动

三种方法:默认配置,运行配置,配置文件启动(推荐使用配置文件使用

redis-server /etc/redis.conf

redis操作

可以使用redis-cli连接服务器,有如下两种方法:交互式和命令式。

  • 交互式:
redis-cli -h 127.0.0.1 -p 6379
>set hello world
OK
>get hello
"world"
  • 命令式:
redis-cli -h 127.0.0.1 -p 6379 get hello
"world"

如果缺省了-h和-p两个参数,那么默认是链接127.0.0.1:6379。

redis选择数据库

使用SELECT <index>可以选择某个特定的数据库。redis共有16个数据库可以使用,默认使用DB 0工作。

127.0.0.1:6379> select 1
OK
127.0.0.1:6379[1]> keys *
(empty list or set)

redis关闭

redis-cli shutdown

redis关闭的过程:断开客户端连接,持久化文件生成。这要求我们自己生成持久化文件,redis并不会自动做这件事。这种情况是特殊情况主动关闭redis的操作,就好像关机之前需要保存工作区一样。

redis使用

查看所有键

127.0.0.1:6379> keys *
1) "backup2"
2) "backup3"
3) "backup4"
4) "backup1"

键总数

127.0.0.1:6379> dbsize
(integer) 4

检查键是否存在

exists [keys],如果键存在则返回1,否则返回0。

127.0.0.1:6379> exists backup1
(integer) 1
127.0.0.1:6379> exists backup1 backup5
(integer) 1
127.0.0.1:6379> exists backup1 backup2
(integer) 2

可以检查多个键,但是返回值是一个整数,表示查询的键中存在的个数。

删除键

del [keys]

返回值是成功删除的键的个数,如果删除失败,返回0,否则返回1。使用的语法和返回结果与上述的exists类似,不加赘述。

键过期

redis支持使用expire key seconds对键添加过期时间,当超过过期时间后,会自动删除该键:

127.0.0.1:6379> set hello world
OK
127.0.0.1:6379> expire hello 20
(integer) 1
127.0.0.1:6379> ttl hello
(integer) 14

使用ttl指令可以查看键的剩余时间。

键的数据结构类型和具体操作

前面说过,一个值的数据类型只有五种:string,hash,list,set,zset(有序集合)。下面是这五种数据类型的插入示例:

  • 字符串string:
SET username "Veni"127.0.0.1:6379> GET username
"Veni"
  • 哈希hash:
HMSET user222 username "Veni" age 20127.0.0.1:6379> HGETALL user222
1) "username"
2) "Veni"
3) "age"
4) "20"127.0.0.1:6379> HGET user222 username
"Veni"

查询哈希需要使用HGET指令,指令格式为HGET key field获取特定key的某个字段的值。使用HGETALL key可以获取某个key的所有字段。

  • 列表list:分为左插入和右插入,rpush是在数组的右侧追加,lpush为左侧追加,比如abc使用rpush就是[a b c],而使用lpush结果是[c b a]。
rpush rlist a b c
lpush llist a b c
​
127.0.0.1:6379> LRANGE rlist 0 -1
1) "a"
2) "b"
3) "c"127.0.0.1:6379> LRANGE llist 0 -1
1) "c"
2) "b"
3) "a"

使用LRANGE可以查询list的元素,0到-1表示查询所有值。修改区间起点和区间终点即可查询到不同的值。

  • 集合set
SADD userset "veni" "moss"127.0.0.1:6379> SMEMBERS userset
1) "moss"
2) "veni"127.0.0.1:6379> SISMEMBER userset "veni"
(integer) 1

使用SMEMBERS可以查看集合中的所有成员,使用SISMEMBER可以查看某一个元素是否在集合里面。

  • 有序集合zset:
ZADD userScore 650 "veni" 625 "moss" 610 "neil"127.0.0.1:6379> ZRANGE userScore 0 -1
1) "neil"
2) "moss"
3) "veni"127.0.0.1:6379> ZSCORE userScore moss
"625"127.0.0.1:6379> ZREVRANGE userScore 0 -1
1) "veni"
2) "moss"
3) "neil"

使用ZRANGE查看有序集合里面的特定一批元素的名称,使用ZSCORE可以某个指定的元素的分数,ZREVRANGE按照分数从大到小列出元素名字。

  • 查询key的类型:使用type指令可以查看某一个key的类型。
127.0.0.1:6379> type userScore
zset

数据结构的编码方式

在redis中,每种数据结构都有多种编码方式。Redis 会根据数据大小、类型以及具体的操作情况来自动选择和转换编码方式,以达到最佳的内存使用和性能效果。一旦有了更高效的编码方式,就可以直接修改内部编码,无需修改外部代码。

  1. 字符串(String)

    • raw:简单字符串的默认编码,适用于存储一般文本数据。
    • int:整数编码,用于存储整数类型数据。
    • embstr:短字符串编码,用于存储较短的字符串数据。
    • ht:哈希表编码,用于存储较大的字符串数据。
  2. 列表(List)

    • ziplist:紧凑列表编码,适用于较小的列表。
    • linkedlist:双向链表编码,适用于较大的列表。
  3. 哈希(Hash)

    • ziplist:紧凑哈希编码,适用于较小的哈希。
    • hashtable:哈希表编码,用于较大的哈希。
  4. 集合(Set)

    • intset:整数集合编码,适用于存储整数类型数据。
    • hashtable:哈希表编码,用于较大的集合。
  5. 有序集合(Sorted Set)

    • ziplist:紧凑有序集合编码,适用于较小的有序集合。
    • skiplist:跳跃表编码,用于较大的有序集合。

单线程架构

当第一次看到redis是单线程架构的时候我惊呆了,但是redis的单线程并没有影响他的高性能。实际上,redis内部使用了多线程来处理不同的任务。redis是单线程这是因为redis的核心是一个事件循环,这个单线程循环处理所有客户端请求,数据读写,命令解析等任务。redis的单线程架构使用非阻塞I/O模型,使用任务切换处理事件循环中的不同任务,使用多路复用技术监听不同的socket。