Redis 原理与实战

  • 持久化
    • Redis 持久化 - RDB
    • Redis 持久化 - AOF
      • AOF 文件重写机制
  • Redis 高可用
    • Redis 主从复制
      • 搭建主从复制环境
      • 全量复制和部分复制
    • Redis 哨兵 (Sentinel)
      • 搭建哨兵集群环境
    • Redis Cluster
      • Hash 分布
      • 配置集群 - 原生命令安装(了解)
      • 配置集群 - 官方工具安装

Java 从 0 到架构师目录:【Java从0到架构师】学习记录

参考:Redis 中两种持久化机制详解

持久化

Redis 所有的数据都是保存在内存中

  • 如果进行了持久化,对数据的更新将异步或者同步的保存到磁盘上
  • 持久化可以避免数据丢失,对数据进行备份,还可以还原指定时间的数据

持久化的方式

  • 快照:MySQL dump、Redis RDB、Oracle dump
  • 写日志:MySQL Binlog、Redis AOF

混合持久化内容的 AOF 文件:

appendonly yes # 开启aof模式
aof-use-rdb-preamble yes # 使用rdb和aof的混合模式, 高版本默认开启

Redis 持久化 - RDB


触发方式:

  • save(同步):如果存在老的 rdb 文件,新的文件会替换老的文件
  • bgsave(异步):Redis 会调用 fork 来创建一个子进程
  • 自动配置:在配置文件中配置快照触发的条件
    saev 900 1
    save 300 10
    save 60 10000
    

    save 900 1 表示 900s 内,执行了 1次 数据库操作则自动创建快照,以此类推

触发机制

  • 全量复制
  • debug reload
  • shutdown

相关配置:

save 900 1 # 15分钟内有1个key进行修改
save 300 10 # 5分钟类有10个key进行修改
save 60 10000 # 1分钟内有10000个key进行修改dbfilename dump_6379.rdb  # 备份文件
dir /usr/local/redis-5.0.8/data # 备份目录
stop-writes-on-bgsave-error yes # 在出现错误的时候终止rdb备份, 默认yes
rdbcompression yes # 是否进行压缩, 默认yes
rdbchecksum yes # 是否进行检查sum值校验, 默认yes

RDB 方式的不足之处:耗时,耗费 IO 性能

Redis 持久化 - AOF


AOF 的三种策略:

  • always:每个 redis 写命令都要同步写入硬盘,严重降低 redis 速度(慎用)
    该策略不会丢失数据,但是 IO 开销很大
  • everysec:每秒同步一次缓冲区的命令到硬盘(推荐,也是默认策略)
    该策略和不使用持久化时的性能几乎无差别,即时系统奔溃也最多丢失 1 秒的数据
  • no:由操作系统决定何时将缓冲区的命令写到硬盘(不推荐)
    该策略是不可控的

AOF 文件重写机制

AOF 方式会使得持久化的文件变的越来越大,AOF 重写机制可以在一定程度下减少磁盘占用量

客户端方式执行重写:BGREWRITEAOF

服务器配置自动重写:

appendonly yes # 是否开启aof文件模式
appendfilename "appendonly-6379.aof" # aof文件名称
appendfsync everysec # aof策略模式
dir usr/local/redis-5.0.8/data # 数据存储路径
no-appendfsync-on-rewrite yes # 在重写的时候, 不要执行aof操作
auto-aof-rewrite-percentage 100 # 自动重写的百分比
auto-aof-rewrite-min-size 64mb # 重写的大小配置
# 当AOF文件体积大于 64M,并且AOF文件的体积比上一次重写之后体积大了 100%(1倍) 时,自动触发重写

Redis 高可用

Redis 主从复制

单击的问题:机器故障引起单点故障,容量达到瓶颈、QPS 达到瓶颈

QPS (Queries Per Second):每秒查询率,是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准,即每秒的响应请求数,也就是最大吞吐能力

主从复制:

  • 一个 Master 可以有多个 Slave
  • 一个 Slave 只能有一个 Master
  • 数据流向是单向的,只能从 Master 流向 Slave
    只有 Master 可以进行写的操作,然后将数据复制到 Slave

主从复制的作用:

  • 避免单点故障
  • 读写分离:Master 节点写数据,然后复制到 Slave 节点,Slave 节点读数据
    (默认情况下 Slave 节点无法写数据)
  • 一主多从
  • 多副本

搭建主从复制环境

配置文件:

port 6380
daemonize yes
pidfile  /var/run/redis-6380.pid
logfile 6380.log
dbfilename dump_6380.rdb
dir /usr/local/redis-5.0.8/data/
# bind 192.168.52.128
# 局域网连接要指定 -h: redis-cli -h 192.168.52.128

