Redis是什么?
Redis (Remote Dictionary Server),即远程字典服务。是一个用C语言开发的开源的、高性能的、基于键值对的缓存与存储系统。
Redis能用来做什么?
可以用作缓存数据,也可以用作数据库,亦可以用作消息队列,等等。取决于使用redis要解决的具体问题:简单系统简单用;复杂系统复杂用。
为什么使用Redis?
Redis是将数据保存在内存中,从内存中读取数据的。从内存中读取数据要比从磁盘IO读取数据要快得多,所以使用Redis能提升应用系统的性;
Redis支持持久化,即将内存中的数据保存到磁盘中,可以避免数据的丢失;
Redis支持多种数据类型,可以存储丰富的数据类型;
Redis支持集群,可以扩展系统,使我们开发出高可用、易扩展的分布式系统;
······
Redis可以解决许多复杂应用系统遇到的问题。总之Redis可以解决许多问题。
Redis版本
Redis约定次版本号(即第一个小数点后的数字)为偶数的版本是稳定版(如2.8版、5.0版),奇数版本为非稳定版本(如2.7版、5.1版),生产环境下一般需要使用稳定版本。
安装Redis
-- 下载redis压缩包
> wget http://download.redis.io/releases/redis-5.0.5.tar.gz
-- 解压缩
> tar xzf redis-5.0.5.tar.gz
-- 进入解压目录
> cd redis-5.0.5
-- 编译
> make
-- 安装redis
> cd src
> make install
这里只简单介绍在Linux系统中安装redis。Window系统安装redis比较简单,下载.exe可执行文件双击按步骤安装即可。
想要使用redis,就必须启动它。我们已经安装好了redis,就需要将redis启动,以作为一个服务端的进程(或者叫做服务)运行起来。运行起来很简单。
-- 进入redis安装目录
> cd [你的redis的安装目录]
-- 启动redis服务,src是redis安装目录下的一个文件夹,里面是一些redis可执行的文件,redis-server就是其中的一个,代表redis服务。另一个常用的是redis-cli,代表redis命令行客户端。
> src/redis-server
redis可执行文件说明
| 文件名 | 说明 |
|---|---|
| redis-server | redis服务 |
| redis-cli | redis命令行客户端 |
| redis-benchmark | redis性能测试工具 |
| redis-check-aof | AOF文件修复工具 |
| redis-check-dump | RDB文件检查工具 |
| redis-sentinel | Sentinel哨兵服务 |
-- 连接redis服务
> redis-cli -h 127.0.0.1 -p 6379
-- 测试redis客户端与redis连接是否正常
> redis-cli PING
PONG
命令返回值
Redis命令的返回值有5种类型。对于每种类型,在redis-cli的展现结果都是不同的。
|返回值类型|英文|解释|例子|
|---|---|---|---|
|状态回复|status reply|最简单的一种回复类型,直接显示状态信息|redis> PING
PONG
redis> SET k1 v1
OK|
|错误回复|error reply|当出现命令不存在或者格式有错误等情况时,redis会返回错误回复。错误回复以(error)开头,并在后面跟上错误信息。(2.8版以后,部分错误信息会以具体的错误类型开头)|redis> ERRORCOMMAND
(error)ERR unknown command|
|整数回复|integer reply|整数回复以(integer)开头,并在后面跟上整数数据|redis> INCR k1
(integer) 1|
|字符串回复|bulk reply|最常见的一种回复类型。当请求一个字符串类型键的键值或一个其他类型键中的某个元素时就会得到一个字符串回复。字符串回复以双引号包裹。 特殊情况是当请求的键值不存在时会得到一个空结果,显示为(nil)。|redis> GET k1
"1"|
|多行字符串回复|multi-bulk reply|很常见的一种回复类型。多行字符串回复中的每行字符串都以一个序号开头|redis> KEYS *
1) "bar"
2) "foo"|
了解redis命令的返回值类型,可以帮助我们根据返回值类型做后续的业务判断和操作。另外,在redis执行lua脚本时,只有知道了redis命令的返回值类型,才能写出正确的脚本函数。
数据类型
Redis支持多种数据类型,常见的五种数据类型:字符串、哈希散列、列表、集合、有序集合。其他类型:位数组(Bit arrays)、超级日志(HyperLogLogs)、流(Streams)
| 数据类型 | 英文 | 简要说明 |
|---|---|---|
| 字符串类型 | String type | 字符串类型是redis中最基本的数据类型,它能存储任何形式的字符串,包括二进制数据。一个字符串类型的键允许存储的数据的最大容量是512MB。 字符串类型是其他4种数据类型的基础,其他数据类型和字符串类型的差别从某种角度来说只是组织字符串的形式不同。 |
| 散列类型 | Hash type | 散列类型的键值是字典结构的,其中存储了字段和字段值的映射。一个散列类型的键可以最多包含223-1个字段。 散列类型适合存储对象,好比关系型数据库的一条data row。 |
| 列表类型 | List type | 列表类型可以存储一个有序的字符串列表,常用的操作是向列表两端添加元素,或者获得列表的某一个片段。 列表类型内部是使用双向链表(double linked list)实现的,所以向列表两端添加元素的时间复杂度为O(1),获取越接近两端的元素速度越快。 一个列表类型的键最多能容纳223-1个元素。 列表中的元素是有序的,而且可以重复。 |
| 集合类型 | Sets type | 集合中的每个元素没有顺序的,而且不能重复。 一个集合键最多可以存储223-1个元素。 集合类型的常用操作是向集合中加入或者删除元素、判断某个元素是否存在、集合求交集并集差集等。 |
| 有序集合 | Sorted sets type | 有序集合类型是在集合类型的基础上为每个元素关联上了一个分数。 集合元素不能重复,但是分数可以有重复。可以用有序集合求分数最大(或最小)的前N个元素、获得指定分数范围内的元素等,类似关系型数据库中的聚合函数Min()、Max()、Sum()等。 |
Redis中使用事务
概念
Redis中的事务(transaction)是一组命令的集合。事务同命令一样都是redis的最小执行单位,一个事务中的命令要么都执行,要么都不执行。
原理
事务的原理是先将属于一个事务的命令发送给redis,然后再让redis依次执行这些命令。
命令
与事务相关的命令。如下所列举:
| 命令 | 说明 |
|---|---|
| MULTI | 开启一个事务。类似关系型数据库的BEGIN TRANSACTION |
| EXEC | 执行事务块中的命令。类似关系型数据库的COMMIT |
| WATCH | 监视一个(或多个)key,如果在事务执行之前这个(或这些)key被其他命令所改动,那么事务将被打断。 |
| UNWATCH | 取消WATCH命令对所有key的监视。 |
| DISCARD | 取消事务。放弃执行事务块内的所有命令。 |
说明
Redis中的执行事务不是原子性的。当事务块中有多条修改数据的命令时,如果中间的某条命令失败(这种错误叫做"运行时错误"),不会导致前面已做的命令回滚,也不会造成后续的命令不做。也就是说,reids事务没有像关系型数据库事务那样的回滚(ROLLBACK)功能。
Redis数据逐出策略
概念
Redis使用内存存储数据,在执行每一个命令之前,都会调取freeMemoryIfNeeded()函数进行检测内存是否充足(freeMemoryIfNeeded()这个函数是redis源码中定义的一个函数,有兴趣的可以去看看),如果内存超出了配置的maxmemory最大内存,redis就会根据配置的逐出策略类型,从内存中删除数据,直到占用的内存小于配置的最大内存值。
配置
这里涉及到redis中的几个配置信息。
| 配置 | 说明 |
|---|---|
| maxmemory | 最大可用内存,指占用系统物理内存的大小。默认为0,表示不限制。而一般在生产环境中,设置为系统内存大小的70%左右。 |
| maxmemory-samples | 每次选取删除数据的个数。选取数据时并不会全库扫描,导致严重的性能消耗,降低读写性能,因此采用随机采样的方式,检测删除数据策略 |
| maxmemory-policy | 数据删除策略 |
策略类型
| 策略类型 | 说明 |
|---|---|
| volatile-lru | 从所有设置了过期时间的key中,选择最近最少使用的数据淘汰 |
| allkeys-lru | 从所有key中,选择最近最少使用的数据淘汰 |
| volatile-lfu | 从所有设置了过期时间的key中,选择最近最不长使用的数据淘汰 |
| allkeys-lfu | 从所有key中,选择最近最不长使用的数据淘汰 |
| volatile-random | 从所有设置了过期时间的key中,随机选择数据淘汰 |
| allkeys-random | 从所有key中,随机选择数据淘汰 |
| volatile-ttl | 从所有设置了过期时间的key中,选择将要过期的数据淘汰 |
| noeviction | 禁止淘汰数据 |
持久化
概念
持久化是指将内存中的数据保存到物理磁盘的操作。
Redis是内存存储数据的,但内存中数据在redis重启后会完全丢失。为了避免避免丢失这些数据,redis提供了两种持久化数据的方式:RDB方式和AOF方式。
| 持久化方式 | 说明 |
|---|---|
| RDB | RDB方式的持久化是通过快照(snapshotting)完成的。当符合一定条件时redis会自动将内存中的所有数据生成一份副本并存储在硬盘上,这个过程即为“快照”。 |
| AOF | AOF方式的持久化即APPEND ONLY FILE。是将redis执行的每次写命令记录到单独的日志文件中(有点像MySQL的binlog);当Redis重启时再次执行AOF文件中的命令来恢复数据。 |
Redis会在以下情况进行RDB持久化:
- 根据配置规则进行自动快照;
- 用户执行SAVE或BGSAVE命令;
- 执行FLUSHALL命令;
- 执行复制(replication)时。
Redis会在配置开启AOF和设置同步策略的情况下进行AOF持久化。涉及知识点: AOF持久化文件:
appendonly yes
dir 你要保存aof文件的文件夹路径
appendfilename 你的aof文件的文件名
appendfsync [always|everysec|no] //这个是同步策略,三种策略任选其一。一般采用everysec,代表每秒执行一次同步操作。always表示每次执行写入都会执行同步,最安全但最慢。no表示不主动进行同步操作,而是完全交由操作系统来做(即每30秒一次),最快但最不安全。
在生产环境中,这两种持久化方式同时开启,既保证数据安全,又使得进行数据备份等操作十分容易。此时重启redis后,redis会使用AOF文件来恢复数据,因为AOF方式的持久化丢失的数据更少。