Redis项目实战---应用及理论(二)---Redis集群原理
一、 Redis官方推荐集群方案:Redis Cluster
适用于redis3.0以后版本,
Redis群集数据分片
· Redis Cluster不使用一致的散列,而是使用不同形式的分片,其中每个键称之为 hash slot.。
Redis集群中有16384个散列槽,为了计算给定密钥的散列槽,我们只需采用密钥模数16384的CRC16。
Redis群集中的每个节点都负责哈希槽的子集,例如,拥有一个包含3个节点的集群,其中:
- 节点A包含从0到5500的散列槽。
- 节点B包含从5501到11000的散列槽。
- 节点C包含从11001到16383的散列槽。
这允许轻松添加和删除集群中的节点。例如,如果我想添加一个新节点D,我需要将一些哈希槽从节点A,B,C移动到D.同样,如果我想从群集中删除节点A,我只需移动A服务的哈希槽。到B和C.当节点A为空时,我可以完全从集群中删除它。
因为将哈希槽从一个节点移动到另一个节点不需要停止操作,添加和删除节点,或者更改节点所持有的哈希槽的百分比,所以不需要任何停机时间。
只要涉及单个命令执行(或整个事务或Lua脚本执行)的所有键都属于同一个哈希槽,Redis Cluster就支持多个键操作。用户可以通过使用称为哈希标记的概念强制多个密钥成为同一哈希槽的一部分。
Hash标签记录在Redis集群规范中,但要点是如果密钥中{}括号之间有子字符串,则只对字符串内部的内容进行哈希处理,例如this{foo}key并another{foo}key 保证位于相同的哈希槽中,并且可以在具有多个键作为参数的命令中一起使用。
Redis Cluster主从模型
为了在主节点子集发生故障或无法与大多数节点通信时保持可用,Redis Cluster使用主从模型,其中每个散列槽从1(主机本身)到N个副本(N) -1个额外的从节点)。创建集群时,每个主节点添加一个从节点,以便最终集群由作为主节点的A,B,C和作为从节点的A1,B1,C1组成。如果节点B出现故障,系统就能继续运行。节点B1复制B,B失败,集群将节点B1升级为新的主节点,并将继续正常运行。
注意,如果节点B和B1同时发生故障,Redis Cluster将无法继续运行。
Redis群集一致性保证
Redis Cluster无法保证强一致性。在某些条件下,Redis Cluster可能会丢失系统向客户端确认的写入。
Redis Cluster可能丢失写入的第一个原因是它使用异步复制。这意味着在写入期间会发生以下情况:
- 客户端写入master B.
- master B向客户端回复确定。
- master B将写入传播到其从设备B1,B2和B3。
(1)B在回复客户端之前并没有等待来自B1,B2,B3的确认,因为这对Redis来说是一个过高的延迟,所以如果客户端写了一些东西,B会确认写入,但是在崩溃之前能够将写入发送到其slave,其中一个slave(没有接收到写入)被提升为master ,永远丢失写入。
这与大多数数据库配置为每秒将数据刷新到磁盘的所发生的情况非常相似。同样,可以通过在回复客户端之前强制数据库刷新磁盘上的数据来提高一致性,但会导致性能过低。在Redis Cluster情况下,相当于同步复制。
解决办法,即需要在性能和一致性之间进行权衡。
Redis Cluster在绝对需要时支持同步写入,通过WAIT命令实现,这使得丢失写入的可能性大大降低,但即使使用同步复制,Redis Cluster也不会实现强一致性:在更复杂的情况下总是可以实现失败场景,无法接收写入的slave被选为master。
(2)还有另一个值得注意的情况是,Redis集群将丢失写入,这种情况发生在网络分区中,其中客户端与少数实例(至少包括主服务器)隔离。如,
以6个节点簇为例,包括A,B,C,A1,B1,C1,3个主站和3个从站。还有一个客户,我们称之为Z1。
在发生分区之后,可能在分区的一侧有A,C,A1,B1,C1,在另一侧有B和Z1。
Z1仍然可以写入B,它将接受其写入。如果分区在很短的时间内恢复,集群将继续正常运行。但是,如果分区持续足够的时间使B1在分区的多数侧被提升为主,则Z1发送给B的写入将丢失。
注意,Z1将能够发送到B的写入量存在maximum window:如果分区的多数方面已经有足够的时间将slave选为master,则少数端的每个主节点都会停止接受写入。
这段时间是Redis Cluster的一个非常重要的配置指令,称为节点超时。
节点超时过后,master被视为失败,可以由其中一个副本替换。类似地,在节点超时已经过去而主节点无法感知大多数其他主节点之后,它进入错误状态并停止接受写入。
2):如果一个实例(instance)距离最后一次有效回复 PING 命令的时间超过 down-after-milliseconds 选项所指定的值, 则这个实例会被 Sentinel 标记为主观下线。
3):如果一个Master被标记为主观下线,则正在监视这个Master的所有 Sentinel 要以每秒一次的频率确认Master的确进入了主观下线状态。
4):当有足够数量的 Sentinel(大于等于配置文件指定的值)在指定的时间范围内确认Master的确进入了主观下线状态, 则Master会被标记为客观下线
5):在一般情况下, 每个 Sentinel 会以每 10 秒一次的频率向它已知的所有Master,Slave发送 INFO 命令
6):当Master被 Sentinel 标记为客观下线时,Sentinel 向下线的 Master 的所有 Slave 发送 INFO 命令的频率会从 10 秒一次改为每秒一次
7):若没有足够数量的 Sentinel 同意 Master 已经下线, Master 的客观下线状态就会被移除。
若 Master 重新向 Sentinel 的 PING 命令返回有效回复, Master 的主观下线状态就会被移除。
主从复制:主节点负责写数据,从节点负责读数据,主节点定期把数据同步到从节点保证数据的一致性
备注:主从复制和哨兵机制需要进行手动配置。
三、Redis作为缓存应用问题及解决方案:
1)缓存穿透
- 对所有可能查询的参数以hash形式存储,在控制层先进行校验,不符合则丢弃。还有最常见的则是采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被这个bitmap拦截掉,从而避免了对底层存储系统的查询压力。
- 也可以采用一个更为简单粗暴的方法,如果一个查询返回的数据为空(不管是数据不存在,还是系统故障),我们仍然把这个空结果进行缓存,但它的过期时间会很短,最长不超过五分钟。
2)缓存雪崩
- 在缓存失效后,通过加锁或者队列来控制读数据库写缓存的线程数量。比如对某个key只允许一个线程查询数据和写缓存,其他线程等待。
- 可以通过缓存reload机制,预先去更新缓存,再即将发生大并发访问前手动触发加载缓存
- 不同的key,设置不同的过期时间,让缓存失效的时间点尽量均匀. 比如我们可以在原有的失效时间基础上增加一个随机值,比如1-5分钟随机,这样每一个缓存的过期时间的重复率就会降低,就很难引发集体失效的事件
- 做二级缓存,或者双缓存策略。A1为原始缓存,A2为拷贝缓存,A1失效时,可以访问A2,A1缓存失效时间设置为短期,A2设置为长期。
3)缓存击穿
4)缓存预热
- 直接写个缓存刷新页面,上线时手工操作下;
- 数据量不大,可以在项目启动的时候自动进行加载;
- 定时刷新缓存;
5)缓存更新
- 定时去清理过期的缓存;
- 当有用户请求过来时,再判断这个请求所用到的缓存是否过期,过期的话就去底层系统得到新数据并更新缓存。
6)缓存降级
- 一般:比如有些服务偶尔因为网络抖动或者服务正在上线而超时,可以自动降级;
- 警告:有些服务在一段时间内成功率有波动(如在95~100%之间),可以自动降级或人工降级,并发送告警;
- 错误:比如可用率低于90%,或者数据库连接池被打爆了,或者访问量突然猛增到系统能承受的最大阀值,此时可以根据情况自动降级或者人工降级;
- 严重错误:比如因为特殊原因数据错误了,此时需要紧急人工降级。
四、redis作为分布式锁方案(性能最优)
分布式锁是控制分布式系统之间同步访问共享资源的一种方式。
实现思路:
- 使用
SETNX命令获取锁,若不存在则设置值,设置成功则表示取得锁成功; - 设置expire,保证超时后能自动释放锁(使用lua脚本将setnx和expire变成一个原子操作);
- 释放锁,使用
DEL命令将锁数据删除。
Redis项目实战---应用及理论(二)---Redis集群原理的更多相关文章
- Elasticsearch(二)--集群原理及优化
一.ES原理 1.索引结构ES是面向文档的 各种文本内容以文档的形式存储到ES中,文档可以是一封邮件.一条日志,或者一个网页的内容.一般使用 JSON 作为文档的序列化格式,文档可以有很多字段,在创建 ...
- Redis项目实战---应用及理论(上)---redis基础知识介绍
redis(Remote Dictionary Server) 一.原理及特性层面: 1.优势: 1)数据加载在内存中,执行速度快, 数据结构类似于HashMap,HashM ...
- Redis项目实战---应用及理论(三)---Jedis使用
Jedis即redis java客户端,源码地址:https://github.com/xetorthio/jedis pom配置: <dependency> <groupId ...
- (转载)Android项目实战(三十二):圆角对话框Dialog
Android项目实战(三十二):圆角对话框Dialog 前言: 项目中多处用到对话框,用系统对话框太难看,就自己写一个自定义对话框. 对话框包括:1.圆角 2.app图标 , 提示文本,关闭对话 ...
- 支撑微博亿级社交平台,小白也能玩转Redis集群(原理篇)
Redis作为一款性能优异的内存数据库,支撑着微博亿级社交平台,也成为很多互联网公司的标配.这里将以Redis Cluster集群为核心,基于最新的Redis5版本,从原理再到实战,玩转Redis集群 ...
- Redis 5.0.7 讲解,单机、集群模式搭建
Redis 5.0.7 讲解,单机.集群模式搭建 一.Redis 介绍 不管你是从事 Python.Java.Go.PHP.Ruby等等... Redis都应该是一个比较熟悉的中间件.而大部分经常写业 ...
- 《Apache kafka实战》读书笔记-管理Kafka集群安全之ACL篇
<Apache kafka实战>读书笔记-管理Kafka集群安全之ACL篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 想必大家能看到这篇博客的小伙伴,估计你对kaf ...
- K8S(07)交付实战-架构说明并准备zk集群
k8s交付实战-架构说明并准备zk集群 目录 k8s交付实战-架构说明并准备zk集群 1 交付的服务架构图: 1.1 架构图解 1.2 交付说明: 2 部署ZK集群 2.1 二进制安装JDK 2.1. ...
- Spring Boot 项目实战(四)集成 Redis
一.前言 上篇介绍了接口文档工具 Swagger 及项目监控工具 JavaMelody 的集成过程,使项目更加健壮.在 JAVA Web 项目某些场景中,我们需要用缓存解决如热点数据访问的性能问题,业 ...
随机推荐
- springboot部署到tomcat
把spring-boot项目按照平常的web项目一样发布到tomcat容器下 多点经验: 1.保证运行环境的jdk和开发环境一致,不然class文件无法被编译 2.保证tomcat和java的版本匹配 ...
- 最全java多线程学习总结1--线程基础
<java 核心技术>这本书真的不错,知识点很全面,翻译质量也还不错,本系列博文是对该书中并发章节的一个总结. 什么是线程 官方解释:线程是操作系统能够进行运算调度的最小单位,包含 ...
- Hexo+NexT(一):在Windows下安装Hexo+NexT及搭建博客
阅读本篇之前,假定读者已经有了Node.js的基础,如需要补充Node.js知识的,请自行百度. Hexo是在Node.js框架下的一个项目,利用Node.js提供的强大功能,完成从Markdown到 ...
- Powerdesigner 从Oracle到mssql2008
database->update model for database> ->系统数据源->选择用户,选择表,确定... 1.database->change Curre ...
- iOS App开发的那些事儿2:如何搭建合适的框架
<iOS App开发的那些事儿>系列文章从更宏观的角度出发,不仅仅局限于具体某个功能.界面的实现,而是结合网易云信iOS端研发负责人多年的经验,从如何优化现有代码的角度出发,深度分析如何创 ...
- Storm 学习之路(一)—— Storm和流处理简介
一.Storm 1.1 简介 Storm 是一个开源的分布式实时计算框架,可以以简单.可靠的方式进行大数据流的处理.通常用于实时分析,在线机器学习.持续计算.分布式RPC.ETL等场景.Storm具有 ...
- C语言类型转换
int/float to string/array: C语言提供了几个标准库函数,可以将任意类型(整型.长整型.浮点型等)的数字转换为字符串,下面列举了各函数的方法及其说明. itoa():将整型值转 ...
- Python笔记【3】_元组学习
#!/usr/bin/env/python #-*-coding:utf-8-*- #Author:LingChongShi #查看源码Ctrl+左键 ''' tuple:以圆括号“()”括起来,以“ ...
- 解决Spring的java项目打包后执行出现“无法读取方案文档...“、“原因为 1) 无法找到文档; 2) 无法读取文档; 3) 文档的根元素不是...”问题
问题 一个用Spring建的java项目,在Eclipse或idea中运行正常,为什么打包后运行出现如下错误呢? 2019/07/10/19:04:07 WARN [main] org.springf ...
- HDU 1394:Minimum Inversion Number(线段树区间求和单点更新)
http://acm.hdu.edu.cn/showproblem.php?pid=1394 Minimum Inversion Number Problem Description The in ...