Redis简明教程学习笔记
Redis简明教程学习笔记
学习时间:2023年2月27日
学习来源:菜鸟教程
REmote DIctionary Server(Redis) 是一个由 Salvatore Sanfilippo 写的 key-value 存储系统,是跨平台的非关系型数据库(nosql)。
1 安装
环境:Linux
安装步骤:
1 | cd /usr/local |
执行完 make 命令后,redis-7.0.8 的 src 目录下会出现编译后的 redis 服务程序 redis-server
,还有用于测试的客户端程序 redis-cli
:
按照默认配置启动redis:
1 | ./redis-server |
也可以通过启动参数告诉 redis 使用指定配置文件使用下面命令启动:
1 | ./redis-server ../redis.conf |
启动 redis 服务进程后,就可以使用测试客户端程序 redis-cli 和 redis 服务交互了。 比如:
1 | [root@HongyiZeng src]# ./redis-cli |
2 配置
Redis 的配置文件位于 Redis 安装目录下,文件名为 redis.conf
,可以通过 CONFIG
命令查看或设置配置项。
命令格式:
1 | CONFIG GET CONFIG_SETTING_NAME # 查看 |
示例
1 | 127.0.0.1:6379> CONFIG GET loglevel |
配置项含义
序号 | 配置项 | 说明 |
---|---|---|
1 | daemonize no |
Redis 默认不是以守护进程的方式运行,可以通过该配置项修改,使用 yes 启用守护进程(Windows 不支持守护线程的配置为 no ) |
2 | pidfile /var/run/redis.pid |
当 Redis 以守护进程方式运行时,Redis 默认会把 pid 写入 /var/run/redis.pid 文件,可以通过 pidfile 指定 |
3 | port 6379 |
指定 Redis 监听端口,默认端口为 6379,作者在自己的一篇博文中解释了为什么选用 6379 作为默认端口,因为 6379 在手机按键上 MERZ 对应的号码,而 MERZ 取自意大利歌女 Alessia Merz 的名字 |
4 | bind 127.0.0.1 |
绑定的主机地址 |
5 | timeout 300 |
当客户端闲置多长秒后关闭连接,如果指定为 0 ,表示关闭该功能 |
6 | loglevel notice |
指定日志记录级别,Redis 总共支持四个级别:debug、verbose、notice、warning,默认为 notice |
7 | logfile stdout |
日志记录方式,默认为标准输出,如果配置 Redis 为守护进程方式运行,而这里又配置为日志记录方式为标准输出,则日志将会发送给 /dev/null |
8 | databases 16 |
设置数据库的数量,默认数据库为0,可以使用SELECT 命令在连接上指定数据库id |
9 | save <seconds> <changes> |
指定在多长时间内,有多少次更新操作,就将数据同步到数据文件,可以多个条件配合 |
10 | rdbcompression yes |
指定存储至本地数据库时是否压缩数据,默认为 yes,Redis 采用 LZF 压缩,如果为了节省 CPU 时间,可以关闭该选项,但会导致数据库文件变的巨大 |
11 | dbfilename dump.rdb |
指定本地数据库文件名,默认值为 dump.rdb |
12 | dir ./ |
指定本地数据库存放目录 |
13 | slaveof <masterip> <masterport> |
设置当本机为 slave 服务时,设置 master 服务的 IP 地址及端口,在 Redis 启动时,它会自动从 master 进行数据同步 |
14 | masterauth <master-password> |
当 master 服务设置了密码保护时,slave 服务连接 master 的密码 |
15 | requirepass foobared |
设置 Redis 连接密码,如果配置了连接密码,客户端在连接 Redis 时需要通过 AUTH |
16 | maxclients 128 |
设置同一时间最大客户端连接数,默认无限制,Redis 可以同时打开的客户端连接数为 Redis 进程可以打开的最大文件描述符数,如果设置 maxclients 0,表示不作限制。当客户端连接数到达限制时,Redis 会关闭新的连接并向客户端返回 max number of clients reached 错误信息 |
17 | maxmemory <bytes> |
指定 Redis 最大内存限制,Redis 在启动时会把数据加载到内存中,达到最大内存后,Redis 会先尝试清除已到期或即将到期的 Key,当此方法处理 后,仍然到达最大内存设置,将无法再进行写入操作,但仍然可以进行读取操作。Redis 新的 vm 机制,会把 Key 存放内存,Value 会存放在 swap 区 |
18 | appendonly no |
指定是否在每次更新操作后进行日志记录,Redis 在默认情况下是异步的把数据写入磁盘,如果不开启,可能会在断电时导致一段时间内的数据丢失。因为 redis 本身同步数据文件是按上面 save 条件来同步的,所以有的数据会在一段时间内只存在于内存中。默认为 no |
19 | appendfilename appendonly.aof |
指定更新日志文件名,默认为 appendonly.aof |
20 | appendfsync everysec |
指定更新日志条件,共有 3 个可选值:no:表示等操作系统进行数据缓存同步到磁盘(快)always:表示每次更新操作后手动调用 fsync() 将数据写到磁盘(慢,安全)everysec:表示每秒同步一次(折中,默认值) |
21 | vm-enabled no |
指定是否启用虚拟内存机制,默认值为 no,简单的介绍一下,VM 机制将数据分页存放,由 Redis 将访问量较少的页即冷数据 swap 到磁盘上,访问多的页面由磁盘自动换出到内存中(在后面的文章我会仔细分析 Redis 的 VM 机制) |
22 | vm-swap-file /tmp/redis.swap |
虚拟内存文件路径,默认值为 /tmp/redis.swap,不可多个 Redis 实例共享 |
23 | vm-max-memory 0 |
将所有大于 vm-max-memory 的数据存入虚拟内存,无论 vm-max-memory 设置多小,所有索引数据都是内存存储的(Redis 的索引数据 就是 keys),也就是说,当 vm-max-memory 设置为 0 的时候,其实是所有 value 都存在于磁盘。默认值为 0 |
24 | vm-page-size 32 |
Redis swap 文件分成了很多的 page,一个对象可以保存在多个 page 上面,但一个 page 上不能被多个对象共享,vm-page-size 是要根据存储的 数据大小来设定的,作者建议如果存储很多小对象,page 大小最好设置为 32 或者 64bytes;如果存储很大大对象,则可以使用更大的 page,如果不确定,就使用默认值 |
25 | vm-pages 134217728 |
设置 swap 文件中的 page 数量,由于页表(一种表示页面空闲或使用的 bitmap)是在放在内存中的,,在磁盘上每 8 个 pages 将消耗 1byte 的内存。 |
26 | vm-max-threads 4 |
设置访问swap文件的线程数,最好不要超过机器的核数,如果设置为0,那么所有对swap文件的操作都是串行的,可能会造成比较长时间的延迟。默认值为4 |
27 | glueoutputbuf yes |
设置在向客户端应答时,是否把较小的包合并为一个包发送,默认为开启 |
28 | hash-max-zipmap-entries 64 hash-max-zipmap-value 512 |
指定在超过一定的数量或者最大的元素超过某一临界值时,采用一种特殊的哈希算法 |
29 | activerehashing yes |
指定是否激活重置哈希,默认为开启(后面在介绍 Redis 的哈希算法时具体介绍) |
30 | include /path/to/local.conf |
指定包含其它的配置文件,可以在同一主机上多个Redis实例之间使用同一份配置文件,而同时各个实例又拥有自己的特定配置文件 |
3 数据类型
Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。
3.1 字符串
string 是 redis 最基本的类型,你可以理解成与 Memcached 一模一样的类型,一个 key 对应一个 value。
string 类型是二进制安全的。意思是 redis 的 string 可以包含任何数据。比如jpg图片或者序列化的对象。
string 类型是 Redis 最基本的数据类型,string 类型的值最大能存储 512MB。
1 | redis 127.0.0.1:6379> SET runoob "菜鸟教程" |
在以上实例中使用了 SET 和 GET 命令。键为 runoob,对应的值为 菜鸟教程。
3.2 哈希
Redis hash 是一个键值(key=>value)对集合。
Redis hash 是一个 string 类型的 field 和 value 的映射表,hash 特别适合用于存储对象。
1 | redis 127.0.0.1:6379> HMSET runoob field1 "Hello" field2 "World" |
实例中使用了 HMSET, HGET
命令,HMSET
为键runoob
设置了两个 field=>value 对(键值对), HGET
获取对应 field 对应的 value。
3.3 列表
Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。命令LPUSH
。
1 | redis 127.0.0.1:6379> lpush runoob redis |
3.4 集合
Redis 的 Set 是 string 类型的无序集合。
集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。
sadd
命令:添加一个 string 元素到 key 对应的 set 集合中,成功返回 1,如果元素已经在集合中返回 0。
1 | redis 127.0.0.1:6379> sadd runoob redis |
3.5 有序集合
Redis zset 和 set 一样也是string类型元素的集合,且不允许重复的成员。
不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。zset的成员是唯一的,但分数(score)却可以重复。
zadd
命令:添加元素到集合,元素在集合中存在则更新对应score
1 | redis 127.0.0.1:6379> zadd runoob 0 redis |
总结:
类型 | 简介 | 特性 | 场景 |
---|---|---|---|
String(字符串) | 二进制安全 | 可以包含任何数据,比如jpg图片或者序列化的对象,一个键最大能存储512M | — |
Hash(字典) | 键值对集合,即编程语言中的Map类型 | 适合存储对象,并且可以像数据库中update一个属性一样只修改某一项属性值(Memcached中需要取出整个字符串反序列化成对象修改完再序列化存回去) | 存储、读取、修改用户属性 |
List(列表) | 链表(双向链表) | 增删快,提供了操作某一段元素的API | 1,最新消息排行等功能(比如朋友圈的时间线) 2,消息队列 |
Set(集合) | 哈希表实现,元素不重复 | 1、添加、删除,查找的复杂度都是O(1) 2、为集合提供了求交集、并集、差集等操作 | 1、共同好友 2、利用唯一性,统计访问网站的所有独立ip 3、好友推荐时,根据tag求交集,大于某个阈值就可以推荐 |
Sorted Set(有序集合) | 将Set中的元素增加一个权重参数score,元素按score有序排列 | 数据插入集合时,已经进行天然排序 | 1、排行榜 2、带权重的消息队列 |
4 命令
4.1 连接命令
如果需要在远程 redis 服务上执行命令,使用的也是 redis-cli 命令。
1 | $ redis-cli -h host -p port -a password |
例如:
1 | $ redis-cli -h 127.0.0.1 -p 6379 -a "mypass" |
4.2 键命令
Redis 键命令用于管理 redis 的键。
基本语法:
1 | redis 127.0.0.1:6379> COMMAND KEY_NAME |
常用命令:
命令 | 描述 |
---|---|
DEL key |
该命令用于在 key 存在时删除 key。 |
DUMP key |
序列化给定 key ,并返回被序列化的值。 |
EXISTS key |
检查给定 key 是否存在。 |
EXPIRE key seconds |
为给定 key 设置过期时间,以秒计。 |
EXPIREAT key timestamp |
EXPIREAT 的作用和 EXPIRE 类似,都用于为 key 设置过期时间。 不同在于 EXPIREAT 命令接受的时间参数是 UNIX 时间戳(unix timestamp)。 |
MOVE key db |
将当前数据库的 key 移动到给定的数据库 db 当中。 |
PERSIST key |
移除 key 的过期时间,key 将持久保持。 |
PTTL key |
以毫秒为单位返回 key 的剩余的过期时间。 |
TTL key |
以秒为单位,返回给定 key 的剩余生存时间(TTL, time to live)。 |
RENAME key newkey |
修改 key 的名称 |
TYPE key |
返回 key 所储存的值的类型。 |
4.3 字符串命令
Redis 字符串数据类型的相关命令用于管理 redis 字符串值。
命令 | 描述 |
---|---|
SET key value |
设置指定 key 的值。 |
GET key |
获取指定 key 的值。 |
示例:
1 | redis 127.0.0.1:6379> SET runoobkey redis |
4.4 哈希命令
Redis hash 是一个 string 类型的 field(字段) 和 value(值) 的映射表,hash 特别适合用于存储对象。
常用命令:
命令 | 命令及描述 |
---|---|
HDEL key field1 [field2] |
删除一个或多个哈希表字段 |
HEXISTS key field |
查看哈希表 key 中,指定的字段是否存在。 |
HGET key field |
获取存储在哈希表中指定字段的值。 |
HGETALL key |
获取在哈希表中指定 key 的所有字段和值 |
HKEYS key |
获取所有哈希表中的字段 |
HLEN key |
获取哈希表中字段的数量 |
HMGET key field1 [field2] |
获取所有给定字段的值 |
HMSET key field1 value1 [field2 value2] |
同时将多个 field-value (域-值)对设置到哈希表 key 中。 |
HSET key field value |
将哈希表 key 中的字段 field 的值设为 value 。 |
示例:
1 | 127.0.0.1:6379> HMSET runoobkey name "redis tutorial" description "redis basic commands for caching" likes 20 visitors 23000 |
4.5 列表命令
Redis列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)
常用命令:
命令 | 描述 |
---|---|
BLPOP key1 [key2] timeout |
移出并获取列表的第一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。 |
BRPOP key1 [key2] timeout] |
移出并获取列表的最后一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。 |
LLEN key |
获取列表长度 |
LPOP key |
移出并获取列表的第一个元素 |
LPUSH key value1 [value2] |
将一个或多个值插入到列表头部 |
LRANGE key start stop |
获取列表指定范围内的元素 |
RPUSH key value1 [value2] |
在列表中添加一个或多个值到列表尾部 |
示例:
1 | redis 127.0.0.1:6379> LPUSH runoobkey redis |
4.6 集合命令
Redis 的 Set 是 String 类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。
集合对象的编码可以是 intset 或者 hashtable。
Redis 中集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。
常用命令:
命令 | 描述 |
---|---|
SADD key member1 [member2] |
向集合添加一个或多个成员 |
SISMEMBER key member |
判断 member 元素是否是集合 key 的成员 |
SMEMBERS key |
返回集合中的所有成员 |
示例:
1 | redis 127.0.0.1:6379> SADD runoobkey redis |
4.7 有序集合命令
Redis 有序集合和集合一样也是 string 类型元素的集合,且不允许重复的成员。
不同的是每个元素都会关联一个 double 类型的分数。redis 正是通过分数来为集合中的成员进行从小到大的排序。
有序集合的成员是唯一的,但分数(score)却可以重复。
常用命令:
命令 | 描述 |
---|---|
ZADD key score1 member1 [score2 member2] |
向有序集合添加一个或多个成员,或者更新已存在成员的分数 |
ZRANGE key start stop [WITHSCORES] |
通过索引区间返回有序集合指定区间内的成员 |
示例:
1 | redis 127.0.0.1:6379> ZADD runoobkey 1 redis |
4.8 INFO命令
Redis Info 命令以一种易于理解和阅读的格式,返回关于 Redis 服务器的各种信息和统计数值。
通过给定可选的参数 section ,可以让命令只返回某一部分的信息,命令格式:
1 | INFO <section> |
可选参数section
有:
server : 一般 Redis 服务器信息,包含以下域:
- redis_version : Redis 服务器版本
- redis_git_sha1 : Git SHA1
- redis_git_dirty : Git dirty flag
- os : Redis 服务器的宿主操作系统
- arch_bits : 架构(32 或 64 位)
- multiplexing_api : Redis 所使用的事件处理机制
- gcc_version : 编译 Redis 时所使用的 GCC 版本
- process_id : 服务器进程的 PID
- run_id : Redis 服务器的随机标识符(用于 Sentinel 和集群)
- tcp_port : TCP/IP 监听端口
- uptime_in_seconds : 自 Redis 服务器启动以来,经过的秒数
- uptime_in_days : 自 Redis 服务器启动以来,经过的天数
- lru_clock : 以分钟为单位进行自增的时钟,用于 LRU 管理
clients : 已连接客户端信息,包含以下域:
- connected_clients : 已连接客户端的数量(不包括通过从属服务器连接的客户端)
- client_longest_output_list : 当前连接的客户端当中,最长的输出列表
- client_longest_input_buf : 当前连接的客户端当中,最大输入缓存
- blocked_clients : 正在等待阻塞命令(BLPOP、BRPOP、BRPOPLPUSH)的客户端的数量
memory : 内存信息,包含以下域:
- used_memory : 由 Redis 分配器分配的内存总量,以字节(byte)为单位
- used_memory_human : 以人类可读的格式返回 Redis 分配的内存总量
- used_memory_rss : 从操作系统的角度,返回 Redis 已分配的内存总量(俗称常驻集大小)。这个值和 top 、 ps 等命令的输出一致。
- used_memory_peak : Redis 的内存消耗峰值(以字节为单位)
- used_memory_peak_human : 以人类可读的格式返回 Redis 的内存消耗峰值
- used_memory_lua : Lua 引擎所使用的内存大小(以字节为单位)
- mem_fragmentation_ratio : used_memory_rss 和 used_memory 之间的比率
- mem_allocator : 在编译时指定的, Redis 所使用的内存分配器。可以是 libc 、 jemalloc 或者 tcmalloc 。
在理想情况下, used_memory_rss 的值应该只比 used_memory 稍微高一点儿。
当 rss > used ,且两者的值相差较大时,表示存在(内部或外部的)内存碎片。
内存碎片的比率可以通过 mem_fragmentation_ratio 的值看出。
当 used > rss 时,表示 Redis 的部分内存被操作系统换出到交换空间了,在这种情况下,操作可能会产生明显的延迟。
当 Redis 释放内存时,分配器可能会,也可能不会,将内存返还给操作系统。
如果 Redis 释放了内存,却没有将内存返还给操作系统,那么 used_memory 的值可能和操作系统显示的 Redis 内存占用并不一致。
查看 used_memory_peak 的值可以验证这种情况是否发生。
persistence : RDB 和 AOF 的相关信息
stats : 一般统计信息
replication : 主/从复制信息
cpu : CPU 计算量统计信息
commandstats : Redis 命令统计信息
cluster : Redis 集群信息
keyspace : 数据库相关的统计信息
实例
1 | redis 127.0.0.1:6379> INFO |
4.9 发布订阅命令
Redis 发布订阅 (pub/sub) 是一种消息通信模式:发送者 (pub) 发送消息,订阅者 (sub) 接收消息。
Redis 客户端可以订阅任意数量的频道。
序号 | 命令及描述 |
---|---|
1 | PSUBSCRIBE pattern [pattern ...] 订阅一个或多个符合给定模式的频道。 |
2 | PUBSUB subcommand [argument [argument ...]] 查看订阅与发布系统状态。 |
3 | PUBLISH channel [message] 将信息发送到指定的频道。 |
4 | PUNSUBSCRIBE [pattern [pattern ...]] 退订所有给定模式的频道。 |
5 | SUBSCRIBE channel [channel ...] 订阅给定的一个或多个频道的信息。 |
6 | UNSUBSCRIBE channel [channel ...] 指退订给定的频道。 |
PSUBSCRIBE
:订阅一个或多个符合给定模式的频道。返回接收到的消息。每个模式以*
作为匹配符,比如it*
匹配所有以 it 开头的频道( it.news 、 it.blog 、 it.tweets 等等)。news.*
匹配所有以news.
开头的频道( news.it 、 news.global.today 等等),诸如此类。
1 | PSUBSCRIBE pattern [pattern ...] |
1 | redis 127.0.0.1:6379> PSUBSCRIBE mychannel |
PUBSUB
:用于查看订阅与发布系统状态,它由数个不同格式的子命令组成。返回由活跃频道组成的列表。
1 | PUBSUB <subcommand> [argument [argument ...]] |
1 | redis 127.0.0.1:6379> PUBSUB CHANNELS |
PUBLISH
:用于将信息发送到指定的频道。返回接收到信息的订阅者数量。
1 | PUBLISH channel message |
1 | redis 127.0.0.1:6379> PUBLISH mychannel "hello, i m here" |
SUBSCRIBE
:用于订阅给定的一个或多个频道的信息。返回接收到的信息。
1 | SUBSCRIBE channel [channel ...] |
1 | redis 127.0.0.1:6379> SUBSCRIBE mychannel |
UNSUBSCRIBE
:用于退订给定的一个或多个频道的信息。
1 | UNSUBSCRIBE channel [channel ...] |
1 | redis 127.0.0.1:6379> UNSUBSCRIBE mychannel |
4.10 事务命令
序号 | 命令及描述 |
---|---|
1 | DISCARD 取消事务,放弃执行事务块内的所有命令。 |
2 | EXEC 执行所有事务块内的命令。 |
3 | MULTI 标记一个事务块的开始。 |
4 | UNWATCH 取消 WATCH 命令对所有 key 的监视。 |
5 | WATCH key [key ...] 监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。 |