什么是Redis?
Redis(Remote Dictionary Server ),即远程字典服务!
是一个开源的使用ANSI C语言编写、支持网络、基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。
是当下最热门的NoSQL数据库之一, 数据结构服务器!
官方记录: Redis 一秒可以写8万,读11万次。
官网地址:https://redis.io/
Redis对比其他Key-Value缓存产品的特点:
- 支持数据持久化机制,重启数据不容易丢失
- 支持的数据类型很多:有string、list、set、hash、zset、geo、gitmap…
- 支持备份,并且对分布式集群有很好的支持:主从复制、哨兵
Redis可以做什么?
- 内存存储和持久化
- 多种数据类型满足基本上所有常见的结构数据的存储需求
- 发布、订阅模型
- 地图分析(坐标缓存、距离计算)
- 定时器 Timer
- 统计打卡
- Hyperloglogs、gitmap
- …
安装启动
安装
从官网上下载redis或者下载docker image运行
下载并解压redis,进redis目录,将Redis二进制文件安装至 usr/local/bin 中,执行命令:
make install |
启动
在此说明:redis配置文件大部分都是注释,在命令行中没有高亮显示,所以为了显示清晰,用vscode查看
redis是C/S架构,先要启动server,可以指定某个配置文件启动,配置文件默认端口6379
redis-server [redis.conf] |
修改redis.conf,设置守护进程的启动方式:
连接
- -h 主机地址默认127.0.0.1
- -p 端口默认6379
- –raw 可解决中文乱码问题
redis-cli [-h 127.0.0.1][-p 6379] |
连接后可使用ping命令检测是否登录成功!因为我们未设置密码,返回PONG代表已经登录
如果ping提示未授权,用auth命令进行登录
auth [密码] |
基础操作命令
Redis 的键
- Redis中所有数据值都有一个唯一的键,用于索引某个值
# 设置键k1为v1 |
配置
- 连接上Redis后可以查看和修改当前运行的配置
# 查看所有配置属性,这些配置在redis.conf中都可以提前配置 |
多数据库概念
Redis默认开启了16个数据库,数据库之间互相隔离
登录后默认切换为0号数据库
# 切换到数据库2 |
其它基础操作命令
# 清空当前数据库 |
五大数据类型
string 字符串
这是Redis中最基本的类型,一个key 对应一个 value,而且这个 value 是String 类型。Redis 字符串value 最大不要超过 512M。
# 设置一个string |
总结
- key如果存在setnx会有成果或失败的信号,而set则是覆盖
- 自增、自减如果key不存在则创建一个从0开始的值进行下一步操作
list 列表
Redis的列表是一个双向链表,left、right都可以插入元素
# 向列表头部插入一个或者多个值 |
总结
- 列表只要元素个数为0,则key也同时消失
- 如果key不存在,push也会同时创建key
- 链表的操作无论是头部还是尾部效率都非常高,如果操作中间的元素就会相对低很多
- 由于Redis双向链表的特性,可以玩成
栈
(先进后出),也可以玩成队列
(先进先出)
set 集合
set集合是一个元素不能重复的集合
# 向集合最后添加一个或多个元素,返回本次插入成功的个数 |
总结
- set集合最关键的机制就是元素不能重复,可以思考出很多应用场景
- 随机抽取命令可以用来做抽奖
- 差集可用来做可能认识的人,交集可用来做共同关注的好友,并集可以用来合并多个集合
hash 哈希
K-V,V又是一组组键值对类似于:K : {k0 : v0 , k1 : v1 },相当于一个对象(K)中有多个字段(k)存储了对应的值(v)
# 设置一个hash的一个或多个字段的值,hSet、hMset功能一致都可以批量设置 |
总结
- Redis Hash 本质其实就是将多个string类型向上封装了一层成为了filed和value的映射表
- 非常适合存储一个对象
zset 有序集合
以 set
集合为基础,增加了一个score值与每个元素绑定在一起
# 添加一个或多个带分数的元素,返回本次新增的个数(不是新增的为已存在的,但是分数会覆盖) |
总结
- zset根据分数来递增排序,分数变化了,排序也会随之变化
- 天然的分数排序,可以用来存储各种排行榜
- 分数区间的查找、统计,最高分、最低分等查询非常灵活且方便
三个特殊类型
GeoSpatial 地理位置
用于存储地理坐标、提供各种地域距离相关的计算,可以使用 百度坐标拾取系统 来测试Geo
# 存储一个或多个坐标元素到一个china-city中 |
总结
- Redis Geo 本质上就是一个有序集合,经纬度的hash值为分数值
- 可以通用zSet的某些命令操作Geo
- 可以方便的做地图范围搜索、地理距离、附近的人等功能
BitMaps 位图
适合存储只有两个状态(0|1)的数据,以计算机最小单位:位(bit)的方式存储,在大数据的场景下占用空间的也是极小的!
# 存储在0下标位置的值为1(true) |
总结
- 未设置的下标getBit拿到的也是0
- 可以将某个人的打卡记录这种类似场景存储在位图中,打卡了标记为1即可,查询某一天是否打卡或者统计一个时间段内打卡次数都是极其的方便
- 最重要的特性是bit存储,一个人365天的打卡记录也仅仅占用45 byte!
HyperLogLogs 基数统计
什么是基数?
基数就是不重复的元素,比如下面两个数据集,原数据集通过 去重
就成为了基数集
- 原数据集: [ 1,3,5,7,5,7,8 ]
- 基数集 :[ 1,3,5,7,8 ]
# 添加一个或多个元素,返回结果1:有任意一个元素是基数,0:此次添加没有基数元素 |
总结
- 用于统计不重复的数据或者出现多次只算一次的数据比较适合
- 基数元素可以存储任何内容,中文、标点符号、特殊符号甚至表情符号都可以作为基数去重处理
- 基数统计最大的优点是最大可以存储2^64 个不同元素的基数,却只占12kb 的空间!
- 精确的统计就不要用了,因为
HyperLogLogs
存在大约1%的错误率 - 用于统计网站的UV使用
HyperLogLogs
非常契合
Redis.conf
Redis所有的配置都在 redis.conf
配置文件中,连接到redis中可以使用以下命令查看/修改当前运行的配置
# 查看某个或所有的配置 |
NETWORK
# 绑定指定一个或者多个网卡ip地址,只有配置的ip地址的网卡才能访问到redis(0.0.0.0表示所有主机)
bind 127.0.0.1
# 保护机制开启,只要1、protected-mode yes(处于开启)2、没有bind指令 3、没有设置密码 就会开启【只有本机才能访问】😅
protected-mode yes
# 端口配置
port 6379GENERAL
# 是否使用守护进程启动,默认是no
daemonize yes
# 是否可以通过systemd来管理redis的守护进程
supervised no
# 以后台方式运行redis,就需要指定pid文件
pidfile /var/run/redis_6379.pid
# 日志级别
# debug (a lot of information, useful for development/testing)
# verbose (many rarely useful info, but not a mess like the debug level)
# notice (moderately verbose, what you want in production probably)
# warning (only very important / critical messages are logged)
loglevel notice
# 日志文件的位置,如果为空,则标准输出!
logfile "redis.log"
# 数据库的数量
databases 16
# 是否显示logo 😅
always-show-logo yesSNAPSHOTTING (RDB)
# rdb 持久化配置
save 900 1 #900秒内发生1次变化触发一次rdb更新
save 300 10 #300秒内发生10次变化触发一次rdb更新
save 60 10000 #60秒内发生10000次变化触发一次rdb更新
# 持久化出现错误之后,是够继续进行。
stop-writes-on-bgsave-error yes
# 是否压缩rdb文件,需要消耗cpu功能,no:不压缩,需要更多的磁盘空间
rdbcompression yes
# 是否检查rdb文件,利于文件的容错性,大概会有10%内存性能损耗
rdbchecksum yes
# 指定持久化文件
dbfilename dump.rdb
# 同步副本持久化文件!
rdb-del-sync-files no
# 数据目录
dir ./REPLICATION
# 主节点host port
replicaof <masterip> <masterport>
# 主节点密码
masterauth <master-password>SECURITY
# 密码配置
requirepass foobaredCLIENTS
# 最大连接数
maxclients 10000MEMORY MANAGEMENT
# 最大内存使用限制
maxmemory <bytes>
# 内存满了的可选规则(参考下图),默认noeviction
# LRU算法,least Recently Used 最近最少使用的几个key随机删除
maxmemory-policy noeviction
# 设置参与随机的key的个数
maxmemory-samples 5APPEND ONLY MODE (AOF)
# 是否开启持久化追加模式
appendonly no
# 追加模式持久化文件
appendfilename "appendonly.aof"
# 持久化策略
# always 每次写入都执行同步,效率相对较低 优点:最安全
# everysec 每秒都执行同步,缺点:down掉最后一秒数据可能丢失
# no 不执行同步,仅在系统需要的时候持久化到磁盘,优点:最快,缺点:最不安全
appendfsync everysec
持久化
Redis是一个内存数据库,断电即失,所以持久化是一个非常重要的需求!
RDB (Redis DataBase)
什么是RDB?持久化原理是什么?
- Rdb是指Redis在指定间隔将内存中的数据压缩成快照(Snapshotting)写入磁盘中的.rdb文件。
- 持久化的过程:1、Redis会fork一个子进程 2、子进程写入临时文件 3、持久化完毕后再替换上次持久化好的文件。
- 优点:
- I/O操作全部交给了子进程来处理,主进程性能基本不受影响
- 适合大规模的数据恢复,比如在主机A的数据想恢复到主机B,只要将A的dump.rdb文件复制到B,即可快速恢复
- 缺点:
- fork后内存数据被克隆了一份,内存大约会膨胀到2倍
- 当内存数据比较大的时候,经常进行fork是非常耗时的,会稍微影响客户端毫秒级的响应
- 持久化是根据配置触发条件或者命令进行持久化,如果在触发持久化之前进程被down掉的话,则会丢失最后一次快照之后变更的数据,完整性和一致性一般
触发规则
被动触发规则在上面 SNAPSHOTTING 的配置中!
主动触发规则:
# 只管保存,会阻塞当前操作!
save
# 在后台异步进行持久化操作
bgSave
# 查看最后一次持久化的时间戳
lastSaveshutdown退出的时候与flushAll清空的时候也会触发持久化
恢复规则
- 启动的时候会自动加载redis主目录下的dump.rdb文件,config get dir命令可以查看此目录~
AOF (Append Only File)
什么是AOF?
- 将我们执行的每一个非查询的步骤都记录下来,不断地在.aof文件最后进行追加内容!
- 恢复的时候按照这个文件的命令一个个读取
- 默认是不不开启的,可以在上面 APPEND ONLY MODE 配置中开启
aof文件异常
如果.aof文件出现异常,会导致redis无法启动,可以使用 redis-check-aof
命令来进行修复aof文件,这个命令会将错误行之后的所有命令删除
redis-check-aof --fix appendonly.aof |
总结
- 同样的数据.aof文件是远远大于.rdb的
- AOF恢复的效率是不如RDB的,但是AOF同步机制会比rdb更加安全
事务
Redis中事务的概念
- 本质是将多个命令组成命令的集合,按顺序串行执行!
- 单条命令是原子性的,但事务不会保证原子性,即任意一个命令错误,其它命令同样会执行并且不会回滚
- 多个命令在开启事务后都会放在队列里,在提交事务前都不会真正执行,所以没有隔离级别的概念!
事务操作
Redis的事务操作流程为:开启一个事务、命令入队、执行或放弃事务:
# 开启事务 |
全部成功的事务
全部未执行的事务
因为命令错误导致的异常,相当于编译出错,此时需要重新开启事务、重新命令入队
部分成功的事务
因为执行过程中出现的错误,相当于运行异常,因为只存在单条命令的原子性,所以只有运行错误的命令失败
乐观锁
乐观锁概念:非常地乐观,认为每次获取数据都不会有变化,因此不用上锁。但是在更新的时候会更新一个版本号,如果下一次有人来改的时候请带上这个版本号,如果带上的这个版本号与这个值当前版本号不一致,那么就认为这个值被别人改过了!
Redis中的乐观锁操作:
# 监控一个或多个key(相当于监控版本号) |
使用 watch
与事务的结合可实现乐观锁,决定事务是否被执行(如下图)
总结
- 一旦执行exec,无论事务是否执行成功都将取消监视
- 一般此用法可以写在一个循环中,直到事务被执行成功为止~
发布、订阅
发布、订阅模型就类似于微信公众号。公众号是发布者、公众是订阅者,一对多的关系
Redis 中的发布订阅使用以下命令即可实现
# 订阅一个或多个通道
subscribe hth
# 向指定通道里推送一个消息
publish hth hello示例:
总结
- 可用于实时消息聊天、群聊、消息队列等场景
- 相对于专业的消息队列中间件来说,功能比较局限
集群
主从复制
概念
- 主Redis服务称为(Master、leader),从Redis服务称为(Slave、follower)
- 只能从主节点复制数据到从节点。
数据冗余
主从复制是除了持久化的另一种数据备份、冗余方式故障恢复
主节点如果挂了,从节点可以替代主节点工作负载均衡
Master:主要用来写,Slave主要用来读。降低了服务器的压力高可用
集群是高可用的基础
搭建集群
搭建一个一主两从的集群,首先可以先复制两个单独的配置文件,并分别修改其端口、持久化配置等再启动
连接redis,使用 info replication
查看集群相关的信息,发现目前每个节点都是master
使用
slaveOf
分别将6381、6382节点设置为Slave,下面是slaveOf
的用法# 设置主节点地址、端口,本节点作为其Slave
slaveOf 127.0.0.1 6380
# 将从节点恢复为主节点
slaveOf NO ONE再使用
info replication
分别查看主从节点此时所有Slave都是不可写状态
并且从master的写会同步到所有Slave!
总结
- 一般实战不会使用
SlaveOf
来修改master的信息,因为重启之后又会读取redis.conf,所以一般修改每个节点的REPLICATION配置 - 多节点配置非常麻烦,可使用docker简化集群的搭建
- 全量复制:slave第一次连接master,会将master所有内容同步一遍
- 增量复制:slave如果挂了,重启之后连上master,会将所有命令同步增加
- 如果master挂了,slave将等待master,此时集群将不可写,master恢复后即可正常工作!为了解决master掉线导致的不可用,需要
哨兵
来处理故障恢复(选举新master)
哨兵模式
配置、启动哨兵
哨兵的所有配置都在
sentinel.conf
文件中,修改关键的配置# 设置哨兵监控的master节点地址
sentinel monitor mymaster 127.0.0.1 6380 1启动一个哨兵
# 指定配置文件启动
redis-sentinel sentinel.conf测试
shutdown
主节点,等待30秒左右
哨兵全部配置
转载自 https://blog.csdn.net/u012441222/article/details/80751390
# 告诉sentinel去监听地址为ip:port的一个master,这里的master-name可以自定义,quorum是一个 数字,指明当有多少个sentinel认为一个master失效时,master才算真正失效 |
性能压测工具
redis-benchmark
是redis自带的性能压力测试工具!
可以模拟高并发的情况来测试 redis 性能。
序号 | 选项 | 描述 | 默认值 |
---|---|---|---|
1 | -h | 指定服务器主机名 | 127.0.0.1 |
2 | -p | 指定服务器端口 | 6379 |
3 | -s | 指定服务器 | socket |
4 | -c | 指定并发连接数 | 50 |
5 | -n | 指定请求数 | 10000 |
6 | -d | 以字节的形式指定 SET/GET 值的数据大小 | 2 |
7 | -k | 1=keep alive 0=reconnect | 1 |
8 | -r | SET/GET/INCR 使用随机 key, SADD 使用随机值 | |
9 | -P | 通过管道传输 请求 | 1 |
10 | -q | 强制退出 redis。仅显示 query/sec 值 | |
11 | –csv | 以 CSV 格式输出 | |
12 | -l | 生成循环,永久执行测试 | |
13 | -t | 仅运行以逗号分隔的测试命令列表。 | |
14 | -I | Idle 模式。仅打开 N 个 idle 连接并等待 |
# 测试:-c 100个连接 -n 十万个请求 |
只显示指定结果的query/sec值:
redis-benchmark -h localhost -p 6380 -c 100 -n 100000 -t set,get,incr -q |