目前情景:开启了两台 Redis 服务器,分别是 127.0.0.1:6379、127.0.0.1:6380,希望 6379 作为 Master 节点,6380 作为 Slave 节点,开启主从复制

  • 方法1:客户端主动执行

    # 以从服务器的身份来执行以下命令的
    # 直接从6379服务端口Master进行数据复制, 自身的数据清空, 然后再从Master复制数据
    slaveof 127.0.0.1 6379
    

    info replication 可以查看当前服务器的角色是 master 还是 slave

    # 脱离 slave 节点的身份, 但是数据会保留
    slaveof no one
    
  • 方法2:服务器配置自动成为 slave 节点

    replicaof 192.168.52.128 6379
    replica-read-only yes # 从节点只读,不能写
    

全量复制和部分复制

全量复制:

部分复制:

Redis 哨兵 (Sentinel)

主从复制在高可用中的问题:

  • 手动故障转移:Master 节点下线后,Slave 不会自动变成 Master
  • 写能力和存储能力受限

哨兵机制集群 - 架构图:

搭建哨兵集群环境

哨兵机制架构规划:

配置开启主从节点:

# 主节点配置 redis_7000.conf
port 7000
daemonize yes
pidfile /var/run/redis-7000.pid
logfile 7000.log
dir /usr/local/redis-5.0.8/data/
# 从节点配置  redis_7001.conf
port 7001
daemonize yes
pidfile  /var/run/redis-7001.pid
logfile 7001.log
dir /usr/local/redis-5.0.8/data/
replicaof 127.0.0.1 7000
#  redis_7002.conf
port 7002
daemonize yes
pidfile /var/run/redis-7002.pid
logfile 7002.log
dir /usr/local/redis-5.0.8/data/
replicaof 127.0.0.1 7000

配置开启 sentinel 监控主从节点:

# sentinel_26379.conf
port 26379
daemonize yes
pidfile /var/run/redis-sentinel-26379.pid
logfile "26379.log"
dir /usr/local/redis-5.0.8/data/
# 告诉sentinel去监听地址为ip:port的一个master, 2个sential认为一个master失效才会真正失效
sentinel monitor mymaster 127.0.0.1 7000 2
# sentinel判断失效的时间
sentinel down-after-milliseconds mymaster 30000
# 最多1个slave对master进行同步
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
sentinel deny-scripts-reconfig yes
# sentinel_26380.conf
port 26380
daemonize yes
pidfile /var/run/redis-sentinel-26380.pid
logfile "26380.log"
dir /usr/local/redis-5.0.8/data/
sentinel monitor mymaster 127.0.0.1 7000 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
sentinel deny-scripts-reconfig yes
protected-mode no
# sentinel_26381.conf
port 26381
daemonize yes
pidfile /var/run/redis-sentinel-26381.pid
logfile "26381.log"
dir /usr/local/redis-5.0.8/data/
sentinel monitor mymaster 127.0.0.1 7000 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
sentinel deny-scripts-reconfig yes
protected-mode no

开启主从节点,哨兵节点:

# 启动主从节点服务器
bin/redis-server conf/redis_7000.conf
bin/redis-server conf/redis_7001.conf
bin/redis-server conf/redis_7002.conf# 启动哨兵节点服务器
bin/redis-sentinel conf/sentinel_26379.conf
bin/redis-sentinel conf/sentinel_26380.conf
bin/redis-sentinel conf/sentinel_26381.conf

通过查看日志可以看到监控信息:

然后进行一些操作,例如结束某个 redis-server:

redis-cli -p 7000 shutdown

然后查看主从节点信息:

# 在 redis-cli 执行以下操作可以查看主从节点信息
info replication

通过哨兵机制,实现了服务端高可用和客户端高可用

Redis Cluster

为什么需要使用集群?

  • 并发量:如果需要的并发量是 100w/s,单个服务的性能是 11w/s,那么就需要 10 个服务器集群同时提供服务
  • 数据量:如果需要存储更多的数据量,可以考虑使用 Redis 集群,集群中的每个服务器都存放一部分数据。如果一个服务存放的数据量是 200G,那么要存储 1T 的数据就需要 5 台服务器进行集群操作。
  • 网络流量:单台服务器的网卡流量是固定的,比如一个服务器的网卡是 1G,需要达到 10G 的网络流量速度,可以使用 10 台服务器集群。

数据分布:对于大量数据,想要存储到不同的节点,是需要按照某种规则的

  • 顺序分区:确定好所有的数据,把数据按照顺序放到不同的服务节点中,均匀分配
    特点:1. 数据容易倾斜 2. 键值分布和业务相关 3. 支持批量操作 4. 可以顺序访问
  • Hash 分区:确定好服务节点数量,根据每个数据的 key 计算对应的 hash 值(数字),对 hash 值进行取模操作(模的值为服务节点数量),根据取模结果把数据存放到对应的服务节点
    特点:1. 数据分散度高 2. 键值分布业务无关 3. 支持批量操作 4. 无法顺序访问

