【Redis技术】

发布于:2022-08-06 ⋅ 阅读:(298) ⋅ 点赞:(0)

1.Redis基础

Redis是一种基于键值对(key-value)的NoSql数据库。

  1. 速度快-数据全部置于内存中
  2. 支持多种数据结构-基于键值对,String,List,Set,Zset,Hash几种基础数据结构,以及Bitmaps,HyperLogLog,GEO
  3. 功能丰富-除了了丰富的数据结构还提供了许多额外的功能。键过期、发布订阅、简单事务、流水线

字符串String

在这里插入图片描述

–基础命令–
incr key -键值+1,原值需要为整
decr key -键值-1,原值需为整
incrby key amount-键值+amount,原值需为整
decrby key amount-键值- amount,原值需为整
incrbyfloat key amount -键值+amount可为浮点数

列表List

在这里插入图片描述

----基础命令—
rpush key value1 [value2 …] -将1个或多个值推入列表右端
lpush key value1 [value2 …]
rpop key -移除并返回列表最右端元素
lpop key
lindex key offset -返回列表中偏移量为offset的元素,第一个是0,可为负
lrange key start end -返回列表中从start到end的所有元素[start, end]闭区间
ltrim key end -对列表进行裁剪只保留偏移量[start, end]区间内的元素
----阻塞式命令—
blpop
brpop
rpoplpush
brpoplpush

集合Set

在这里插入图片描述

sadd key itm [item …] -添加1个或多个元素,返回被添加的原来不存在的数量
srem key item [item …] -移除1个或多个元素,返回被移除的个数
sismember key item -检查item是否是set中的元素
scard key -返回set中元素数量
smembers key -返回set中所有元素
srandmember key [count] -从set中随机返回1个或多个元素。当count>0返回不重复,否则可能会重复
spop key -随机移除集合中一个元素,并返回该元素
smov key1 key1 item –如果key1中包含元素item则移入key2加粗样式,成功移除返回1,否则0
sdiff key1 [key2 …] -返回存在于key1,但不存在与其他集合中的元素。(求差集)
sdiffstore destKey key1 [key2 …] -将存在于key1,但不存在与其他集合中的元素存储到destKey

有序集合ZSet

在这里插入图片描述

** zadd key score1 member1 [score2 member2 …]** –将1个或多个带有分值的成员添加到有序集合中
zrem key member1 [member2 …] –移除一个或多个成员,返回移除的个数
**zcard key -返回成员数量
zincrby key increment member -将成员的分值增加increment后返回,若成员不存在则新增
zcount key min max -返回分值介于[min, max]之间的成员数量。
zrank key member -返回成员在集合中的排名,从小到大的排名,从0开始
zscore key member -返回成员分值
zrange key start stop [withscores] -返回有序集合中排名(按分值升序)介于[start, stop]之间的成员,给出可选项withscores时表示分数一并返回。(start可从0开始)
zrevrange key start stop [withscores] 同上,降序

哈希Hash

在这里插入图片描述

hset key field value -向散列中添加或更新一个字段的值
hget key field -获取散列中一个字段的值
hmset key field1 value1 [field2 value2 …] -向散列中添加/更新一个或多个键的值
hmget key field1 [field2 …] ** 获取1个或多个键的值
hdel key field1 [field2 …]
-删除散列中的1个或多个键值对,返回成功删除的个数
hlen key -返回散列中包含键值对的数量
hexists key field –检查给定的字段field是否存在于散列中,是返回1,否0
hkeys key -返回散列中的所有字段名
hvals key -返回散列中的所有字段值
hgetall key -获取散列中所有键值对
hincrby key field increment –将散列中字段加上整数increment,并返回新值(需要原值就是整数;若原来不存在字段则直接添加)
hincrbyfloat key field increment -将散列中字段加上数值increment,并返回新值(若原来不存在字段则直接添加)

2.数据安全和持久化

Redis数据全部存放于内存中,保证了高性能,进程意外退出时会丢失全部数据。Redis通过提供持久化机制能够有效避免因进程退出造成的数据丢失问题。
RDB(快照方式)
AOF(只追加文件方式)
两种方式都能完成数据的备份和恢复。可以根据具体场景选择一种、两种同时使用、或根本不持久化

2.1 RDB快照

RDB快照持久化是Redis默认采用的持久化方式,将某一时刻的所有数据写入硬盘。在创建之后,可以对快照文件进行备份

在这里插入图片描述

