Redis 基础篇
一、redis 概念及特性
1.1 Redis 概念
Redis(Remote Dictionary Server),即远程字典服务,是一个开源的高性能键值存储数据库,可以用作数据库、缓存和消息中间件。
redis 官网:Redis - The Real-time Data Platform
redis 中文文档:Redis中文学习网 - Redis开发与运维技术、Redis教程、使用手册
1.2 Redis特性
- 高性能:Redis的速度非常快,官方给出的读写性能可以达到10万次/秒,这得益于其内存存储、C语言实现、单线程架构以及优秀的源代码。
- 丰富的功能:除了基本的Key-Value存储外,Redis还支持发布/订阅机制、事务、Lua脚本、流水线、键过期等功能。
- 持久化:Redis提供了两种持久化方式:RDB(快照)和AOF(追加文件),以确保数据的可靠性和持久性。
- 主从复制:Redis支持主从同步,数据可以从主服务器向任意数量的从服务器上同步,这有助于实现数据的冗余和读取操作的扩展性。
- 高可用性和分布式:Redis提供了高可用实现Redis Sentinel和分布式实现Redis Cluster,以确保在分布式环境中的高可用性和读写、容量的扩展性。
1.3 docker 安装 redis
// 拉取镜像 docker pull redis // 在后台运行 redis docker run -v /usr/redis/redis3.conf:/usr/redis/redis.conf -p 6379:6379 --name myredis -d redis // 在后台运行 redis docker run -v /usr/redis/redis2.conf:/usr/redis/redis.conf -v /usr/redis/data:/data --privileged=true -p 6380:6380 --name redis_slave80 -d redis redis-server /usr/redis/redis.conf
二、redis 常用数据类型及命令
2.1 查看和设置配置
查看所有配置:config get *
查看某项配置:CONFIG GET CONFIG_SETTING_NAME
设置某项配置:CONFIG SET CONFIG_SETTING_NAME NEW_CONFIG_VALUE
2.2 常用数据类型
2.2.1 String
// 设置字符串的命令 SET key value [EX seconds|PX milliseconds|KEEPTTL] [NX|XX] [GET]
// 当 Key 值不存在时,才进行设置
set mykey 111 nx
// 当 Key 值存在时,才进行设置
set myKey 222 xx
// 设置过期时间(秒)
set myKey 333 ex 10
// 设置过期时间(毫秒)
set myKey 444 px 5000
// 保留 Key 之前设置的过期时间
set myKey 555 ex 30
set myKey 666 keepttl
// 同时设置多个键值对
mset k1 v1 k2 v2
// 同时获取多个键值对
mget k1 k2
// 获取字符串的一部分内容
getrange mykey 0 3 // 0 -1 表示全部
// 对存储的数字加 1
set k1 100
incr k1
应用场景:喜欢的视频或商品,点一次加1
2.2.2 List
应用场景:微信公众号订阅文章
2.2.3 Hash
应用场景:早期购物车
2.2.4 Set
应用场景:社交场景中的共同好友、可能认识的人、抽奖活动
2.2.5 Sorted set
应用场景:商品销量排序
参考 redis 命令手册
三、redis 持久化
redis 提供了多种不同级别的持久化方式:
- RDB 持久化可以在指定的时间间隔内生成数据集的时间点快照(point-in-time snapshot)
- AOF 持久化记录服务器执行的所有写操作命令,并在服务器启动时,通过重新执行这些命令来还原数据集
AOF配置:
通过修改配置文件来打开 AOF 功能: appendonly yes
AOF工作流程:
三种写回策略:
- always:每次有新命令追加到 AOF 文件时就执行一次 fsync :非常慢,也非常安全。
- everysec:每秒 fsync 一次,redis默认的写回策略。足够快(和使用 RDB 持久化差不多),并且在故障时只会丢失 1 秒钟的数据。
- no:从不 fsync :将数据交给操作系统来处理。更快,也更不安全的选择。
四、redis 事务
5.1 概念
redis 事务可以将命令组合在一起以便于它们作为一个单独的事务执行。
5.2 命令
Redis使用 MULTI 命令标记事务开始,它总是返回OK。MULTI执行之后,客户端可以发送多条命令,Redis会把这些命令保存在队列当中,而不是立刻执行这些命令。所有的命令会在调用EXEC 命令之后执行。 如果不调用EXEC,调用 DISCARD 会清空事务队列并退出事务。
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> set k1 2222
QUEUED
127.0.0.1:6379(TX)> incr k1
QUEUED
127.0.0.1:6379(TX)> hset k2 name snow age 18 address beijing
QUEUED
127.0.0.1:6379(TX)> exec
1) OK
2) (integer) 2223
3) (integer) 3
5.3 redis事务与关系型数据库事务的区别
5.4 为什么 redis 事务不支持回滚
Redis事务中的命令允许失败,但是Redis会继续执行其它的命令而不是回滚所有命令。
这么做的原因有两点:
①Redis 命令只在两种情况失败:
- 语法错误的时候才失败(在命令输入的时候不检查语法)。
- 要执行的key数据类型不匹配:这种错误实际上是编程错误,这应该在开发阶段被测试出来,而不是生产上。
②因为不需要回滚,所以Redis内部实现简单并高效。
五、redis 管道
5.1 管道定义
pipeline 是为了解决命令RTT(round-trip time)往返时间,仅仅将命令打包一次性发送,对整个redis的执行不造成任何影响。
5.2 管道的使用方法
使用命令:
cat cmd.txt | redis-cli --pipe
举例说明:
5.3 管道和原生批处理命令的区别
- 原生批量命令是原子性(例如:mset mget),pipeline是非原子性
- 原生批量命令一次只能执行一种命令,pipeline支持批量执行不同命令
- 原生批命令是服务端实现,而pipelne需要服务端与客户端共同完成
5.4 注意事项
- pipeline缓冲的指令只是会依次执行,不保证原子性,如果执行中指令发生异常,将会继续执行后续的指令
- 使用pipeline组装的命令个数不能太多,不然数据量过大客户端阻塞的时间可能过久,同时服务端此时也被迫回复一个队列答复,占用很多内存
六、redis 复制
6.1 概念
主从复制,master 以写为主,slave 以读为主,当 master 数据变化的时候,自动将新的数据以异步的方式同步到其他 slave 数据库。
6.2 特性
- 读写分离
- 容灾恢复
- 数据备份
- 水平扩容支撑高并发
6.3 主从复制的命令
// 主从复制
replicaof 主库IP 主库端口
// 变更主库
slaveof 新主库IP 新主库端口
// 取消从库
slave no one
redis搭建一主二从复制的具体操作见 阿里云环境下用docker搭建redis主从复制-CSDN博客
6.4 主从复制的工作原理
- slave启动,同步初请
- 首次连接,全量复制
- 心跳持续,保持通信
- 进入平稳,增量复制
- 从机下线,重连续传
6.5 主从复制的缺点
复制延时,信号衰减
master服务故障
七、redis 哨兵
7.1 概念
吹哨人巡查监控后台master主机是否出现故障,如果出现故障,则根据投票数自动将某一个从库转为新主库,继续对外提供服务。俗称无人值守运维。
八、redis 集群
8.1 概念
redis 集群是一个可以提供在多个redis节点间共享数据的程序集,redis 集群可以支持多个 master。
8.2 特性
- redis 集群支持多个 master,每个 master 后可以挂载多个 slave,支持读写分离、高可用,支持海量数据的读写存储操作
- redis 集群自带 sentinel 故障转移机制,无需再去使用哨兵功能
- 客户端与 redis 的节点连接,不再需要连接集群中的所有节点,只需要任意连接集群中的一个可用节点即可
- 槽位 slot 负责分配到各个物理服务节点,由对应的集群来维护各个槽位、节点、数据之间的关系
8.3 槽位
redis 集群有16384个哈希槽。每个key通过CRC16校验后对16384取模来决定放置到哪个槽,集群中的每个节点负责一部分hash槽。
8.4 分片
使用 redis 集群存储数据时,我们会将数据分散到多台 redis 机器上,这就是分片。
8.5 哈希槽映射
- 哈希取余分区
hash(key) % N个机器台数,取模的值决定将数据映射到哪个节点上。
优点:简单高效
缺点:扩容缩容时客户端到服务端的映射发生改变
- 一致性哈希算法分区
一致性哈希算法在1997年由麻省理工学院中提出的,设计目标是为了解决分布式缓存数据变动和映射问题,某个机器宕机了,分母数量改变了,自然取余数不OK了。
①算法构建一致性哈希环:
②服务器节点映射
③Key 落到服务器的落键规则
优点:容错性、扩展性
缺点:数据倾斜问题
- 哈希槽分区
哈希槽实质就是一个数组,数组[0, 2^14 -1] 形成哈希槽空间。
哈希槽的作用:
解决数据均匀分配的问题,在数据和节点之间又加了一层,把这层称为哈希槽,用于管理数据和节点之间的关系。
一个集群只能有16384(2^14)个槽,对 key 取哈希值,然后对 16384 取模,余数是几,key就落到对应的槽里。因为槽的数量是固定的,所以移动数据比较容易。
为什么最大哈希槽数是16384?
①redis 每秒都要发送心跳包,如果槽位是2^16(65536),消息头达8k(65536/8/1024),过于庞大,浪费带宽
②redis 集群中主节点数量基本不可能超过1000个,16384个槽位基本够用了。
③槽位越小,节点少的情况下,压缩比高,容易传输
8.6 搭建 redis 集群
- 开启集群功能
port 7000
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
- 构建集群关系
redis-cli --cluster create 127.0.0.1:7000 127.0.0.1:7001
127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005
--cluster-replicas 1
// 选项 --cluster-replicas 1 表示为每一个主服务器配一个从服务器
- 查看集群信息
// 查看主从关系
info replication
// 查看某一个节点的集群信息
cluster info
// 查看集群节点关系
cluster nodes
redis 集群搭建实例待补充!
参考视频:尚硅谷Redis零基础到进阶,最强redis7教程,阳哥亲自带练(附redis面试题)_哔哩哔哩_bilibili