Hash 分布

节点取余扩容:

一致性 Hash

虚拟槽分配:

配置集群 - 原生命令安装(了解)

集群规划图:

集群配置

port 7000
# 设置是否以守护进程开启
daemonize yes
dir /usr/local/redis-5.0.8/data
dbfilename dump_7000.dbf
logfile 7000.log
# 是否开启集群模式
cluster-enabled yes
# 集群节点的单独配置
cluster-config-file node_7000.conf
cluster-node-timeout 15000
# 设置什么情况下集群对外提供服务, yes表示集群节点都正常才对外提供服务
cluster-require-full-coverage no
bind 192.168.52.129
protected-mode no

快速根据已有文件替换字符并输出新文件:

sed 's/7000/7001/g' redis_7000.conf > redis_7001.conf
#sed 命令 替换字符串 写入新文件

启动集群

bin/redis-server conf/redis_7000.conf
bin/redis-server conf/redis_7001.conf
bin/redis-server conf/redis_7002.conf
bin/redis-server conf/redis_7003.conf
bin/redis-server conf/redis_7004.conf
bin/redis-server conf/redis_7005.conf# 查看服务状态
ps -ef |grep redis
netstat -ntlp# 查看集群状态,没有绑定ip可以不写-h(默认连接127.0.0.1)
bin/redis-cli -h 192.168.52.129 -p 7000 cluster info# 以集群模式连接客户端(-c)
bin/redis-cli -c -h 192.168.52.129 -p 7000
cluster info # 查看集群状态
cluster nodes # 查看集群中的节点

节点通信

# 或者以集群模式连接客户端后,直接执行 cluster meet ip port 命令
bin/redis-cli -h 127.0.0.1 -p 7000 cluster meet 192.168.52.129 7001
bin/redis-cli -h 127.0.0.1 -p 7000 cluster meet 192.168.52.129 7002
bin/redis-cli -h 127.0.0.1 -p 7000 cluster meet 192.168.52.129 7003
bin/redis-cli -h 127.0.0.1 -p 7000 cluster meet 192.168.52.129 7004
bin/redis-cli -h 127.0.0.1 -p 7000 cluster meet 192.168.52.129 7005# 查看集群信息
bin/redis-cli -p 7000 cluster info

分配 slot 卡槽

# 1 编写分配卡槽脚本 addslots.sh
# $1 代表第一个参数start=$1
end=$2
port=$3
for slot in `seq ${start} ${end}`
do./redis-cli -h 192.168.52.129 -p ${port} cluster addslots ${slot}
done# 2 执行脚本
sh addslots.sh 0 5460 7000
sh addslots.sh 5461 10922 7001
sh addslots.sh 10923 16383 7002

配置从节点

# 这里需要配置一个node节点的id信息
# a0502ceb7461f9b2ec99d440904cf4768a297c22
redis-cli -h 192.168.52.129 -p 7003 cluster replicate node1_id
# 50caaf79a5145b511eec6680ffa3355e4dbc9e73
redis-cli -h 192.168.52.129 -p 7004 cluster replicate node2_id
# 45713493b59ed5ed3cca4397fa13148cf6666efc
redis-cli -h 192.168.52.129 -p 7005 cluster replicate node3_id

配置集群 - 官方工具安装

# 同时杀死所有 redis-server 进程ps -ef | grep redis | grep -v grep | awk '{print $2}' | xargs kill -9# 清除上次配置的集群信息: 删除配置集群生成的日志
# 我配置的日志目录是 data, 因此进入 data 后执行 rm -rf *

使用官方工具安装,只需要执行集群配置启动集群的步骤,可以省略节点通信、分配 slot 卡槽,配置从节点的步骤。

集群配置、启动集群参考上面,下面直接进行安装:

# 通过命令进行安装
# --cluster-replicas 1 表示主从比例1:1, 即 一主一从
# --cluster-replicas 2 表示主从比例1:2, 即 一主两从
bin/redis-cli --cluster create 192.168.52.129:7000 192.168.52.129:7001 192.168.52.129:7002 192.168.52.129:7003 192.168.52.129:7004 192.168.52.129:7005 --cluster-replicas 1

