Open Source, Open Future!
  menu
107 文章
ღゝ◡╹)ノ❤️

Redis

官网介绍

Redis is an open source (BSD licensed), in-memory data structure store, used as a database, cache and message broker. It supports data structures such as strings, hashes, lists, sets, sorted sets with range queries, bitmaps, hyperloglogs, geospatial indexes with radius queries and streams. Redis has built-in replication, Lua scripting, LRU eviction, transactions and different levels of on-disk persistence, and provides high availability via Redis Sentinel and automatic partitioning with Redis Cluster.

特点

  • 开源免费
  • 高性能(数据存储在内存中)
  • 支持数据的持久化
  • 丰富的数据类型【String(字符串)、Hash(散列)、List(列表)、Set(集合)、Sorted Set(有序集合)】
  • 支持事务
  • 单个操作是原子性的
  • 支持 publish/subscribe
  • 可以设置key过期
  • 通过哨兵和自动分区提供高可用性

设置密码

如果需要设置密码,可以用下面两种方法:

  1. 修改配置文件redis.conf,找到参数requirepass,设置红框中的密码

image.png

  1. 使用命令:CONFIG set requirepass 123456
    服务器重启会失效

命令(linux下)

  1. 启动服务器
    redis-server redis.conf

  2. 连接服务器
    redis-cli -h host -p port -a password
    如:redis-cli -h 192.168.1.201 -p 6379 -a 123456
    如果是本地测试又没有密码,可以用redis-cli

  3. 连接远程服务器问题

    • 如果连不上,可以修改配置文件redis.conf,将下面的参数注释掉:

image.png

  • 如果不需要密码访问,可以修改配置文件redis.conf,参数requirepass注释掉,参 数protected-mode设为no

image.png

  1. 查看服务端信息
    info server
  2. 关闭服务器(客户端命令)
    shutdown
  3. 退出客户端
    quit 或者exit

命令

命令返回值描述
SELECT indexOK切换index对应的数据库

keys常用命令

命令返回值描述
EXISTS key [key ...]能够查到的数量检查key是否存在(可检查多个,用空格隔开)
DEL key [key ...]成功删除的数量删除key(可删除多个,用空格隔开)
FLUSHALL [ASYNC]OK清除所有库所有key
FLUSHDB [ASYNC]OK清除单个库所有key
KEYS pattern符合要求的key的集合查找所有符合指定模式 pattern的key
EXPIRE key seconds1:成功;
0:key不存在或失败
设置 key 的过期时间(秒)
EXPIREAT key timestamp同上设置 key 的过期时间(秒)(时间戳)
PEXPIRE key milliseconds同上设置 key 的过期时间(毫秒)
PEXPIREAT key milliseconds-timestamp同上设置 key 的过期时间(毫秒)(时间戳)
PERSIST key1:成功;
0:key不存在或 key 没有设置过期时间
移除 key的过期时间
TTL key-2:key不存在;
-1:key存在但没设置过期时间;
其他:key的剩余时间
查询key还有多长时间过期(秒);
TTL:Time To Live
PTTL key同上查询key还有多长时间过期(毫秒)
RANDOMKEY随机返回一个key随机返回一个key,没有时返回nil
RENAME key newkeyOK:修改成功;
error:key不存在
将key的名字改为newkey
RENAMENX key newkey1:修改成功;
0:newkey已经存在,修改失败;
error:key不存在
将key的名字改为newkey
TYPE keystring:字符串
list:列表
set:集合
zset:有序集合
hash:哈希表
none:key不存在
查询key储存的值的类型

数据类型

String

字符串类型,Redis 最基本的类型,值最大能存储 512MB

