当前位置: 首页 > news >正文

网站开发相关会议国内免费制作网页的网站

网站开发相关会议,国内免费制作网页的网站,兰州百度推广的公司,建筑公司标志logo设计Redis 作为一门主流技术#xff0c;缓存应用场景非常多#xff0c;很多大中小厂的项目中都会使用redis作为缓存层使用。 但是Redis作为缓存#xff0c;也会面临各种使用问题#xff0c;比如数据一致性#xff0c;缓存穿透#xff0c;缓存击穿#xff0c;缓存雪崩#…Redis 作为一门主流技术缓存应用场景非常多很多大中小厂的项目中都会使用redis作为缓存层使用。 但是Redis作为缓存也会面临各种使用问题比如数据一致性缓存穿透缓存击穿缓存雪崩数据倾斜热点keyhot key大keybig key在集群中的数据倾斜redis集群脑裂等常见的缓存使用问题。 下边我们就来依次解析一下这些常见问题的生成原因和解决方案 数据一致性 Redis作为缓存层它是为了高并发场景下可以提供高并发量的访问和更新数据的一种技术。当用户面对不同的操作数据场景下我们应该对Redis做出什么要求呢 场景 查询数据 当用户对数据进行查询时用户会先到Redis中进行查询如果Redis中不存在会请求数据库并且写到Redis中然后返回给用户数据。 新增数据 当用户进行从插入数据时直接写入到数据库中不经过缓存也不会新增到缓存中只有查询数据时如果缓存没有才会进行新增。 更新数据 当用户对数据进行更改的时候不但要对数据库中的数据进行更改还要对缓存进行更新不然就会出现脏读的现象。 那么如何保证在更改数据的时候不会出现缓存和数据库中的数据不一致的现象导致脏读呢 数据一致性的四种可能处理逻辑 我们按照常规逻辑来想无非就四种情况 更新缓存更新数据库更新数据库更新缓存更新数据库删除缓存删除缓存更新数据库 1更新数据库更新缓存 如果我成功更新了缓存但是在执行更新数据库的那一步服务器突然宕机了那么此时我的缓存中是最新的数据而数据库中是旧的数据。 脏数据就因此诞生了并且如果我缓存的信息是单独某张表的而且这张表也在其他表的关联查询中那么其他表关联查询出来的数据也是脏数据结果就是直接会产生一系列的问题。 2更新数据库更新缓存 只有等到缓存更新之后才能访问到正确的信息。那么在缓存没过期的时间段内所看到的都是脏数据。 以上两个策略只要执行第二步时失败了就必然会产生脏数据。 3删除缓存更新数据库 这种方式在没有高并发的情况下是可能保持数据一致性的。 如果只有第一步执行成功而第二步失败那么只有缓存中的数据被删除了但是数据库没有更新那么在下一次进行查询的时候查不到缓存只能重新查询数据库构建缓存这样其实也是相对做到了数据一致性。 4更新数据库删除缓存 如果更新数据库成功了而删除缓存失败了那么数据库中就会是新数据而缓存中是旧数据数据就出现了不一致情况。 3,4两个策略在读写并发的情况下还是会出现数据不一致的情况。 3策略 4策略 但是此处达成这个数据不一致性的条件明显会比起其他的方式更为困难 时刻1读请求的时候缓存正好过期 时刻2读请求在写请求更新数据库之前查询数据库 时刻3写请求在更新数据库之后要在读请求成功写入缓存前先执行删除缓存操作。 延迟双删 以上四种方式无论选择那种方式如果实在多服务或时并发的情况下其实都是有可能产生数据不一致性的。 为了解决这个存在的问题有以下方式 先进行缓存清除再执行update最后延迟N秒再执行缓存清除。进行两次删除且中间需要延迟一段时间 redis.delKey(X) db.update(X) Thread.sleep(N) redis.delKey(X)和3策略比起来其实就是加了一个“延时删除缓存”的操作因为读写并发场景下可能会导致构建旧缓存的操作在update之后所以加个延时时间确保删除操作能够在构建旧缓存之后完成延时时间以读取构建缓存的时间作为参考加上几百ms。 这样只有在延时的时间内会读取到脏数据但是最终一致性是得到了保证。对于用户来说是完全可以接受的。 延迟双删的优化消息队列删除缓存 延迟双删要求更新操作延迟一段时间但是这会降低代码的性能减少了接口的吞吐量对代码也有一定的侵入性。 而且都无法保证两者都能一次性操作成功所以我们最好的办法就是重试这个重试并不是立即重试因为缓存和数据库可能因为网络或者其它原因停止服务了立即重试成功率极低而且重试会占用线程资源显然不合理所以我们需要采用异步重试机制。 异步重试我们可以使用消息队列来完成因为消息队列可以保证消息的可靠性消息不会丢失也可以保证正确消费当且仅当消息消费成功后才会将消息从消息队列中删除。 优点1可以大幅减少接口的延迟返回的问题 优点2MQ本身有重试机制无需人工去写重试代码 优点3解耦把查询Mysql和同步Redis完全分离互不干扰 延迟双删的再次优化canal订阅日志 即使把删除缓存的工作交给了消息队列,但是操作消息队列还是对代码有一定的侵入性。因为有的时候更新数据库并不需要修改缓存这样维护起来还是比较麻烦的不能做到适配。 以mysql为例在数据库一条记录发生变更时就会生成一条binlog日志我们可以订阅这种消息拿到具体的数据然后根据日志消息更新缓存订阅日志目前比较流行的就是阿里开源的canal那么我们的架构就变为如下形式。 订阅数据库变更日志当数据库发生变更时我们可以拿到具体操作的数据然后再去根据具体的数据去删除对应的缓存。 当然Canal 也是要配合消息队列一起来使用的因为其Canal本身是没有数据处理能力的。 这个方式算的上彻底解耦了应用程序代码无需再管消息队列方面发送失败问题全交由 Canal来发送。 但是需要注意的是canal对数据库会有性能上的影响具体用哪种操作来保证双写一致性还是要看具体的业务逻辑和整体的性能需求。 缓存穿透 问题的发生现象 是指查询一个根本不存在的数据缓存层和存储层都不会命中于是这个请求就可以随意访问数据库这个就是缓存穿透缓存穿透将导致不存在的数据每次请求都要到存储层去查询失去了缓存保护后端存储的意义。 缓存穿透问题可能会使后端存储负载加大由于很多后端存储不具备高并发性甚至可能造成后端存储宕掉。 通常可以在程序中分别统计总调用数、缓存层命中数、存储层命中数如果发现大量存储层空命中可能就是出现了缓存穿透问题。 问题的发生原因 造成缓存穿透的基本原因有两个。 第一自身业务代码或者数据出现问题比如我们数据库的 id 都是1开始自增上去的如发起为id值为 -1 的数据或 id 为特别大不存在的数据。如果不对参数做校验数据库id都是大于0的我一直用小于0的参数去请求你每次都能绕开Redis直接打到数据库数据库也查不到每次都这样并发高点就容易崩掉了。 第二,一些恶意攻击、爬虫等造成大量空命中。 问题的解决方法 缓存空对象 当存储层不命中到数据库查发现也没有命中那么仍然将空对象保留到缓存层中之后再访问这个数据将会从缓存中获取,这样就保护了后端数据源。 缓存空对象会有两个问题: 第一空值做了缓存意味着缓存层中存了更多的键需要更多的内存空间(如果是攻击问题更严重),比较有效的方法是针对这类数据设置一个较短的过期时间让其自动剔除。 第二缓存层和存储层的数据会有一段时间窗口的不一致可能会对业务有一定影响。例如过期时间设置为5分钟如果此时存储层添加了这个数据那此段时间就会出现缓存层和存储层数据的不一致此时可以利用消前面所说的数据一致性方案处理。 布隆过滤器拦截 在访问缓存层和存储层之前,将存在的key用布隆过滤器提前保存起来,做第一层拦截。例如:一个推荐系统有4亿个用户id每个小时算法工程师会根据每个用户之前历史行为计算出推荐数据放到存储层中,但是最新的用户由于没有历史行为,就会发生缓存穿透的行为,为此可以将所有推荐数据的用户做成布隆过滤器。如果布隆过滤器认为该用户id不存在,那么就不会访问存储层,在一定程度保护了存储层。 这种方法适用于数据命中不高、数据相对固定、实时性低(通常是数据集较大)的应用场景,代码维护较为复杂,但是缓存空间占用少。 因为布隆过滤器是通过哈希映射来进行判断的不存储真正的值所以必定存在哈希碰撞这样以来删除对于布隆过滤器来说是个难题。虽然可以通过定期重建布隆过滤器或者使用计数布隆过滤器来实现删除操作但是前者实时性并不好后者会占用更大的空间。 缓存击穿 问题的发生现象 缓存击穿是指一个Key非常热点在不停的扛着大并发大并发集中对这一个点进行访问当这个Key在失效的瞬间持续的大并发就穿破缓存直接大并发量请求数据库就像在一个完好无损的桶上凿开了一个洞。 问题的发生原因 大多数情况是因为秒杀或者热点新闻或者特殊的在极短时间内有某个热度极高的数据被不断请求。 问题的解决方法 缓存击穿的话设置热点数据永远不过期或者加上互斥锁就能搞定了。 使用互斥锁(mutex key) 业界比较常用的做法是使用mutex。简单地来说就是在缓存失效的时候判断拿出来的值为空不是立即去load db而是先使用缓存工具的某些带成功操作返回值的操作比如Redis的SETNX或者Memcache的ADD去set一个mutex key当操作返回成功时再进行load db的操作并回设缓存否则就重试整个get缓存的方法。 key永远不过期 这里的“永远不过期”包含两层意思 (1) 从redis上看不设置过期时间这就保证了不会出现热点key过期问题也就是“物理”不过期。 (2) 从功能上看如果不过期那不就成静态的了吗所以我们把过期时间存在key对应的value里如果发现要过期了通过一个后台的异步线程进行缓存的构建也就是“逻辑”过期。 从实战看这种方法对于性能非常友好唯一不足的就是构建缓存时候其余线程(非构建缓存的线程)可能访问的是老数据但是对于一般的互联网功能来说这个还是可以忍受。 缓存雪崩 问题的发生现象 由于缓存层承载着大量请求,有效地保护了存储层,但是如果缓存层由于某些原因不能提供服务比如同一时间缓存数据大面积失效那一瞬间Redis跟没有一样于是所有的请求都会达到存储层存储层的调用量会暴增造成存储层也会级联宕机的情况。 缓存雪崩的英文原意是stampeding herd(奔逃的野牛)指的是缓存层宕掉后流量会像奔逃的野牛一样,打向后端存储。 问题的发生原因 原因一缓存中大量的数据同时过期 原因二redis 服务挂了缓存层瘫痪 问题的解决方法 缓存中大量的数据同时过期场景 方案一请求限流并降级补救兜底方案 请求限流就是限制前端请求每秒请求量使得数据库能承受前端全部请求。比如前端允许每秒访问1000次其中900请求缓存100次才请求数据库。一旦发生雪崩数据库每秒请求激增到1000次此时启动请求限流在前端入口只允许每秒请求100次过多的请求直接拒绝。 对redis所在的服务器进行指标监控比如QPS、CPU使用率、内存使用率等如果发现redis服务宕机而数据库请求压力倍增此时可以启动请求限流 方案二缓存失效时间分散防止同时过期 将缓存失效时间分散开比如我们可以在原有的失效时间基础上增加一个随机值比如1-5分钟随机这样每一个缓存的过期时间的重复率就会降低就很难引发集体失效的事件。 Redis宕机场景 这个问题其实就是保证Redis的高可用 方案一哨兵机制或者集群cluster 保证缓存层服务高可用性。和飞机都有多个引擎一样如果缓存层设计成高可用的,即使个别节点、个别机器、甚至是机房宕掉依然可以提供服务。Sentinel和 Redis Cluster都实现了高可用。 数据倾斜 热点keyhot key 问题的发生现象 和缓存击穿稍许不同缓存击穿是因为热点key的过期时间到期导致请求直接越过了缓存层打到了DB上导致DB宕机。 缓存热点是指大部分甚至所有的业务请求都命中同一份缓存数据给缓存服务器带来了巨大压力甚至超过了单机的承载上限导致服务器宕机。 请求分片集中超过单Server的性能极限。在服务端读数据进行访问时往往会对数据进行分片切分此过程中会在某一主机Server上对相应的Key进行访问当访问超过Server极限时就会导致热点Key问题的产生。 1、流量集中达到物理网卡上限。 2、请求过多缓存分片服务被打垮。 3、DB击穿引起业务雪崩。 问题的发生原因 热点问题产生的原因大致有以下两种 用户消费的数据远大于生产的数据热卖商品、热点新闻、热点评论、明星直播。 在日常工作生活中一些突发的事件例如双十一期间某些热门商品的降价促销当这其中的某一件商品被数万次点击浏览或者购买时会形成一个较大的需求量这种情况下就会造成热点问题。同理被大量刊发、浏览的热点新闻、热点评论、明星直播等这些典型的读多写少的场景也会产生热点问题。 问题的解决方法 解决热点key问题可以从两个方面来综合考虑 1.发现热点key 1预估发现 针对业务提前预估出访问频繁的热点key例如秒杀商品业务中秒杀的商品都是热点key。 当然并非所有的业务都容易预估出热点key可能出现漏掉或者预估错误的情况。 2客户端发现 客户端其实是距离key最近的地方因为Redis命令就是从客户端发出的以Jedis为例可以在核心命令入口使用这个Google Guava中的AtomicLongMap进行记录如下所示。 使用客户端进行热点key的统计非常容易实现但是同时问题也非常多 (1) 无法预知key的个数存在内存泄露的危险。 (2) 对于客户端代码有侵入各个语言的客户端都需要维护此逻辑维护成本较高。 (3) 规模化汇总实现比较复杂。 3Redis发现命令 monitor命令 monitor命令可以监控到Redis执行的所有命令利用monitor的结果就可以统计出一段时间内的热点key排行榜命令排行榜客户端分布等数据。 Facebook开源的redis-faina正是利用上述原理使用Python语言实现的例如下面获取最近10万条命令的热点key、热点命令、耗时分布等数据。为了减少网络开销以及加快输出缓冲区的消费速度monitor尽可能在本机执行。 此种方法会有两个问题 1、monitor命令在高并发条件下内存暴增同时会影响Redis的性能所以此种方法适合在短时间内使用。 2、只能统计一个Redis节点的热点key对于Redis集群需要进行汇总统计。 可以参考的框架Facebook开源的redis-faina正是利用上述原理使用Python语言实现的 hotkeys命令 Redis在4.0.3中为redis-cli提供了–hotkeys用于找到热点key。 如果有错误需要先把内存淘汰策略设置为allkeys-lfu或者volatile-lfu否则会返回错误。 但是如果键值较多执行会较慢和热点的概念的有点背道而驰同时热度定义的不够准确。 4抓取TCP包发现 Redis客户端使用TCP协议与服务端进行交互通信协议采用的是RESP。如果站在机器的角度可以通过对机器上所有Redis端口的TCP数据包进行抓取完成热点key的统计 此种方法对于Redis客户端和服务端来说毫无侵入是比较完美的方案但是依然存在3个问题 (1) 需要一定的开发成本 (2) 对于高流量的机器抓包对机器网络可能会有干扰同时抓包时候会有丢包的可能性。 (3) 维护成本过高。 对于成本问题有一些开源方案实现了该功能例如ELK(ElasticSearch Logstash Kibana)体系下的packetbeat[2] 插件可以实现对Redis、MySQL等众多主流服务的数据包抓取、分析、报表展示 2.解决热点key 1使用二级缓存 可以使用 guava-cache或hcache发现热点key之后将这些热点key加载到JVM中作为本地缓存并且设置一个失效时间。将首先检查该数据是否存在于本地缓存中如果存在则直接返回如果不存在再去访问分布式缓存的服务器有效的保护了缓存服务器。 缺点实时感知最新的缓存数据有点麻烦会产生数据不一致的情况。我们可以设置一个比较短的过期时间采用被动更新。当然也可以用监控机制如果感知到数据已经发生了变化及时更新本地缓存。 2key分散 将热点key分散为多个子key然后存储到缓存集群的不同机器上这些子key对应的value都和热点key是一样的。当通过热点key去查询数据时通过某种hash算法随机选择一个子key然后再去访问缓存机器将热点分散到了多个子key上。 注意缓存一般都会设置过期时间为了避免缓存的集中失效我们对缓存的过期时间尽量不要一样可以在预设的基础上增加一个随机数。 大keybig key 问题的发生现象 1、内存空间不均匀.(平衡):例如在Redis Cluster中bigkey 会造成节点的内存空间使用不均匀。 2、超时阻塞:由于Redis单线程的特性操作bigkey比较耗时也就意味着阻塞Redis可能性增大。 3、CPU压力 对BigKey的数据序列化和反序列化会导致CPU的使用率飙升影响Redis实例和本机其它应用 4、网络拥塞:每次获取bigkey产生的网络流量较大 假设一个bigkey为1MB每秒访问量为1000那么每秒产生1000MB 的流量,对于普通的千兆网卡(按照字节算是128MB/s)的服务器来说简直是灭顶之灾而且一般服务器会采用单机多实例的方式来部署,也就是说一个bigkey可能会对其他实例造成影响,其后果不堪设想。 如果这个bigkey存在但是几乎不被访问,那么只有内存空间不均匀的问题存在,相对于另外两个问题没有那么重要紧急,但是如果bigkey是一个热点key(频繁访问)那么其带来的危害不可想象,所以在实际开发和运维时一定要密切关注bigkey的存在。 问题的发生原因 1、redis数据结构使用不恰当 将Redis用在并不适合其能力的场景造成Key的value过大如使用String类型的Key存放大体积二进制文件型数据。 2、未及时清理垃圾数据 没有对无效数据进行定期清理造成如HASH类型Key中的成员持续不断的增加。即一直往value塞数据却没有删除机制value只会越来越大。 3、对业务预估不准确 业务上线前规划设计考虑不足没有对Key中的成员进行合理的拆分造成个别Key中的成员数量过多。 4、明星、网红的粉丝列表、某条热点新闻的评论列表 假设我们使用List数据结构保存某个明星/网红的粉丝或者保存热点新闻的评论列表因为粉丝数量巨大热点新闻因为点击率、评论数会很多这样List集合中存放的元素就会很多可能导致value过大进而产生Big Key问题。 问题的解决方法 发现bigkey redis-cli --bigkeys可以命令统计bigkey的分布。 但是在生产环境中开发和运维人员更希望自己可以定义bigkey的大小而且更希望找到真正的bigkey都有哪些,这样才可以去定位、解决、优化问题。 判断一个key是否为bigkey只需要执行debug object key查看serializedlength属性即可它表示 key对应的value序列化之后的字节数。 scan debug object 如果是要遍历多个则尽量不要使用keys的命令可以使用scan的命令来减少压力。 Redis 从2.8版本后提供了一个新的命令scan它能有效的解决keys命令存在的问题。和keys命令执行时会遍历所有键不同,scan采用渐进式遍历的方式来解决 keys命令可能带来的阻塞问题但是要真正实现keys的功能,需要执行多次scan。可以想象成只扫描一个字典中的一部分键直到将字典中的所有键遍历完毕。scan的使用方法如下: scan cursor [match pattern] [count number]cursor 是必需参数实际上cursor是一个游标第一次遍历从0开始每次scan遍历完都会返回当前游标的值,直到游标值为0,表示遍历结束。 Match pattern 是可选参数,它的作用的是做模式的匹配,这点和keys的模式匹配很像。 Count number 是可选参数,它的作用是表明每次要遍历的键个数,默认值是10,此参数可以适当增大。 除了scan 以外Redis提供了面向哈希类型、集合类型、有序集合的扫描遍历命令解决诸如hgetall、smembers、zrange可能产生的阻塞问题对应的命令分别是hscan、sscan、zscan它们的用法和scan基本类似请自行参考Redis官网。 渐进式遍历可以有效的解决keys命令可能产生的阻塞问题但是scan并非完美无瑕如果在scan 的过程中如果有键的变化(增加、删除、修改)那么遍历效果可能会碰到如下问题:新增的键可能没有遍历到遍历出了重复的键等情况也就是说scan并不能保证完整的遍历出来所有的键这些是我们在开发时需要考虑的。 debug object key 根据传入的对象Key的名称来对Key进行分析并返回大量数据其中serializedlength的值为该Key的序列化长度需要注意的是Key的序列化长度并不等同于它在内存空间中的真实长度此外debug object属于调试命令运行代价较大并且在其运行时进入Redis的其余请求将会被阻塞直到其执行完毕。 如果键值个数比较多scan debug object会比较慢可以利用Pipeline机制完成。对于元素个数较多的数据结构debug object执行速度比较慢存在阻塞Redis的可能所以如果有从节点,可以考虑在从节点上执行。 第三方工具 利用第三方工具如 Redis-Rdb-Tools 分析RDB快照文件全面分析内存使用情况 https://github.com/sripathikrishnan/redis-rdb-tools 解决bigkey 使用合理的数据结构 对大Key进行清理 对Redis中的大Key进行清理从Redis中删除此类数据。Redis自4.0起提供了UNLINK命令该命令能够以非阻塞的方式缓慢逐步的清理传入的Key通过UNLINK你可以安全的删除大Key甚至特大Key。 拆分 对 big key 存储的数据 big value进行拆分变成value1value2… valueN等等。 例如big value 是个大json 通过 mset 的方式将这个 key 的内容打散到各个实例中或者一个hash每个field代表一个具体属性通过hget、hmget获取部分valuehset、hmset来更新部分属性。 例如big value 是个大list可以拆成将list拆成。 list_1 list_2, list3, …listN 其他数据类型同理。 key推荐值 单个key的value小于10KB 对于集合类型的key建议元素数量小于1000 在集群中的数据倾斜 背景 对于分布式系统而言整个集群处理请求的效率和存储容量往往取决于集群中响应最慢或存储增长最快的节点。所以在系统设计和容量规划时我们尽量保障集群中各节点的“数据和请求分布均衡“。但在实际生产系统中出现数据容量和请求倾斜(类似Data Skew问题是比较常见的。 什么是集群中的数据倾斜 单台机器的硬件配置有上限制约一般我们会采用分布式架构将多台机器组成一个集群下图的集群就是由三台Redis单机组成。客户端通过一定的路由策略将读写请求转发到具体的实例上。 由于业务数据特殊性按照指定的分片规则可能导致不同的实例上数据分布不均匀大量的数据集中到了一台或者几台机器节点上计算从而导致这些节点负载多大而其他节点处于空闲等待中导致最终整体效率低下。 数据倾斜主要分为两类 数据存储容量倾斜数据存储总是落到集群中少数节点(bigKey)qps请求倾斜qps总是落到少数节点。(hot key) 导致Redis集群倾斜的常见原因 一般是系统设计时键空间(keyspace)设计不合理 系统存在大的集合key(hash,set,list等)导致大key所在节点的容量和QPS过载集群出现qps和容量倾斜 DBA在规划集群或扩容不当导致数据槽(slot)数分配不均匀导致容量和请求qps倾斜; 系统大量使用Keys hash tags, 可能导致某些数据槽位的key数量多集群集群出现qps和容量倾斜 工程师执行monitor这类命令导致当前节点client输出缓冲区增大used_memory_rss被撑大导致节点内存容量增大出现容量倾斜 如何有效避免Redis集群倾斜问题 避免出现hotkey 和 bigkey redis集群部署和扩缩容处理保证数据槽位分配平均 系统设计角度应避免使用keys hash tag某类key分配同一个分片使用scan扫描keyspace是否有使用hash tags的或使用monitor,vc-redis-sniffer工具分析倾斜节点是否大理包含有hash tag的key 日常运维和系统中应避免直接使用keys,monitor等命令导致输出缓冲区堆积这类命令建议作rename处理 合量配置normal的client output buffer, 建议设置10mb,slave限制为1GB按需要临时调整(警示:和业务确认调整再修改避免业务出错) 在实际生产业务场景中大规模集群很难做到集群的完全均衡只是尽量保证不出现严重倾斜问题。 redis脑裂 所谓的脑裂就是指在有主从集群中同时出现了两个主节点它们都能接收写请求。 而脑裂最直接的影响就是客户端不知道应该往哪个主节点写入数据结果就是不同的客户端会往不同的主节点上写入数据。而且严重的话脑裂会进一步导致数据丢失。 数据丢失一定是发生了脑裂吗 那可能你想问了数据丢失一定是发生了脑裂吗如何判断发生了脑裂 数据丢失不一定是发生了脑裂最常见的原因是主库的数据还没有同步到从库结果主库发生了故障等从库升级为主库后未同步的数据就丢失了。 如果是这种情况的数据丢失我们可以通过比对主从库上的复制进度差值来进行判断也就是计算 master_repl_offset 和 slave_repl_offset 的差值。如果从库上的 slave_repl_offset 小于原主库的 master_repl_offset那么我们就可以认定数据丢失是由数据同步未完成导致的。 而判断是否发生了脑裂可以采取排查客户端的操作日志的方式。 通过看日志能够发现在主从切换后的一段时间内会有客户端仍然在和原主库通信并没有和升级的新主库进行交互这就相当于主从集群中同时有了两个主库。根据这个迹象我们就可以判断可能是发生了脑裂。 单机主从架构脑裂 现在假设有三台服务器一台主服务器两台从服务器还有一个哨兵。 基于上边的环境这时候网络环境发生了波动导致了sentinel没有能够心跳感知到master但是哨兵与slave之间通讯正常。所以通过选举的方式提升了一个salve为新master。如果恰好此时server1仍然连接的是旧的master而server2连接到了新的master上。数据就不一致了哨兵恢复对老master节点的感知后会将其降级为slave节点然后从新maste同步数据full resynchronization导致脑裂期间老master写入的数据丢失。 基于setNX指令的分布式锁可能会拿到相同的锁 基于incr生成的全局唯一id也可能出现重复。 解决方案 通过配置参数 min-replicas-to-write x min-replicas-max-lag y第一个参数表示最少的salve节点为z个 第二个参数表示数据复制和同步的延迟不能超过y秒 配置了这两个参数 这两个配置项组合后的要求是主库连接的从库中至少有 x 个从库和主库进行数据复制时的 ACK 消息延迟不能超过 y 秒否则主库就不会再接收客户端的请求了。 这样一来即使原主库是假故障它在假故障期间也无法响应哨兵发出的心跳测试也不能和从库进行同步自然也就无法和从库进行 ACK 确认了这样可以避免大量数据丢失。 集群脑裂 Redis集群的脑裂一般是不存在的因为Redis集群中存在着过半选举机制而且当集群16384个槽任何一个没有指派到节点时整个集群不可用可用配置文件更改。 所以我们在构建Redis集群时应该让集群 Master 节点个数最少为 3 个且集群可用节点个数为奇数。 不过脑裂问题不是是可以完全避免只要是分布式系统必然就会一定的几率出现这个问题CAP的理论就决定了。
http://www.hkea.cn/news/14288415/