【Java从0到架构师】Redis 进阶 - 持久化(RBD、AOF)、高可用(主从复制、哨兵机制、Cluster)相关推荐

  1. 【Java从0到架构师】Redis 进阶 - pipline、发布订阅、Bitmap、HyperLogLog、GEO

    Redis 原理与实战 Jedis 的基本使用 Redis 数据淘汰策略 Redis 进阶拓展 pipline - 命令批处理,减少大量命令的网络开销,提高操作性能 发布订阅 - subscribe ...

  2. 【Java从0到架构师】Redis 应用 - Jedis 基本使用、使用缓存的用户登陆、缓存常见问题

    Redis 原理与实战 Jedis 基本使用 Jedis 连接 Redis 服务器 Jedis 使用 pipeline Jedis 发布订阅 Jedis 使用 bitmap Jedis 使用 Hype ...

  3. 【Java从0到架构师】Redis 基础 - 数据类型

    Redis 原理与实战 Redis 基础 为什么 Redis 这么快? Redis 安装.启动 Redis 常用配置 Redis 数据类型 通用命令 String - value 可以是字符串.数值. ...

  4. 【Java从0到架构师(1),Java中高级面试题总结(全面)

    JSP 九大内置对象 MySQL 基础 + 多表查询 [Java从0到架构师]MySQL 基础 MySQL MySQL 的使用步骤 数据库的内部存储细节 GUI 工具 SQL 语句 DDL 语句 DD ...

  5. 【Java从0到架构师】SpringCloud - Hystrix、Zuul

    SpringCloud 基本概念 熔断和降级 服务雪崩效应 服务熔断与降级 - Hystrix SpringBoot 集成 Hystrix 熔断降级服务异常报警通知 重点属性 - 熔断隔离策略.超时时 ...

  6. 【Java从0到架构师】Dubbo 基础 - 设置启动时检查、直接提供者、线程模型、负载均衡、集群容错、服务降级

    Dubbo 分布式 RPC 分布式核心基础 分布式概述 RPC Dubbo Dubbo 入门程序 - XML.注解 部署管理控制台 Dubbo Admin 修改绑定的注册 IP 地址 设置启动时检查 ...

  7. 【Java从0到架构师】Nginx 拓展 - HTTPS支持、缓存、Http请求防盗链、限流、高可用(Keepalived)

    Nginx HTTPS 支持 SSL 证书 重写 - rewrite Nginx 跨域解决方案 Nginx 开启缓存 Http 请求防盗链 Nginx 限流方案 常见的限流策略 - 计数器算法.漏桶算 ...

  8. 【Java从0到架构师】项目实战 - 会话管理、EhCache、JWT、权限管理 Shiro、打包部署

    项目实战 - 权限管理 会话管理 客户端身份认证 - 基于 Cookie.Session 客户端身份验证 - 基于 token EhCache - 简单的缓存框架 JWT - 基于 JSON 的 to ...

  9. 【Java从0到架构师】Spring - 复杂对象、Converter

    复杂对象.Converter 创建过程比较复杂的对象 实例工厂 静态工厂 FactroyBean 引入外部配置文件 SpEL表达式 scope - 控制 bean 是否单例 Converter Spr ...

最新文章

  1. Hadoop fs命令详解
  2. 帝国cms怎么增加php,帝国CMS增加系统配置字段
  3. 怎么更新android 10.0,Android 10.0(Q OS)系统升级计划Androi
  4. 软考解析:2015年上半年下午试卷
  5. 标识符的命名规定java 0126
  6. wps表格里面计算机在哪里,“Excel表格软件在电脑上到哪里找?“电脑excle在哪里...
  7. 为Xen虚拟机扩容根文件系统(LVM)
  8. LoadRunner 中的 Unique Number 参数类型小结
  9. Linux(ubuntu)下打包 解压
  10. 清华大学计算机科学与技术专业设置,清华大学计算机科学与技术专业介绍
  11. 用JavaSocket编程开发聊天室,附超详细注释
  12. RS-485 接口电路--转载
  13. 32.768khz晶振应该接多大的电容
  14. python 进化树_进化树专题(七)| 进化树与不完全谱系分选
  15. Pandas(七)--分组、合并和连接
  16. 三大微分中值定理和洛必达法则、泰勒公式
  17. 基于httpx和pyside2的哔哩哔哩(bilibili)-视频下载程序
  18. 寂静之城——哀悼FeedBurner
  19. Required request body is missing: public错误
  20. 苹果手机与电脑互传文件(win10自带方法)

热门文章

  1. “一加一减”的两种说话技巧
  2. 头条鼓励内容营销吗?创作商品营销内容会不会限制推荐?
  3. 富文本编辑器KindEditor在前端JS的应用
  4. uni-app中的数据绑定
  5. 1045. 快速排序(25)-PAT乙级真题
  6. Junit单元测试/反射/注解
  7. 结局就在附近! (对于SQL Server 2008和SQL Server 2008 R2)
  8. collector_使用Data Collector进行SQL Server性能监视–第3部分–阅读报告
  9. springboot系列十二、springboot集成RestTemplate及常见用法
  10. Cuda beginning