命令返回值描述
SET key value [expiration EX seconds|PX milliseconds] [NX|XX]OK:成功设置key-value
MSET key value [key value ...]OK:成功批量设置key-value
SETNX key value1:成功;
0:key已存在,设置失败
当key不存在时,设置key-value
SETEX key seconds valueOK:成功;
error:设置失败
设置key-value和过期时间(秒)
PSETEX key milliseconds value同上设置key-value和过期时间(毫秒)
SETRANGE key offset value新值长度用value覆盖key的值,覆盖的位置从偏移量 offset 开始
SETBIT key offset value指定偏移量原来储存的位设置指定偏移量上的位
GET keynil:key不存在;
error:key不是String类型;
其他:key对应的值
获取值
GETSET key value同上设置值,并返回旧值
MGET key [key ...]key对应的值的集合一次查询多个key,若其中有些key不存在,则其对应的值为nil
GETRANGE key start enderror:key不是String类型或参数错误;
其他:key对应的值
查询key对应的值的子字符串;
负数表示从末尾看,如-1:倒数第一位;
当key不存在时返回的是"",而不是nil
GETBIT key offset指定偏移量上的位获取指定偏移量上的位(对不存在的 key 或者不存在的 offset 进行 GETBIT, 返回 0)
STRLEN key字符串长度查询字符串长度,key不存在返回0
APPEND key value若key存在返回新值;
若key不存在返回新值的长度
key的值追加value;
key不存在,新建k-v,再追加value
INCR keykey 的新值key 中储存的数字值加1;
key如果不存在,则先自动创建key-value,value初始值为0,然后再加1;
value如果不是integer类型,返回error
INCRBY key increment同上key 中储存的数字值加increment;
key如果不存在,则先自动创建key-value,value初始值为0,然后再加increment;
value如果不是integer类型,返回error
INCRBYFLOAT key increment同上key 中储存的数字值加increment;
key如果不存在,则先自动创建key-value,value初始值为0,然后再加increment;
value如果不是float类型,返回error;
值和增量都是指数符号,会被改成非指数符号;
小数部分多余的0会被去掉;
DECR key同上key 中储存的数字值减1;
key如果不存在,则先自动创建key-value,value初始值为0,然后再减1;
value如果不是integer类型,返回error
DECRBY key decrement同上key 中储存的数字值减decrement;
key如果不存在,则先自动创建key-value,value初始值为0,然后再减decrement;
value如果不是integer类型,返回error
DECRBYFLOAT key increment同上key 中储存的数字值减increment;
key如果不存在,则先自动创建key-value,value初始值为0,然后再减increment;
value如果不是float类型,返回error;
值和增量都是指数符号,会被改成非指数符号;
小数部分多余的0会被去掉;

Hash

每个 hash 可以存储 232- 1 键值对(40多亿)。

命令返回值描述
HEXISTS key field1:存在;0:不存在检查field是否存在
HSET key field value1:field 是新字段,且value设置成功;
0:field 是已经存在的字段,且value覆盖成功
给哈希表新增/修改field,新值为value
HSETNX key field value1:field 是新字段,且value设置成功;
0:field 是已经存在的字段,设置失败
field不存在时,设置值为value;
field存在时,不处理
HMSET key field value [field value ...]OK给哈希表批量新增/修改field
HLEN keyfield数量查询哈希表中field的数量;
key 不存在时,返回 0
HKEYS keyfield集合返回哈希表的所有的field
HVALS keyvalue集合返回哈希表的所有的value
HGET key fieldvalue查询field对应的value
HMGET key field [field ...]value集合批量查询field对应的value;
若其中有些field不存在则其对应的value为nil
HGETALL key集合查询所有的field和value;
每个field后面紧跟对应的value;
返回集合的大小是哈希表大小的两倍
HDEL key field [field ...]成功删除field的数量删除field
HINCRBY key field increment新值field对应的value加increment(整数);
increment可以为负数
HINCRBYFLOAT key field increment新值field对应的value加increment(浮点数);
increment可以为负数

List

列表类型,一个列表最多可以包含 232- 1个元素

