架构师之路-redis集群解析
引子
上篇《架构师之路-https底层原理》里我提到了上面的整体视图,文章也介绍了想要真正能在工作中及时正确解决问题的基本功:原理理解透彻。今天以redis集群解析为例介绍一个及时敏锐的发现问题的基本功:深入分析。
我认为达到深入分析有三个步骤:
第一步,深入理解
第二步,学以致用
第三步,千人千问
第一步redis集群各种原理介绍的人也很多;第二步很多人实际项目中大概也对redis集群不陌生;所以本文主要讲第三步:千人千问。
提出问题
"redis集群使用时有什么注意事项?"这是之前有段时间我面试喜欢问的一个问题。我的一个观点是作为redis集群的使用方而不是开发者首先要做的是用好。通过这个问题确定候选人用好了,再去挖掘他是通过了解了怎么用好的。所以我通常不会一开始就问一些中间件的原理,而是先从使用者的角度提出问题。
下面列举了6条代表性的回答:
1>防止集中失效
2>单线程执行,注意不要卡住
3>注意客户端和服务端的版本匹配
4>分片要保持流量均匀
5>注意超时时间配置
6>当内存缓存用,推荐删除代替更新
每条问题前面加上个为什么,就引出了6条新的问题。
解决问题
Q1:为什么要防止缓存集中失效?
A:缓存穿透、缓存集中失效和缓存雪崩并称为缓存世界的三大问题。先来总结理解一下这三个概念。这三个概念都是建立在缓存的一大作用就是对后端存储,比如mysql的保护。缓存没有保护住mysql,一个或一些到mysql了,那就是穿透;一个时间点缓存数据没有了,打到mysql了就是集中失效;缓存完全丧失了保护mysql的能力,请求全打到mysql了,就是雪崩。
所以防止缓存集中失效是对后端存储的保护。
Q2:为什么单线程执行,注意不要卡住?
A:卡住换个专业点的词就是阻塞嘛。什么叫阻塞呢,一辆小轿车A在单行道跑,遇到前面一辆车B停了,那A就被阻塞了。如果A和B都在高速单行道上跑,A开了160迈、B开了140迈。就算高速的允许最高速度是120迈(咱就当路过的是没有摄像头的路段,这俩车肆无忌惮),那A是不是还是被B给阻塞了呢?所以卡住造成的最直接影响就是快的快不起来,因为单线程不能绕行嘛。
有人说不是可以多开几个redis嘛。是滴,但是客户端分请求使用的是crc16,根本不会先探测哪个服务端比较空闲呀。所以后面来的总会被阻塞。
注意不要卡住还有个大家更常听到的名字:“避免大key问题”。其实我刚听到这个名字的时候是觉得很奇怪的。因为避免大key实际上是要避免key所对应的value不要太大。我之前一直觉得这个名字取的不对。那应该叫“避免大value问题”。后来想想这确实是正宗的中国话。比如张三的媳妇,人家都怎样叫呢?一般都是张三媳妇、张三家的。因为他家主要是张三出来抛头露面。那redis取值也一样,一般是先知道key,从key取value。用这个key取出来的数据大,就是大key问题啦。
Q3:如果不注意客户端和服务端版本匹配会引发什么问题?
A:先来思考客户端做了什么事情。我理解它就做了两件事:第一是使用RESP(Redis自定义的序列化协议)传输客户端命令并返回结果。第二是为了做第一件事,因为Redis集群是直连服务端模式,所以计算命令要落在哪个节点、哪个哈希槽上也是客户端来做的,我就称为选节点吧。
其实要回答客户端和服务端不匹配会引发什么问题,正规的方法应该是查看客户端版本升级都做过什么更新。
一般升级会做的是客户端依赖的jar包变了。这个可能会引起程序启动错误,但是这个往往启动成功了就不会再有问题,和服务端版本没有直接关系。
十年前还在用memcache的时候,发生过一次升级客户端版本,因为算法发生了变化,所以导致缓存全部不命中的问题。Redis最近的算法一直是crc16。如果不存在分布式算法不兼容问题的话,下一个要考虑的是大迭代是Redis3.0版本,支持了集群,集群模式是必须要匹配的。
Q4:为什么分片要保持流量均匀?
A:要提分片先来回忆一下redis集群的发展史,从单机版到主从版,后来有了大家可能很耳熟的哨兵模式。哨兵模式就是给主从增加一个监控,发现主节点挂了自动把从节点升级为主节点,有了故障自动迁移的功能。但是直到哨兵时代都只有一个主节点,也就是处理写请求的节点,不能称之为真正的集群。这也是很无奈的事情,一旦多个节点写一份数据,就涉及到数据一致性的问题。
一个蜂巢只能有一个蜂后,多出来一个,蜜蜂们就不会正常提供采蜜服务了,都打架去了。但是分成两个蜂巢呢?秩序就会恢复。所以现在的集群基本都是分片的原理。之前主从和哨兵的经验不能废弃,加上分片。redis集群就是将一个完整服务数据分成几份,每份都带着从节点,故障时可自动转移的一个整体。之前在《Redis集群搭建采坑总结》里讲过,1个节点的集群会有问题,最少需要3主3从也就是6个redis进程。3个主方便在1个挂掉之后重新选主。
梳理了这个之后,分片保持流量均匀这件事也很容易了。就是Q2的问题,均匀更不容易阻塞嘛。
Q5:为什么要注意超时时间配置?
A:提到redis的key的过期时间,首先想到的是redis的术语中,带过期时间的key又叫volatile key,就是不稳定key。怎么不稳定呢?就相当key这个对象有value和过期时间2个属性。过期时间这个属性1s改变一次(redis领域内时间都是以秒为单位),一直在变,当然不稳定。
如果把过期时间理解为key的一个属性,那也很好理解:对其进行del、set命令时过期时间也会删除;rename会把过期时间传给新的key;incr、lpush、hset等命令改变的是key的存储容器,没有改变key这个对象本身所以不会影响过期时间。
值得注意的是persist命令就是持久化保存的意思,将不稳定变成稳定,过期时间也自动删除了。
Redis在服务端有过期策略,但是对客户端是不感知的。客户端访问过期的就是一个表现,访问不到了。实际上服务端是有两种策略配合使用,一个是惰性删除,就是访问的时候发现过期了,就直接删除了;另一个策略会定期去删除,这个是为了防止一个过期的key总是不被访问到,还占着资源不释放。
Q6:为什么当内存缓存用,推荐删除代替更新?
A:一般大家出于数据一致性的考虑,会选择删除代替更新。这都是基于更新一定要更新数据库的固有思路。并发场景下,A的值1先被更新到数据库再更新缓存时,又来了一个更新请求把A的值更新为2。如果这时候执行更新为1的服务器性能不好或者网络传输速度比更新为2的慢,导致2在数据库是最新值,而设置为1的后更新了缓存。缓存就和数据库不一致了。
但只是记住删除代替更新不太够。如果先删除缓存再更新数据库,其他请求可能会把数据库老的值再加载到缓存中。记得之前有人介绍缓存还有三大种模式:Cache-Aside、Read-Through/Write-Through、Write-Behind。
Cache-Aside就是先更新数据库再删除缓存数据,可以避免上面提到的持续脏读的问题,顶多就是更新数据库的那一小段时间有更新延迟可见。我们给Cache-Aside起个中文名,叫经典模式。
Read-Through/Write-Through就是数据以缓存为准,数据库的操作是缓存发起的。Read-Through是在读数据时发现缓存过期了,那缓存自己去数据库加载新的数据,读数据还是读取缓存值。Write-Through写数据时调用方只负责写缓存,缓存自己去同步更新数据库。Read-Through/Write-Through一般配合使用。
Write-Behind和Write-Through的区别是虽然都是是写数据时调用方只负责写缓存,但是Write-Behind缓存自己去异步更新数据库。
因为Read-Through/Write-Through、Write-Behind都是以缓存为准,缓存不可靠,所以还是推荐经典模式。
后记
一些朋友问我一边上班一边写文章哪有那么多时间呀。细心的朋友可能会发现我的文章一般是周末或者周一,再不就是节假日或者哪天失眠了发出来。因为内容都是非上班时间写的,但是每次下笔腹稿都是提前打好的。个人意见哈,作为架构师,很多人都会形成随时随地为工作思考和总结的习惯。所以很多人看着下班很早,人家回家路上,晒太阳的时候……未必没在想工作的事情。
架构师三件占时间的事:会议、评审和演讲。对应有三大难:提出有水平的问题、做出有水平的总结和建议、做出有水平的回答。所以每天有很多的腹稿要打。腹稿按照一定的框架结构整理就是文章。
如果大家都架构师的三大难有兴趣,我可以举一些具体的示例和解决方法。大家投票吧,如果在看超过10个,我就写这个。
推荐阅读
架构师之路-redis集群解析的更多相关文章
- 【架构师之路】集群/分布式环境下5种session处理策略
[架构师之路]集群/分布式环境下5种session处理策略 转自:http://www.cnblogs.com/jhli/p/6557929.html 在搭建完集群环境后,不得不考虑的一个问题就是 ...
- Couchbase集群和Redis集群解析
Couchbase集群和Redis集群解析 首先,关于一些数据库或者是缓存的集群有两种结构,一种是Cluster;一种是master-salve. 关于缓存系统一般使用的就是Redis,Redis是开 ...
- linux运维、架构之路-redis集群
一.介绍 redis cluster 3.0之后的功能,至少需要3(Master)+3(Slave)才能建立集群,是无中心的分布式存储架构,可以在多个节点之间进行数据共享,解决了 ...
- (转)高性能网站架构之缓存篇—Redis集群搭建
看过 高性能网站架构之缓存篇--Redis安装配置和高性能网站架构之缓存篇--Redis使用配置端口转发 这两篇文章的,相信你已经对redis有一定的了解,并能够安装上,进行简单的使用了,但是在咱们的 ...
- (转)高性能网站架构之缓存篇—Redis集群增删节点
标签: 高性能架构集群缓存redis 上一篇文章,我们搭建了Redis-cluster集群,这篇博客跟大家讲一下如何在一个运行的集群上增加节点或者删除节点. Redis集群添加节点 首先我们要新建立一 ...
- windows下rabbitmq(架构师必备神器)集群搭建
准备2台机器,例如:computera: 10.0.0.151 computerb:10.0.0.234 都安装erlang环境和rabbitmq服务,注意otp环境和rabbitmq服务必须版 ...
- Java企业级电商项目架构演进之路 Tomcat集群与Redis分布式
史诗级Java/JavaWeb学习资源免费分享 欢迎关注我的微信公众号:"Java面试通关手册"(坚持原创,分享各种Java学习资源,面试题,优质文章,以及企业级Java实战项目回 ...
- 【原创】那些年用过的Redis集群架构(含面试解析)
引言 今天是2019年2月12号,也就是大年初八,我接到了高中同学刘有码面试失利的消息. 他面试的时候,身份是某知名公司的小码农一枚,却因为不懂自己生产上Redis是如何部署的,导致面试失败! 人间惨 ...
- 【转】那些年用过的Redis集群架构(含面试解析)
引言 今天是2019年2月12号,也就是大年初八,我接到了高中同学刘有码面试失利的消息. 他面试的时候,身份是某知名公司的小码农一枚,却因为不懂自己生产上Redis是如何部署的,导致面试失败! 人间惨 ...
随机推荐
- Python增强下git那长长的指令
场景 现如今有点规模的公司都使用GitFlow模式进行分支管理.虽然插件给我们带来了非常大的方便,但切换分支.找分支.起分支还是那么的麻烦 需求 在社会主次国家,每个生活在底层的劳动人民,他们默默的工 ...
- 从输入 URL 到展现页面的全过程
总体分为以下几个过程 DNS解析 TCP连接 发送HTTP请求 服务器处理请求并返回HTTP报文 浏览器解析渲染页面 连接结束 DNS解析 域名到ip地址转换 TCP连接 HTTP连接是基于TCP连接 ...
- PTA 面向对象程序设计 7-1 2017Final 圆周率山
7-1 2017Final 圆周率山 为了参加学校的社团风采展,怡山小学数学组的同学们决定画一座圆周率山,以宣传圆周率. 已知圆周率为:3. 1415926535 8979323846 2643383 ...
- Python爬无止境,获得王者荣耀全部高清皮肤
作为一名热爱王者两年的程序员,早就想爬取所有英雄皮肤的高清照片,在设个幻灯片放映,真香,这次只用16行代码就能实现,对于新手拿这个作为实战练手项目既简单又容易上手,快来尝试下. 百度"王者荣 ...
- C# lambda 实现 Ascii 排序
var dir = new Dictionary<string, string>(); dir.Add("channelId", "1& ...
- php 日期相关的类 DateInterval DateTimeZone DatePeriod
* DateInterval <?php /** * Created by PhpStorm. * User: Mch * Date: 7/18/18 * Time: 21:30 */ $dat ...
- web 阶段的一些简答题
1.jsp 9个隐含对象 2. jsp 4大域对象 3.mybatis 中 #{} %{ } 的区别于联系 4. Servlet容器默认是采用单实例多线程的方式处理多个请求的: 5.Cookie 与S ...
- linux中创建公私钥
linux中创建公私钥要再~(root)目录下ssh-keygencd /root/.ssh/lsid_rsa 是私钥id_rsa.pub 是公钥把 authorized_keys删除掉,重新建aut ...
- iMAC_使用相关
MAC软件下载 https://www.macwk.com/ 这是网站是一个下载免费软件的网站,下载通过<天翼云盘>下载,这个天翼云盘下载的快 好用的软件推荐 腾讯柠檬(Tencent L ...
- 牛客练习赛84F-牛客推荐系统开发之下班【莫比乌斯反演,杜教筛】
正题 题目链接:https://ac.nowcoder.com/acm/contest/11174/F 题目大意 给出\(n,k\)求 \[\sum_{i_1=1}^n\sum_{i_2=1}^n.. ...