创建RDB快照的几种方式

  1. 手动bgsave命令,fork创建子进程将快照写入硬盘,父进程继续处理命令和请求(阻塞只发生在fork阶段);
  2. 手动save命令,接收save命令的redis服务在创建完成快照之前将不再响应任何其他命令。save很少用,只在没有足够内存bgsave或save期间停止对外服务无所谓时才使用;
  3. 根据配置文件中save配置,(例如save 60 100 在60秒内发生100次修改时自动触发bgsave)满足条件时自动触发bgsave;
  4. 接受shutdown命令或者标准tem信号时,会执行save命令并阻塞所有客户端;
  5. 当一个redis连接另一个redis,并发送sync开始一次复制时,若主redis当前没有正在执行bgsave或并非刚刚执行完bgsave操作,那么主redis就会执行bgsave命令。

!!!如果系统崩溃,用户将丢失最近一次生成快照后更改的所有数据。若不能接受,则需要考虑AOF方式

bgsave是主流的触发RDB持久化方式。bgsave过程:

bgsave生成rgb快照过程
rdb优点:

  1. 紧凑的压缩二进制文件,是某时刻数据的快照,适用于备份,全量复制;
  2. redis加载rdb远远快于aof

rdb缺点:

  1. 无法做到实时持久化/秒级持久化。bgsave每次执行fork,是重量级操作,频繁执行成本
  2. rdb采用二进制文件,redis演进过程有多个格式的rdb版本,可能存在兼容问题

2.2 AOF只追加文件持久化

Redis在执行写命令时将被执行的写命令复制到硬盘里,每次追加到AOF文件末尾。
Redis默认不开启aof持久化,若要开启,需要修改配置文件后重启节点:
在这里插入图片描述
AOF过程:

在这里插入图片描述
AOF过程:

  1. 所有的写入命令追加到aof_buf缓冲区中;
  2. aof缓冲区根据对应的配置策略向硬盘同步;
  3. 随着aof越来越大,定期重写aof文件,实现压缩
  4. redis重启时可以加载aof文件恢复数据

2.3 持久化数据恢复

若开启了持久化配置,则redis在下次启动时就会加载持久化文件数据到内存中,实现数据恢复

在这里插入图片描述
redis重启数据恢复过程:

  1. aof开启,则优先加载aof文件(此时若aof不存在也不会去加载rdb文件);
  2. aof没开启则去加载rdb文件;
  3. 若aof文件或rdb文件存在错误,启动则失败

3.主从复制

单机模式一般不会用于生产,只在学习和测试中使用。在分布式系统中为了解决单点问题,通常把数据复制多个副本部署到其他服务器,满足故障恢复和负载均衡的需求。Redis也是如此,通过提供复制功能实现多个Redis副本。

3.1 一主一从

复制是高可用Redis的基础,哨兵和集群模式都是在复制的基础上实现。
几种常见的主从复制拓扑结构
一主一从
一主多从
树状结构

一主一从-最简单的主从复制结构,用于主节点宕机时从节点提供故障转移支持。

在这里插入图片描述
TIPS: 当应用写命令高并发且需要持久化时,可以只在从节点上开启aof,此时主节点不持久化,由从节点完成持久化,在保证数据安全的同时避免了持久化操作对主节点的性能干扰(!!!此时主节点宕机时应避免自动重启操作,否则自动重启后数据集为空,从节点继续复制时数据也被清空,相当于没有持久化,安全的做法是在从节点执行slave of no one断开与主节点的联系)。

一主多从-一个主节点拥有多个从节点。
可以利用多个从节点实现读写分离。对于读占比大的场景,可以把读命令发送到从节点分担主节点压力,对于一些比较耗时的读命令如keys、sort等也可以在一台从节点执行,防止慢查询对主节点造成阻塞影响服务稳定性。对于写占比大的场景,多个从节点会导致主节点的写命令频繁的同步过渡消耗带宽,影响主节点的稳定性。

在这里插入图片描述

树状主从-从节点可以拥有自己的从节点。
通过引入复制中间层,可以有效减少主节点负载和需要传送给从节点的数据量,避免对主节点性能的影响。
在这里插入图片描述

3.2 从节点复制过程

在这里插入图片描述
复制过程:

  1. 从节点保存主节点信息;
  2. 从节点内部定时任务维护复制相关逻辑,发现新节点后,尝试与新节点建立连接,专门用于接收主节点发送的复制命令;
  3. 发送ping命令根据主节点返回(pong)判断主从连接是否可用,可用则继续复制过程,否则断开连接,下次定时任务从上一步开始重连;
  4. 权限验证,若主节点开启了requirepass参数,则从节点需要配置masterauth参数配置与主节点相同的密码才能连接成功;
  5. 同步数据集。主从连接后进行数据复制,首次复制主节点发送全部数据(耗时)
    注: 老版本的redis使用sync命令完成首次全量同步,一次性发送所有数据;redis2.8以后提供psync命令支持部分复制;
  6. 命令持续复制。首次复制完成后,主节点持续不断的把写命令发送给从节点,保证数据一致性。

名词: 复制积压缓冲区-用于增量复制和断连后的数据补偿
!!!: 全量复制是耗时操作:主节点bgsave生成RDB+网络传输rdb+从节点清空数据+从节点加载rdb+从节点开始aof时的aof重写

