redis 简单整理——开发和运维中的问题[二十四]
前言
简单介绍一下开发和运维中的问题。
正文
从上文中介绍了,我们有了一个副本了,通过复制的方式。
这些副本可以应用于读写分 离、故障转移(failover)、实时备份等场景。
那么可以关注一些开发和运维的一些问题。
对于读占比较高的场景,可以通过把一部分读流量分摊到从节点 (slave)来减轻主节点(master)压力,同时需要注意永远只对主节点执行 写操作。
当然了,默认从节点是写不了的。
当使用从节点响应读请求时,业务端可能会遇到如下问题:
·复制数据延迟。
·读到过期数据。
·从节点故障。
1.数据延迟
Redis复制数据的延迟由于异步复制特性是无法避免的,延迟取决于网络带宽和命令阻塞情况,比如刚在主节点写入数据后立刻在从节点上读取可能获取不到。
需要业务场景允许短时间内的数据延迟。对于无法容忍大量延 迟场景,可以编写外部监控程序监听主从节点的复制偏移量,当延迟较大时 触发报警或者通知客户端避免读取延迟过高的从节点.
1)监控程序(monitor)定期检查主从节点的偏移量,主节点偏移量在 info replication的master_repl_offset指标记录,从节点偏移量可以查询主节点 的slave0字段的offset指标,它们的差值就是主从节点延迟的字节量。
2)当延迟字节量过高时,比如超过10MB。监控程序触发报警并通知客户端从节点延迟过高。可以采用Zookeeper的监听回调机制实现客户端通知。
3)客户端接到具体的从节点高延迟通知后,修改读命令路由到其他从节点或主节点上。当延迟恢复后,再次通知客户端,恢复从节点的读命令请求。
这种方案的成本比较高,需要单独修改适配Redis的客户端类库。如果 涉及多种语言成本将会扩大。
客户端逻辑需要识别出读写请求并自动路由, 还需要维护故障和恢复的通知。采用此方案视具体的业务而定,如果允许不 一致性或对延迟不敏感的业务可以忽略,也可以采用Redis集群方案做水平扩展.
2.读到过期数据
当主节点存储大量设置超时的数据时,如缓存数据,Redis内部需要维 护过期数据删除策略,删除策略主要有两种:惰性删除和定时删除
惰性删除:主节点每次处理读取命令时,都会检查键是否超时,如果超 时则执行del命令删除键对象,之后del命令也会异步发送给从节点。需要注 意的是为了保证复制的一致性,从节点自身永远不会主动删除超时数据.
定时删除:Redis主节点在内部定时任务会循环采样一定数量的键,当 发现采样的键过期时执行del命令,之后再同步给从节点.
如果此时数据大量超时,主节点采样速度跟不上过期速度且主节点没有 读取过期键的操作,那么从节点将无法收到del命令。这时在从节点上可以读取到已经超时的数据。Redis在3.2版本解决了这个问题,从节点读取数据 之前会检查键的过期时间来决定是否返回数据,可以升级到3.2版本来规避 这个问题。
3.从节点故障问题
对于从节点的故障问题,需要在客户端维护可用从节点列表,当从节点 故障时立刻切换到其他从节点或主节点上。这个过程类似上文提到的针对延 迟过高的监控处理,需要开发人员改造客户端类库。
综上所出,使用Redis做读写分离存在一定的成本。
Redis本身的性能非 常高,开发人员在使用额外的从节点提升读性能之前,尽量在主节点上做充 分优化,比如解决慢查询,持久化阻塞,合理应用数据结构等,当主节点优 化空间不大时再考虑扩展。
笔者建议大家在做读写分离之前,可以考虑使用 Redis Cluster等分布式解决方案,这样不止扩展了读性能还可以扩展写性能 和可支撑数据规模,并且一致性和故障转移也可以得到保证,对于客户端的维护逻辑也相对容易。
主从配置不一致
主从配置不一致是一个容易忽视的问题。对于有些配置主从之间是可以不一致,比如:主节点关闭AOF在从节点开启。
但对于内存相关的配置必须 要一致,比如maxmemory,hash-max-ziplist-entries等参数。
当配置的 maxmemory从节点小于主节点,如果复制的数据量超过从节点maxmemory 时,它会根据maxmemory-policy策略进行内存溢出控制,此时从节点数据已 经丢失,但主从复制流程依然正常进行,复制偏移量也正常。修复这类问题也只能手动进行全量复制。
当压缩列表相关参数不一致时,虽然主从节点存 储的数据一致但实际内存占用情况差异会比较大。
规避全量复制
全量复制是一个非常消耗资源的操作,前面做了具体说明。因此如何规 避全量复制是需要重点关注的运维点。下面我们对需要进行全量复制的场景 逐个分析:
1.第一次建立复制:由于是第一次建立复制,从节点不包含任何主节点 数据,因此必须进行全量复制才能完成数据同步。对于这种情况全量复制无 法避免。当对数据量较大且流量较高的主节点添加从节点时,建议在低峰时 进行操作,或者尽量规避使用大数据量的Redis节点。
2.节点运行ID不匹配:当主从复制关系建立后,从节点会保存主节点的 运行ID,如果此时主节点因故障重启,那么它的运行ID会改变,从节点发现 主节点运行ID不匹配时,会认为自己复制的是一个新的主节点从而进行全量 复制。对于这种情况应该从架构上规避,比如提供故障转移功能。当主节点 发生故障后,手动提升从节点为主节点或者采用支持自动故障转移的哨兵或 集群方案。
3.·复制积压缓冲区不足:当主从节点网络中断后,从节点再次连上主节 点时会发送psync{offset}{runId}命令请求部分复制,如果请求的偏移量不在 主节点的积压缓冲区内,则无法提供给从节点数据,因此部分复制会退化为 全量复制。针对这种情况需要根据网络中断时长,写命令数据量分析出合理 的积压缓冲区大小。网络中断一般有闪断、机房割接、网络分区等情况。这 时网络中断的时长一般在分钟级(net_break_time)。写命令数据量可以统 计高峰期主节点每秒info replication的master_repl_offset差值获取(write_size_per_minute)。积压缓冲区默认为1MB,对于大流量场景显然 不够,这时需要增大积压缓冲区,保证 repl_backlog_size>net_break_time*write_size_per_minute,从而避免因复制积 压缓冲区不足造成的全量复制。
规避复制风暴
复制风暴是指大量从节点对同一主节点或者对同一台机器的多个主节点 短时间内发起全量复制的过程。复制风暴对发起复制的主节点或者机器造成 大量开销,导致CPU、内存、带宽消耗。因此我们应该分析出复制风暴发生 的场景,提前采用合理的方式规避。规避方式有如下几个。
1.单主节点复制风暴一般发生在主节点挂载多个从节点的场景。当主节点 重启恢复后,从节点会发起全量复制流程,这时主节点就会为从节点创建 RDB快照,如果在快照创建完毕之前,有多个从节点都尝试与主节点进行全 量同步,那么其他从节点将共享这份RDB快照。这点Redis做了优化,有效 避免了创建多个快照。但是,同时向多个从节点发送RDB快照,可能使主节 点的网络带宽消耗严重,造成主节点的延迟变大,极端情况会发生主从节点 连接断开,导致复制失败。 解决方案首先可以减少主节点(master)挂载从节点(slave)的数量, 或者采用树状复制结构,加入中间层从节点用来保护主节点.
从节点采用树状树非常有用,网络开销交给位于中间层的从节点,而不 必消耗顶层的主节点。但是这种树状结构也带来了运维的复杂性,增加了手 动和自动处理故障转移的难度。
2.单机器复制风暴
由于Redis的单线程架构,通常单台机器会部署多个Redis实例。当一台 机器(machine)上同时部署多个主节点(master)时:
如果这台机器出现故障或网络长时间中断,当它重启恢复后,会有大量 从节点(slave)针对这台机器的主节点进行全量复制,会造成当前机器网 络带宽耗尽。
如何避免?方法如下:
·应该把主节点尽量分散在多台机器上,避免在单台机器上部署过多的 主节点。
·当主节点所在机器故障后提供故障转移机制,避免机器恢复后进行密 集的全量复制。
总结
1)Redis通过复制功能实现主节点的多个副本。从节点可灵活地通过 slaveof命令建立或断开复制流程。
2)复制支持树状结构,从节点可以复制另一个从节点,实现一层层向 下的复制流。Redis2.8之后复制的流程分为:全量复制和部分复制。全量复 制需要同步全部主节点的数据集,大量消耗机器和网络资源。而部分复制有 效减少因网络异常等原因造成的不必要全量复制情况。通过配置合理的复制 积压缓冲区尽量避免全量复制。
3)主从节点之间维护心跳和偏移量检查机制,保证主从节点通信正常 和数据一致。
4)Redis为了保证高性能复制过程是异步的,写命令处理完后直接返回 给客户端,不等待从节点复制完成。因此从节点数据集会有延迟情况。
5)当使用从节点用于读写分离时会存在数据延迟、过期数据、从节点可用性等问题,需要根据自身业务提前作出规避。
6)在运维过程中,主节点存在多个从节点或者一台机器上部署大量主节点的情况下,会有复制风暴的风险。
结
下一大节,redis的阻塞。
redis 简单整理——开发和运维中的问题[二十四]的更多相关文章
- IOS开发---菜鸟学习之路--(二十四)-iOS7View被导航栏遮挡问题的解决
(此文为复制帖,原文地址为:http://blog.sina.com.cn/s/blog_a8192bdd0101af40.html) self.navigationController.naviga ...
- DevOps的故事(如何整合开发和运维?)
在一个与我们平行的世界中,有一个软件开发公司.这个公司所做的产品用户量近期增长的十分迅猛,但是令CTO头疼的是公司的两大部门:开发部和运维部近期也是“掐”得厉害.为解决这个问题,CTO决定倒入现在十分 ...
- 二十四、Struts2中的UI标签
二十四.Struts2中的UI标签 Struts2中UI标签的优势: 数据回显 页面布局和排版(Freemark),struts2提供了一些常用的排版(主题:xhtml默认 simple ajax) ...
- python3.4学习笔记(二十四) Python pycharm window安装redis MySQL-python相关方法
python3.4学习笔记(二十四) Python pycharm window安装redis MySQL-python相关方法window安装redis,下载Redis的压缩包https://git ...
- 设计模式学习(二十四):Spring 中使用到的设计模式
设计模式学习(二十四):Spring 中使用到的设计模式 作者:Grey 原文地址: 博客园:设计模式学习(二十四):Spring 中使用到的设计模式 CSDN:设计模式学习(二十四):Spring ...
- 重新整理 .net core 实践篇————polly失败重试[三十四]
前言 简单整理一下polly 重试. 正文 在开发程序中一般都有一个重试帮助类,那么polly同样有这个功能. polly 组件包: polly 功能包 polly.Extensions.Http 专 ...
- SpringBoot进阶教程(二十四)整合Redis
缓存现在几乎是所有中大型网站都在用的必杀技,合理的利用缓存不仅能够提升网站访问速度,还能大大降低数据库的压力.Redis提供了键过期功能,也提供了灵活的键淘汰策略,所以,现在Redis用在缓存的场合非 ...
- 重新整理 .net core 实践篇—————3种配置验证[十四]
前言 简单整理一些配置的验证. 正文 配置的验证大概分为3类: 直接注册验证函数 实现IValidteOptions 使用Microsoft.Extensions.Options.DataAnnota ...
- 重新整理 .net core 实践篇—————工作单元模式[二十六]
前言 简单整理一下工作单元模式. 正文 工作单元模式有3个特性,也算是其功能: 使用同一上下文 跟踪实体的状态 保障事务一致性 工作单元模式 主要关注事务,所以重点在事务上. 在共享层的基础建设类库中 ...
- 性能测试二十四:环境部署之Redis多实例部署
由于redis服务端是单线程实现的,因此只能占用CPU的单核,为了充分利用CPU资源,可以在一台服务器上同时启动多个redis-server实例 首先删除之前的rdb.aof文件 注释掉3个save ...
随机推荐
- 文心一言 VS 讯飞星火 VS chatgpt (208)-- 算法导论15.4 5题
五.设计一个 O($n^2$) 时间的算法,求一个 n 个数的序列的最长单调递增子序列.要写代码的时候,请用go语言. 文心一言,抛panic: 在 Go 语言中设计一个 O(n^2) 时间复杂度的算 ...
- SemanticKernel如何基于自有数据聊天
效果 使用gpt-3.5-turbo的效果 什么是向量数据库? 向量数据库是一种专为处理高维向量数据而设计的数据库系统.与传统的关系型数据库不同,向量数据库专注于存储和查询向量数据,例如图像.音频.文 ...
- C++ //栈 stack 容器 先进后出 不允许遍历
1 //栈 stack 容器 先进后出 不允许遍历 2 3 4 #include<iostream> 5 #include<stack> 6 7 using namespace ...
- acme.sh 免费泛解析证书生成
环境准备 本篇文章使用的 ACME 客户端是基于 Docker 容器使用的,所以需要准备 Docker 运行环境.本文使用的是 CentOS 7.x 与 Docker CE - 19.03.13,且已 ...
- 新零售SaaS架构:什么是线上商城系统?
零售商家为什么要建设线上商城 传统的实体门店服务范围有限,只能吸引周边500米内的消费者.因此,如何拓展服务范围,吸引更多消费者到店,成为了店家迫切需要解决的问题. 缺乏忠实顾客,客户基础不稳,往往是 ...
- Vue 动态插入组件 用js函数的方式
Vue 动态插入组件 用js函数的方式 第一步 import vue组件 第二步 Vue把组件扩展进去 第三步 创建实例 第四步 将组件的el挂载到document.body上 第五步 设置组件内部d ...
- Dreamweaver基础教程:学习HTML
目录 HTML简介 HTML实例 HTML 标签 HTML元素 HTML 属性 HTML网页结构 <!DOCTYPE> 声明 HTML 基础 HTML 标题 HTML 段落 HTML 链接 ...
- python计算二进制bin文件hash值
一 hash的价值 hash值的唯一性仅仅在是同一个文件的情况下得到了同样的hash值,而哪怕错误一个字节也会得到不一样的hash值. hash值得最大价值就是唯一性.这样在bin文件检查和校验这块用 ...
- rancher添加用户报错x509: certificate has expired Internal error occurred: failed calling webhook "rancherauth.cattle.io":
错误信息: Internal error occurred: failed calling webhook "rancherauth.cattle.io": Post https: ...
- uniapp踩坑记录
sessionStorage.setItem('token', data.msg)uni.setStorage('token', res.data); 搞了半天登录后直接通过获取getstorage获 ...