命令返回值描述
LLEN key列表的长度查询列表的长度
LPUSH key value [value ...]列表的长度从列表头部插入元素;
列表不存在则创建
LPUSHX key value同上从列表头部插入元素;
列表不存在则失败,返回0
RPUSH key value [value ...]同上从列表尾部插入元素;
列表不存在则创建
RPUSHX key value同上从列表尾部插入元素;
列表不存在则失败,返回0
LINSERT key BEFORE|AFTER pivot value-1:没有找到元素pivot;
0:key 不存在;
其他数值:列表的长度
在指定元素pivot前面或后面插入元素value;
start 和stop可以为负数
LRANGE key start stop子列表查询列表指定区间内的元素;
start 和stop可以为负数
LINDEX key index列表指定索引处的元素查询列表指定索引处的元素;
索引值若超出列表的区间,返回 nil
LSET key index valueOK / error修改指定索引处的元素;
索引值若超出列表的区间,返回 error;
key不存在,返回 error
LPOP key列表的第一个元素移除并返回列表的第一个元素;
key不存在返回nil;
移除后列表若为空,同时删除key
RPOP key列表的最后一个元素移除并返回列表的最后一个元素;
key不存在返回nil ;
移除后列表若为空,同时删除key
BLPOP key [key ...] timeout列表(有两个元素);
第一个元素表示属于哪个key;
第二个元素是移除的值
移除并返回列表的第一个元素;
列表为空时会阻塞,直到超时或有元素为止;
移除后列表若为空,同时删除key
BRPOP key [key ...] timeout列表(有两个元素);
第一个元素表示属于哪个key;
第二个元素是移除的值
移除并返回列表的最后一个元素;
列表为空时会阻塞,直到超时或有元素为止;
移除后列表若为空,同时删除key
RPOPLPUSH source destination timeout弹出的元素列表中取出最后一个元素,并插入到另外一个列表的头部;
移除后列表若为空,同时删除key
BRPOPLPUSH source destination弹出的元素列表中取出最后一个元素,并插入到另外一个列表的头部;
列表为空时会阻塞,直到超时或有元素为止;
移除后列表若为空,同时删除key
LREM key count value成功删除的数量删除与value相等的元素;
count > 0 : 从头部开始搜索,移除与 value相等的元素,数量为 count ;
count < 0 : 从头部开始搜索,移除与 value相等的元素,数量为 count 的绝对值 ;
count = 0 : 从头部开始搜索,移除与 value相等的全部元素;
key不存在,返回 0
LTRIM key start stopOK对列表进行修剪,只保留区间内的元素;
key不存在,也同样返回 OK

Set

集合类型,无序,不重复,集合中的元素数量最多为 232 - 1

命令返回值描述
SADD key member [member ...]集合的大小添加元素
SPOP key [count]子集合随机查询count个元素,并移除;
count如果不传,默认为1
SRANDMEMBER key [count]子集合随机查询count个元素;
count如果不传,默认为1
SCARD key集合的大小查询集合的大小
SMEMBERS key集合的所有元素查询集合的所有元素
SISMEMBER key member1:是;0:否查询member是否是集合中的元素
SMOVE source destination member1:是;0:否将member从source集合移动到destination集合;
若member不在source集合中则返回0
SREM key member [member ...]成功移除的数量移除元素
SUNION key [key ...]并集查询给定集合之间的并集
SUNIONSTORE destination key [key ...]并集的大小查询给定集合之间的并集,将结果存入destination
SINTER key [key ...]交集查询给定集合之间的交集
SINTERSTORE destination key [key ...]交集的大小查询给定集合之间的交集,将结果存入destination
SDIFF key [key ...]差集查询给定集合之间的差集;
以第一个集合为基准,与后面的所有集合作比较
SDIFFSTORE destination key [key ...]差集的大小查询给定集合之间的差集,将结果存入destination;
以第一个集合为基准,与后面的所有集合作比较

Sorted Set