复制存在的问题:

  1. 在主从模式下,主节点故障后需要人工选择一个从节点晋升为主节点,还要命令其他从节点复制新的主节点(老的主节点恢复后设置为新的从节点),同时需要客户端更新主节点地址,无论从时效性还是影响范围都是无法接受的;
  2. 主节点的写能力受到单机的限制(只有主节点允许写入);
  3. 主节点的存储能力受到单机限制,因为每个节点都存储了全量数据

4. 哨兵模式Sentinel

在主从模式下,主节点故障后需要人工介入将从节点晋升为主节点(老的主节点恢复后设置为新的从节点),同时需要客户端更新主节点地址,无论从时效性还是影响范围都是无法接受的。

哨兵模式是redis真正可实施的高可用实现方案。通过引入哨兵节点,将复制模式下的故障转移自动完成。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
与主从模式相比,哨兵模式只是多了若干哨兵节点,哨兵节点对所有节点进行监控(哨兵之间也会相互监控),并且在主节点发生故障的情况下能够完成自动故障转移,且对客户端是无感的。

哨兵任务

  1. 监控
  2. 通知应用方
  3. 主节点故障转移(整个过程和主从模式下的人工操作完全一样,只不过是全自动的)
  4. 配置提供者(客户端配置的是哨兵节点集合)。

!!!: 哨兵不应在同一台物理机器上;哨兵应为奇数个且至少3个

5. 集群模式Cluster

在哨兵模式下,每个节点上都存放了全量的数据,在数据规模不大时可以使用哨兵模式。但在数据量巨大时,哨兵模式便无法很好的运行,且哨兵模式所有的写操作都在主节点完整,无法很好的应对持续高并发写场景。Redis提供了cluster集群分布式解决方案。

实现了数据分区,每个节点负责整体数据的一个子集,所有数据的集合组成全量数据。当数据量大时可以十分灵活的横向扩容增大数据承载能力
集群中每个主节点都可接收处理读写命令,真正做到了负责均衡。当压力大时亦能通过增加节点实现扩容增大请求负责能力

在这里插入图片描述
集群相对于单机模式某些功能存在一定限制

  1. key批量支持操作有限;
  2. Key事务操作支持有限;
  3. key作为数据分区的最小粒度,大键值对象如hash,list落在一个节点;
  4. 不支持多数据库空间,单机redis16个库,cluster下只能用一个数据库空间db 0;
  5. 复制结构只支持一层,从节点不允许级联。

集群数据分布
RedisCluster采用虚拟槽分区,所有的键根据哈希函数映射到0-16383整数槽上(公式slot=CRC16(key)&16383),而每个节点负责一部分槽以及槽内的数据(下图已5个节点为例):
在这里插入图片描述

5.1 集群搭建

在这里插入图片描述

  1. 节点准备
    修改配置开启集群模式
    启动所有节点
  2. 节点握手
    集群模式下节点通过Gossip协议彼此通信,感知对方过程
    初次启动所有节点后,在任意一个节点上执行命令 cluster meet ipN portN握手所有其他节点而后节点信息就会在整个集群传播。最终达到一致
    握手后集群处于下线状态,需要将所有的槽分配后才可用
  3. 分配槽
    为所有主节点分配所有的槽(0-16383 )命令redis-cli -h ipN –p portN {0…3276}
    将所有槽都分配完成后集群进入在线状态
    为所有主节点分配从节点(生产上cluster集群节点应至少由6个节点,3主3从)在从节点上执行cluster replicate nodeId(所属主节点的nodeId)

备注: 以上整个过程通过命令手动完成,可以借助redis-trib.rb来更方便的完成

  1. 依然配置好所有节点并启动
  2. 通过redis-trib.rb create命令完成握手和槽分配过程 redis-trib.rb create –repicas 1 ip1:port1 ip2:port2 ipN:portN*

5.2 节点通讯

  • meet消息:用于通知新节点加入,发送者通知接收者加入到当前集群 ping消息:集群内交换最频繁的信息,用于检测节点状态和交换彼此信息。
  • ping消息:发送封装自身节点和部分其他节点的状态数据
  • pong消息:当收到ping、meet时作为响应恢复给对方的消息
  • fail消息:节点判断集群内另一个节点下线时会向集群内广播一个fail消息

5.3 集群扩缩容

  • 集群扩容
  1. 准备新节点,修改配置并启动
  2. 新节点加入集群,通过前文所述的握手方式
  3. 迁移槽和数据-迁移计划应保证槽的分布相对均匀
  • 集群收缩
  1. 下线节点需要将自己负责的槽迁移到其他节点(若下线从节点,则直接忘记即可)
  2. 忘记节点
本文含有隐藏内容,请 开通VIP 后查看