相关文章:

  • 企业网站内容是什么上海哪里网站备案
  • 什么网站比较少人做免费电子商务网站源码
  • 建企业网站教程网页加速器ios
  • 如何做情趣网站盘锦建设小学网站
  • 网站建设教学方法探究相关搜索优化软件
  • 微信公众号授权给网站网站访问慢原因
  • 网站怎么做展现量友情链接交换软件
  • 做网站在哪里泰安市最大的网络公司
  • 帝国行业网站模板没有做等保的网站不能上线对吗
  • 有哪些做品牌特卖的网站公司简介模板设计图片
  • 外贸响应式网站茂名网站建设技术托管
  • 影响网站排名的因素 权重wordpress10万数据多大
  • 红谷滩园林建设集团网站济南房产信息网站官网
  • 石家庄万达网站制作敬请期待换个说法
  • 淘宝网站是怎么做的吗建立网站需要多少钱费用
  • 龙华营销型网站制作网站微信公众号链接怎么做
  • 美工好的网站凡科手机网站建设开发
  • qml 网站开发wordpress 开源主题
  • 手机传奇手游发布网站成都动力无限网站推广
  • 建设网站赚广告费是否可行加盟培训网站建设
  • 电商网站管理系统模板下载无需下载国外黄冈网站推广
  • 做百科网站广州环保网站建设
  • 网站降权不更新文章可以吗库存管理软件有哪些
  • 网站的主页按钮怎么做上海城隍庙旅游区
  • 氧气瓶网站建设周口哪里做网站
  • 富平网站建设莱芜雪野湖介绍
  • 网站标题关键优化开发一个婚恋app需要多少钱
  • 电商网站国内外需求分析公司注册资金实缴后多久可以取出
  • wordpress建站平台网页浏览器没有声音
  • 做网站从哪里找货源公众号排版