集合类型,有序,不重复,每个元素都会关联一个double类型的分数,通过分数对元素从小到大排序,集合中的成元素数量最多为 232 - 1

命令返回值描述
ZADD key [NX|XX] [CH] [INCR]
score member [score member ...]
添加成功的数量添加元素
ZSCORE key member分数值查询指定元素的分数值
ZINCRBY key increment member新分数值指定元素的分数加上增量increment;
increment可以为负数;
key不存在则自动创建
ZCARD key集合的大小查询集合的大小
ZCOUNT key min max指定分数区间的元素数量查询指定分数区间内的元素数量
ZLEXCOUNT key min max指定字典区间的元素数量查询指定字典区间内的元素数量
ZRANGE key start stop [WITHSCORES]子集合查询指定索引区间内的所有元素
ZRANGEBYLEX key min max [LIMIT offset count]子集合查询指定字典区间内的所有元素
ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]子集合查询指定分数区间内的所有元素
ZREVRANGE key start stop [WITHSCORES]子集合查询指定索引区间内的所有元素;
分数从高到低排序;
ZRANGE相反
ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count]子集合查询指定分数区间内的所有元素;
分数从高到低排序;
ZRANGEBYSCORE相反
ZRANK key member索引值查询指定元素在集合中的索引;
集合中若没有指定的元素,返回nil
ZREVRANK key member索引值查询指定元素在集合中的索引;
集合中若没有指定的元素,返回nil;
分数从高到低排序
ZREM key member [member ...]移除成功的数量移除元素
ZREMRANGEBYLEX key min max移除成功的数量移除指定字典区间内的所有元素
ZREMRANGEBYRANK key start stop移除成功的数量移除指定索引区间内的所有元素
ZREMRANGEBYSCORE key min max移除成功的数量移除指定分数区间内的所有元素
ZINTERSTORE destination numkeys key [key ...]
[WEIGHTS weight] [AGGREGATE SUM|MIN|MAX
集合destination的大小计算交集,结果存进集合destination
ZUNIONSTORE destination numkeys key [key ...] [WEIGHTS weight] [AGGREGATE SUM|MIN|MAX]集合destination的大小计算并集,结果存进集合destination
ZSCAN key cursor [MATCH pattern] [COUNT count]返回的每个元素都是一个有序集合元素;
一个有序集合元素由一个成员(member)和一个分值(score)组成
迭代有序集合中的元素(包括元素成员和元素分值)

发布订阅

命令返回值描述
SUBSCRIBE channel [channel ...]接收到的信息订阅指定的频道
PSUBSCRIBE pattern [pattern ...]接收到的信息订阅符合指定模式的频道
UNSUBSCRIBE [channel [channel ...]]接收到信息的订阅者数量退订指定的频道
PUNSUBSCRIBE [pattern [pattern ...]]接收到的信息退订符合指定模式的频道
PUBLISH channel message接收到信息的订阅者数量将信息发送到指定的频道
PUBSUB subcommand [argument [argument ...]]由活跃频道组成的列表查看订阅与发布系统状态;
如:PUBSUB CHANNELS

事务

特性

  • 批量操作在发送 EXEC 命令前被放入队列缓存。
  • 收到 EXEC 命令后进入事务执行,事务中任意命令执行失败,其余的命令依然被执行。
  • Redis 事务的执行并不是原子性的。
  • 在事务执行过程,其他客户端提交的命令请求不会插入到事务执行命令序列中。

流程

  1. 开始事务(MULTI
  2. 命令入队
  3. 执行事务(EXEC
命令返回值描述
MULTIOK标记一个事务块的开始
EXEC事务块内所有命令的返回值;
按命令执行的先后顺序排列;
当操作被打断时,返回空值 nil
执行事务块内的所有命令
DISCARDOK取消事务,放弃执行事务块内的所有命令
WATCH key [key ...]OK用于监视一个(或多个) key ;
如果在事务执行之前key被其他命令所改动,那么事务将被打断,事务块内的所有命令都不执行
UNWATCHOK取消 对所有 key 的监视

备份与恢复

备份

命令返回值描述
SAVEOK备份文件
BGSAVEBackground saving started在后台备份文件

恢复

将备份文件 (dump.rdb) 移动到 redis 安装目录并启动服务即可。

过期键删除策略

redis使用的是惰性删除+定期删除,两种策略配合使用。

惰性删除

访问指定键时才对键进行过期检查,若过期就删除。

定期删除

每隔一段时间(默认100ms)执行一次删除。分多次遍历服务器的各个数据库,随机检查一部分键的过期时间,并删除其中的过期键。

内存淘汰策略

redis在占用内存超过maxmemory之后,可以通过淘汰策略删除数据,默认使用noeviction策略 。
格式:maxmemory-policy xxx

策略说明
volatile-lru设置了过期时间的键中,用LRU算法淘汰
volatile-lfu设置了过期时间的键中,用LFU算法淘汰
volatile-random设置了过期时间的键中,随机淘汰
volatile-ttl设置了过期时间的键中,过期时间最早的淘汰
allkeys-lru所有键中,用LRU算法淘汰
allkeys-lfu所有键中,用LFU算法淘汰
allkeys-random所有键中,随机淘汰
noeviction不淘汰

持久化

Redis的数据是放在内存中的,没有持久化机制,一旦服务器进程退出,数据就会丢失。Redis持久化机制有两种:RDB和AOF

RDB

介绍:
将某个时间点的数据库状态(快照)保存到一个rdb文件中。

创建

手动生成RDB:
使用命令:SAVE(阻塞) 或 BGSAVE (子进程处理)

自动生成RDB:
配置文件redis.conf中有个参数save,可以设置多个条件,当任一条件满足时,自动执行一次BGSAVE命令。格式如下:
save <seconds> <changes>
指定在多长时间内,有多少次更新操作,就将数据同步到数据文件。
Redis 默认配置文件中提供了三个条件:
save 900 1
save 300 10
save 60 10000
分别表示 900 秒(15 分钟)内有 1 个更改,300 秒(5 分钟)内有 10 个更改, 60 秒内有 10000 个更改。

载入

RDB的载入是在服务器启动时自动执行的,只要Redis在启动时检测到rdb文件的存在,就自动载入。
如果服务器开启了AOF持久化功能,则优先用AOF文件来还原数据库状态。流程图如下:

image.png

AOF

AOF:Append Only File
当开启AOF功能时,每执行一个写命令,会同时将这个命令顺序记录到文件中。

appendfsync

为了提高文件的写入效率,当用户调用write函数,将数据写入文件时,操作系统通常会将数据暂时保存在一个内存缓冲区中,等缓冲区满了或超过指定的时限时,才真正将数据写入磁盘。
系统提供了两个同步函数:fsyncfdatasync,可以强制将缓存区的数据写入到磁盘中。

Redis可以通过配置appendfsync来使用不同的同步策略。

  • always
    每个事件循环都将缓冲区数据写入磁盘,所以效率是最低的,但是安全性最好;
  • everysec
    默认配置,每隔一秒钟在子进程中做次同步,效率很好;若故障停机,最多丢失一秒数据;
  • no
    何时同步,由操作系统控制;若故障停机,则上次同步之后的数据会丢失;
载入

AOF文件中包含了重建数据库状态所需的所有写命令,所以服务器只要读入并重新执行一遍AOF文件里面保存的写命令,就可以还原关闭之前的数据库状态。

image.png

重写

AOF文件会记录所有的写操作,时间一长,文件会非常庞大,还原数据时需要的时间也会越来越多。为解决这个问题,Redis提供了文件重写(rewrite)功能。创建一个新的AOF文件替换原来的AOF文件。重写过程并不依赖原来的文件,而是直接读取当前的数据库状态,因此,新文件的体积要小很多。