目录
[一、Redis 的基本特点](#一、Redis 的基本特点)
[3、 功能丰富](#3、 功能丰富)
[4、 支持集群](#4、 支持集群)
[二、Redis 的典型应用场景](#二、Redis 的典型应用场景)
[1、运行 Redis 服务端 + 查看运行信息](#1、运行 Redis 服务端 + 查看运行信息)
[2、手动关闭 Redis 服务端](#2、手动关闭 Redis 服务端)
[3、 启动 Redis 客户端](#3、 启动 Redis 客户端)
[6、查询某个 Key 是否存在:exists](#6、查询某个 Key 是否存在:exists)
[7、删除某个指定 Key:del](#7、删除某个指定 Key:del)
[8、设置指定键值对的过期时间:expire / pexpire](#8、设置指定键值对的过期时间:expire / pexpire)
[9、获取指定键值对的剩余过期时间 :TTL(time to live)/ PTTL](#9、获取指定键值对的剩余过期时间 :TTL(time to live)/ PTTL)
[10、查询某个 key 对应的 value 的数据类型:type](#10、查询某个 key 对应的 value 的数据类型:type)
[四、redis 的过期策略(重要)](#四、redis 的过期策略(重要))
Redis 是一种在内存中存储数据 的数据库,主要用于分布式系统,只是单机程序,直接通过变量存储数据即可。
Redis 就是基于网络,可以把自己内存中的变量交给别的进程甚至别的主机的进程来使用。当我们想让多个服务器共享数据,又想把数据保存在内存中时,就可以使用 Redis。
Redis 的初心是为了作为"消息中间件"(消息队列)的,但是现在,大部分 Redis 的用途都是作为数据库和缓存而存在。
一、Redis 的基本特点
1、速度快(但空间有限)
1、Redis 由于是在内存中存储数据的,所以相比于数据储存在硬盘上的MySQL,访问速度要快很多。
2、从网络的角度,Redis 使用了 IO 多路复用 epoll 模式,让单个线程,管理多个套接字上的事件。
3、Redis 使用的是单线程模型,减少了不必要的线程竞争开销。(更高版本的 Redis 引入了多线程,但很多时候还是单线程。因为多线程一般是在处理 CPU 密集型任务时可以高效利用 CPU 核数提高效率,而 redis 核心任务是操作内存中的数据结构,不是很吃 CPU)
2、储存键值对的"非关系型数据库"
相比于以表为核心存储的关系型数据库(MySQL等),Redis 是主要是通过"键值对"来存储组织数据的。
3、 功能丰富
1、Redis 可以直接通过简单的交互命令进行操作,也可以通过脚本的方式批量执行一些操作。
2、可以使用C、C++、Rust 这几个高级编程语言来编写 Redis 扩展***(本质就是动态链接库)***
4、 支持集群
Redis 作为分布式系统中的一个中间件,支持水平扩展和集群。
由于内存空间有限,一个 Redis 能储存的数据也是有限的,所以可以引入多个主机,部署多个 Redis 节点,每个 Redis 储存数据的一部分。
5、支持持久化
Redis 由于是把数据存储在内存上的,但是内存上的数据是容易丢失的,一般进程退出 / 系统重启,都会导致数据的丢失。
所以,Redis 支持把数据持久化存储在硬盘上,相当于把内存中的数据进行备份,如果 Redis 重启了,就会在重启的时候把硬盘中的备份数据进行加载,使 Redis 的内存数据恢复到重启前的状态。
有 RDB | AOF 两种模式
6、主从复制架构
从服务器相当于主服务器的备份
二、Redis 的典型应用场景
1、作为存储热点数据的缓存
Redis 由于其存储空间小,速度快的特点,大部分情况下都用来作为储存常用的热点数据的缓存。
(一般和储存在硬盘上的 MySQL 搭配使用;全量数据储存在 MySQL 上,Redis 储存部分热点数据,这样即使 Redis 数据丢失,也可以从 MySQL 上加载回来)
2、作为消息队列服务器
Redis 的初心是为了作为"消息中间件"(消息队列)的,即基于实现一个网络版本的生产者消费者模型,但是现在,大部分 Redis 的用途都是作为数据库和缓存而存在的。
3、作为把数据存储在内存中的数据库
Redis 某些时候也可以作为数据库,速度很快,但是容易丢失,要注意持久化问题。
三、常用全局命令
笔者常用的 CentOS 7 下的 Redis 5,所以这里大部分命令都是基于 Redis 5 介绍。
前言:
Redis 是基于 [key, value] 键值对的,其中key 类型固定为字符串,而 value 有多种类型(后面会进行介绍,常用的有五种),操作不同类型的数据,有不同的命令。
而有些命令是可以搭配任意一种数据结构使用的,这样的命令就称作全局命令。
Redis 是基于客户端-服务端交互方式实现的,所以一般是把服务端进程作为守护进程,然后运行客户端来进行操作。
1、运行 Redis 服务端 + 查看运行信息
bash
# 启动 redis 服务端进程
redis-server /etc/redis/redis.conf
启动服务端后,会在后端变为守护进程(即使终端关闭,只要服务器不关闭 / 不手动关闭它,其会一直存在),可以通过 ps / netstat 查看其具体信息(二者皆可)
bash
# 主要用于查看 Redis 进程的状态,如 CPU 和内存使用情况、启动参数
ps aux | grep redis | grep grep
# 主要用于查看 Redis 的网络连接状态,如它监听的端口、是否有活动连接、连接的来源和目标等
[sudo] netstat -anp | grep redis
都可以查到
2、手动关闭 Redis 服务端
先查询到 Redis 服务端的进程ID,然后直接用 kill 命令即可删除***(在对 Redis 的配置文件进行修改后,一般需要重启 Redis 服务端)***
3、 启动 Redis 客户端
bash
# 启动 Redis 客户端,即可输入命令
redis-cli
即可像 MySQL 一样输入命令了
4、最核心的两个命令:存取键值对
因为 Redis 是按照键值对来存储的,所以最核心的命令就是存取键值对。
bash
# 把 key 和 value 存进去
#(key 和 value 都是字符串,不用加引号就表示字符串;当然加引号亦可,单双引号都可以)
set key value
# 根据 key 来取 value
get key
值得注意的是,redis 中的 value 有五种类型,这里的 set 只是用来存放 string 类型的 value。其它类型,有其它的插入方式。
get 和 set 大小写均可。
当键值对不存在时,会返回 nil,与 NULL 类似
5、筛选字符串命令:keys
keys 命令主要用来查询当前服务器上匹配的 key ,可以通过一些特殊符号(通配符)来描述 key,匹配出符合这些特殊符号的 key。
下面介绍这些通配符:
? :匹配任意一个字符
* :匹配1个 / 任意个字符
[字符字符] :从给出的这几个字符中选择一个,即只匹配这些字符***(eg:[ae],即只匹配 a 和 e 两个字符的 key )***
[^字符]:排除错误答案,给出的字符不匹配。(eg:[^e],排除 e 字符)**
[字符-字符] : 闭区间筛选字符。(eg:[a-e],即只匹配 a-e 中的字符)
bash
keys 包含特殊通配符的字符串
使用实例
PS:由于 keys 需要遍历所有键值对,时间复杂度是 O(N) ,因为时间复杂度较高,不适合去在真实生产环境中使用,会导致以单线程为基础的 redis 阻塞。尤其是 keys* (查询所有 key)
6、查询某个 Key 是否存在:exists
bash
# 可以查询一个 key,也可以查询多个 key,多个 key 之间由空格间隔
exists key1 [key2 key3......]
因为 redis 本身是以哈希表来组织键值对的,所以查询某个 Key 是否存在的时间复杂度是查询几个key,时间复杂度就是几。
exists 的返回值是存在的 Key 的个数。 (在查询多个 key 是否存在的时候比较有用)
查询范例
值得一提的是,由于redis 是基于网络的服务器-客户端通信,所以分开查询相较于合并查询,会增加更多的网络通信轮次,会降低效率提高成本。(因此,redis 的很多命令实际上都是支持一次性操作多个 Key 的,redis 也建议我们这样做)
7、删除某个指定 Key:del
bash
# 同样可以删除一个 / 多个 key,用空格间隔
del key1 [key2 key3]
del 的时间复杂度同样是 O(1),返回的是删掉的 Key 的个数。
使用实例
由于 MySQL 存储的是全量数据,Redis 存储的大部分是热点数据缓存,所以相较于 MySQL,Redis 的删除操作,危险系数要小很多。
(删除少量 Redis 问题不大,但是不建议删除大量 Redis 数据,因为 Redis 毕竟是为了辅助 MySQL 而存在的,其速度比较快;如果 Redis 中数据被大量删除,许多请求都会转移至 MySQL,容易导致 MySQL 服务器崩溃)
8、设置指定键值对的过期时间:expire / pexpire
bash
expire/pexpire key名 秒数/毫秒数
expire / pexpire 命令用来为指定的 key 添加过期时间***(expire 添加的是秒级别的,pexpire 添加的是毫秒级别的,二者使用方式是一致的)***
所谓过期时间 ,就是这个 key 对应的键值对在超过指定的过期时间后,会被自动删除。
(使用举例:手机验证码 / 基于 redis 实现的分布式锁,为了避免不能正确解锁,加个过期时间)
expire / pexpire 的时间复杂度都是O(1)的,返回值 1 表示成功,0 表示失败。(指定的 key 必须存在,否则会失败)
使用实例
9、获取指定键值对的剩余过期时间 :TTL(time to live)/ PTTL
bash
ttl / pttl key名
当我们需要查询某个键值对的过期时间还剩下多少秒 / 毫秒时,便可以使用 ttl / pttl 命令*(分别查询的单位是秒和毫秒)*
TTL / PTTL 的时间复杂度同样是O(1),返回值是剩余的过期时间;如果返回 -1 表示这个键值对没有设置过期时间,返回 -2 则说明这个键值对不存在。
使用实例
10、查询某个 key 对应的 value 的数据类型:type
bash
type key名
因为 value 有多种数据结构,每一种数据类型有着自己的操作方式,因此我们在使用时,可以先试用 type 查询一下其类型,然后用对应的类型操作方式。
type 的时间复杂度也是 O(1),返回值有 none, string, list, set, zset, hash 和 stream*(stream 是 redis 作为消息队列时,value 的数据类型)*
11、常用全局命令总结
1、运行 redis 服务器: redis-server /etc/redis/redis.conf
2、运行 redis 客户端: redis-cli
3、存字符串类型键值对:set key value
4、获取键值对信息:get key
5、筛选字符串:keys
6、查询某个键值对是否存在:exists
7、删除某个键值对:del
8、设置键值对过期时间:expire / pexpire
9、获取指定键值对剩余过期时间:ttl / pttl
10、查询某个 key 对应的 value 的数据类型:type
四、redis 的过期策略(重要)
一个 redis 服务器中,可能存在许多键值对,这些键值对有可能有很大一部分都规定了过期时间。那么 redis 服务器一定要制定一些过期策略来知道哪些键值对过期了需要被删除,哪些没有过期。
redis 主要是通过 惰性删除+定期删除 两项过期策略结合执行的。
1、定期删除
定期删除策略,就是 redis 会每次抽取一部分键值对,验证这些键值对的过期时间。
(这个抽取检查的过程必须要足够快,因为 redis 是单线程程序,如果抽取检查的速度太慢,正常的处理数据请求就会被阻塞)
2、惰性删除
如果某个键值对已经到了过期时间,redis 并不会立刻删除它,而是当某次访问访问到这个键值对的时候,redis 才会触发删除操作,同时返回 nil。
当然,即使这两种策略相结合,其实效果也比较一般,仍然可能会有很多过期的键值对残留,因此 redis 还提供了内存淘汰机制。