一、Redis五种核心数据结构
1、String(字符串)
- 常用操作
- SET key value [expiration EX seconds|PX milliseconds] [NX|XX]:存入一个字符串键值对(可选:EX 秒|PX 毫秒)(可选:NX|XX)
- GET key:获取一个字符串键值
- MSET key value [key value …]:批量存入字符串键值对
- MGET key [key …]:批量获取字符串键值
- INCR key:将key中储存的数字值加1
- DECR key:将key中储存的数字值减1
- INCRBY key increment:将key所储存的值加increment
- DECRBY key decrement:将key所储存的值减decrement
- 应用场景
- 验证码
- 分布式锁
- 全局序列号
2、Hash(哈希)
- 常用操作
- HSET key field value:在哈希表key中存入一个field-value
- HGET key field:在哈希表key中获取一个field的value
- HMSET key field value [field value …]:在哈希表key中批量存入field-value
- HMGET key field [field …]:在哈希表key中批量获取field的value
- HDEL key field [field …] :在哈希表key中批量删除field-value
- HLEN key:返回哈希表key中field的数量
- HGETALL key:返回哈希表key中所有的field-value
- HINCRBY key field increment:为哈希表key中field的value加increment
- 应用场景
- 对象缓存
- 购物车
- 虚拟币钱包
3、List(列表)
- 常用操作
- LPUSH key value [value …]:左侧插入value
- RPUSH key value [value …]:右侧插入value
- LPOP key:左侧取出value
- RPOP key:右侧取出value
- LRANGE key start stop:返回列表中指定区间内的元素,区间以偏移量start和stop指定
- BLPOP key [key …] timeout:从列表左侧取出一个元素,若列表中没有元素,阻塞等待timeout秒,如果timeout=0,一直阻塞等待
- BRPOP key [key …] timeout:从列表右侧取出一个元素,若列表中没有元素,阻塞等待timeout秒,如果timeout=0,一直阻塞等待
- 应用场景
- 栈:LPUSH + LPOP
- 队列:LPUSH + RPOP
- 阻塞队列:LPUSH + BRPOP
- 抢红包
4、Set(无序集合)
- 常用操作
- SADD key member [member …]:往集合key中存入元素,元素存在则忽略
- SREM key member [member …]:从集合key中删除元素
- SMEMBERS key:获取集合key中所有元素
- SCARD key:获取集合key中元素个数
- SISMEMBER key member:判断member元素是否存在于集合key中
- SRANDMEMBER key [count]:从集合key中随机选出count个元素,元素不从key中删除
- SPOP key [count]:从集合key中随机选出count个元素,元素从key中删除
- SINTER key [key …]:交集运算
- SINTERSTORE destination key [key …]:将交集结果存入新集合destination中
- SUNION key [key …]:并集运算
- SUNIONSTORE destination key [key …]:将并集结果存入新集合destination中
- SDIFF key [key …]:差集运算
- SDIFFSTORE destination key [key …]:将差集结果存入新集合destination中
- 应用场景
- 抽奖:SRANDMEMBER key [count] / SPOP key [count]
- 关注模型
5、Zset(有序集合)
- 常用操作
- ZADD key score member [score member…]:往集合key中加入带分值成员
- ZREM key member [member …]:从集合key中删除成员
- ZSCORE key member:返回集合key中成员的分值
- ZINCRBY key increment member:为集合key中成员的分值加上increment
- ZCARD key:返回集合key中成员个数
- ZRANGE key start stop [WITHSCORES]:正序获取集合key中start到stop的成员
- ZREVRANGE key start stop [WITHSCORES]:倒序获取集合key中start到stop的成员
- ZUNIONSTORE destkey numkeys key [key …]:并集计算
- ZINTERSTORE destkey numkeys key [key …]:交集计算
- 应用场景
- 排行榜
二、Redis单线程
- Redis的单线程指的是执行Redis命令的操作是由一个线程负责的,客户端发送的Redis命令会加入队列中依次执行
- Redis严格来讲并不是单线程,比如持久化、异步删除、集群数据同步等操作是由额外的线程执行的
- 使用Redis时应注意耗时操作的出现,比如bigkey、keys等
三、Redis高性能
- 基于内存
- 单线程避免了线程切换的性能损耗
- IO多路复用机制:简单理解就是多线程并发连接客户端接收命令,执行命令线程依次执行命令,将结果通知给对应的连接线程执行响应操作
四、Redis持久化
1、RDB数据快照
-
原理:RDB(redis database)是Redis默认的持久化方案,在规定时间内,达到规定次数的写操作,就会触发快照,将内存中数据做一次全量备份,生成rdb文件,写入到磁盘中,覆盖旧的rdb文件
-
RDB配置
# RBD核心配置 # save <seconds> <changes> # 开启save配置即代表开启RDB持久化方案 # seconds:规定的时间 changes:规定的写操作次数 # 在seconds时间内达到changes次写操作,执行快照操作 save 900 1 save 300 10 save 60 10000 # 文件名配置 dbfilename dump.rdb # 文件路径配置 dir /usr/local/redis/redis-5.0.10/data # 文件压缩配置 # 默认值是yes # 采用LZF算法进行数据压缩 rdbcompression yes # 数据校验配置 # 默认值是yes # 采用CRC64算法进行数据校验 rdbchecksum yes # 拒绝写入配置 # 默认值是yes # 快照错误时,Redis停止接收写命令,一种保护机制 stop-writes-on-bgsave-error yes
-
快照模式
- save:Redis主进程直接调用rdbSave函数,执行快照操作,不消耗内存,但阻塞Redis主进程,不能处理客户端命令
- bgsave:Redis主进程fork一个子进程,由子进程调用rdbSave函数,执行快照操作,消耗内存,但不阻塞Redis主进程,可以处理客户端命令
-
触发快照
- 直接调用save命令,触发save
- 直接调用bgsave命令,触发bgsave
- 直接调用flushall命令,触发bgsave
- 达到save 规则,触发bgsave
- 关闭Redis服务
-
数据恢复:Redis启动时,只能通过RDB恢复数据时,调用rdbLoad函数,从磁盘中加载rdb文件,恢复数据到内存中,期间Redis服务处于阻塞状态
-
优点
- RDB是一个经过压缩的二进制文件,内容非常紧凑,体积很小
- 数据恢复近似于从磁盘到内存的加载数据动作,速度快
- 通常快照操作由fork出的子进程执行,对主进程影响较小,性能好
-
缺点
- 数据安全性较差,如果Redis服务意外停止,数据丢失问题会比较严重
- 在高并发场景,数据量比较大的情况下,频繁的快照操作,对Redis服务的性能可能会产生比较大的影响
2、AOF指令追加
-
原理:当修改指令执行成功后,立即将指令信息写入到缓冲区中,再根据配置的同步规则,决定何时将指令信息保存到AOF文件尾部
-
AOF配置
# AOF功能配置 # 默认值是no appendonly yes # 文件名配置 # 默认值是"appendonly.aof" appendfilename "appendonly.aof" # 文件路径配置 # 默认值是./ dir /usr/local/redis/redis-5.0.10/data # 追加同步规则配置 # 默认值是everysec # always: 每当有修改指令执行成功时就fsync一次,写入和保存操作都阻塞,非常慢,也非常安全 # everysec: 每秒fsync一次,写入操作阻塞,保存操作异步,足够快,也足够安全,在故障时只会丢失1秒钟的数据 # no: 由操作系统决定何时fsync,写入和保存操作都阻塞,更快,也更不安全 appendfsync everysec no-appendfsync-on-rewrite no aof-load-truncated yes # AOF自动重写的增长比例要求配置 # 默认值是100 # 设置为0将禁用AOF重写功能 # 当AOF文件大小增长了100%,则触发AOF重写功能 auto-aof-rewrite-percentage 100 # 触发AOF重写的最小体积配置 # 默认值是64mb # 只有AOF文件大小达到64mb,才会执行AOF重写功能 auto-aof-rewrite-min-size 64mb # aof-use-rdb-preamble yes
-
触发重写
- 直接调用bgrewriteaof命令,手动执行,不受配置限制
- 达到auto-aof-rewrite-percentage和auto-aof-rewrite-min-size配置要求,自动执行
- 关闭Redis服务
-
数据恢复:Redis启动时,优先查找AOF恢复数据,通过创建一个伪客户端来执行指令重放操作,恢复数据到内存中
-
优点
- 可以保障数据安全性较高,甚至能做到只丢一个命令的数据
-
缺点
3、RDB与AOF
综合比较 | RDB | AOF |
---|---|---|
文件体积 | 小(压缩的二进制数据) | 大(压缩的二进制数据 + 指令集) |
数据恢复 | 快(数据加载) | 慢(数据加载 + 指令重放) |
数据安全 | 差(数据丢失问题大) | 高(数据丢失问题小) |
性能 | 好 | 差 |
选择 | 不推荐 | 推荐 |