共计 4520 个字符,预计需要花费 12 分钟才能阅读完成。
作者:Vt\
起源:https://juejin.im/post/5eb0e7…
前言
Redis 大家都不生疏,就算是没用过,也都据说过了。
作为最宽泛应用的 KV 内存数据库之一,在当今的大流量时代,单机模式略显薄弱,免不了要有一些拓展的计划。
笔者下文会对各种计划进行介绍,并且给出场景,实现 等等概述,还会提到一些老手常见的误区。
注释
先从根底的拓展形式开始,这样更便于了解较高级的模式。
分区
概述
分区 (Partitioning) 是一种最为简略的拓展形式。
在咱们面临单机的存储空间瓶颈时,第一点就能想到像传统的关系型数据库一样,进行数据分区。
或者假如手中有 N 台机器能够作为 Redis 服务器
所有机器内存总和有 256G, 而客户端正好也须要一个大内存的存储空间。
咱们除了能够把内存条都拆下来焊到一个机器上,也能够抉择分区应用,这样又拓展了计算能力。
单指分区来讲,行将全副数据扩散在多个 Redis 实例中,每个实例不须要关联,能够是齐全独立的。
应用形式
- 客户端解决
和传统的数据库分库分表一样,能够从 key 动手,先进行计算,找到对应数据存储的实例在进行操作。
范畴角度,比方 orderId:1~orderId:1000 放入实例 1,orderId:1001~orderId:2000 放入实例 2 …
哈希计算,就像咱们的 hashmap 一样,用 hash 函数加上位运算或者取模,高级玩法还有一致性 Hash 等操作,找到对应的实例进行操作
- 应用代理中间件
咱们能够开发独立的代理中间件,屏蔽掉解决数据分片的逻辑,独立运行。
当然也有别人曾经造好的轮子,Redis 也有优良的代理中间件,譬如 Twemproxy,或者 codis,能够联合场景抉择是否应用。
毛病
- 无缘多 key 操作,key 都不肯定在一个实例上,那么多 key 操作或者多 key 事务天然是不反对。
- 保护老本,因为每个实例在物理和逻辑上,都属于独自的一个节点,不足对立治理。
- 灵活性无限,范畴分片还好,比方 hash+MOD 这种形式,如果想动静调整 Redis 实例的数量,就要思考大量数据迁徙,这就十分麻烦了。
同为开发者,深知咱们尽管总能“曲线救国”的实现一些以后环境不反对的性能,然而总归要麻烦一些。
主从
概述数据迁徙
常说的主从 (Master-Slave),也就是复制(Replication) 形式,怎么称说都能够。
同下面的分区一样,也是 Redis 高可用架构的根底,老手可能会误以为这类根底模式即是“高可用”,这并不是非常正确的。
分区临时能解决单点无奈包容的数据量问题,然而一个 Key 还是只在一个实例上,在大流量时代显得不那么牢靠。
主从就是另一个纬度的拓展,节点将数据同步到从节点,就像将实例“分身”了一样,可靠性又进步了不少。
图画的有些夸大了,次要还是想体现构造灵便,是一主一从,还是一主多从,还是一主多从多从 … 看你情绪
有了“实例分身”,天然就能够做读写拆散,将读流量均摊在各个从节点。
应用形式
高手星散的时代,聊天软件不免要备上这么一张表情包。
这表情包和应用形式有什么关系呢?首先看看应用形式:
- 作为主节点的 Redis 实例,并不要求配置任何参数,只须要失常启动
- 作为从节点的实例,应用配置文件或命令形式 REPLICAOF 主节点 Host 主节点 port 即可实现主从配置
是不是和表情包一样,“dalao”没动,我去“抱大腿”。
这样一个主从最小配置就实现了,主从实例即可对外提供服务。
命令里的“主节点”是绝对的,slave 也能够抱 slave 大腿,也就是上文提到的构造灵便。
毛病
- slave 节点都是只读的,如果写流量大的场景,就有些力不从心了。
那我把 slave 节点只读关掉不就行了?当然不行,数据复制是由主到从,从节点独有数据同步不到主节点,数据就不统一了。
- 故障转移不敌对,主节点挂掉后,写解决就无处安放,须要手工的设定新的主节点,如应用 REPLICAOF no one(谁大腿我都不抱了) 降职为主节点,再梳理其余 slave 节点的新主配置,相对来说比拟麻烦。
哨兵
概述
主从的手工故障转移,必定让人很难承受,天然就呈现了高可用计划 - 哨兵(Sentinel)。
咱们能够在主从架构不变的场景,间接退出 Redis Sentinel,对节点进行监控,来实现主动的故障发现与转移。
并且还可能充当配置提供者,提供主节点的信息,就算产生了故障转移,也能提供正确的地址。
哨兵自身也是 Redis 实例的一种,但不作为数据存储方应用,启动命令也是不一样的。
尽管图有些简单,看起来像要号召光能使者。
其实理论应用起来是很便捷的。
应用形式
Sentinel 的最小配置,一行即可:
sentinel monitor < 主节点别名 > < 主节点 host> < 主节点端口 > < 票数 >
只须要配置 master 即可,而后用 redis-sentinel < 配置文件 > 命令即可启用。
Redis 官网提到的“最小配置”是如下所示,除了下面提到的一行,还有其它的一些配置:
sentinel monitor mymaster 127.0.0.1 6379 2sentinel down-after-milliseconds mymaster 60000sentinel failover-timeout mymaster 180000sentinel parallel-syncs mymaster 1sentinel monitor resque 192.168.1.3 6380 4sentinel down-after-milliseconds resque 10000sentinel failover-timeout resque 180000sentinel parallel-syncs resque 5
这是因为官网加了一个修饰词,是“典型的最小配置”,把重要参数和多主的例子都写进去了,关照大家 CV 大法的时候,不要遗记重要参数,其实都是有默认值的。
正如该例所示,设置主节点别名就是为了监控多主的时候,与其额定配置项可能与其对应, 以及 sentinel 一些命令,如 SENTINEL get-master-addr-by-name 就要用到别名了。
哨兵数量倡议在三个以上且为奇数,在 Redis 官网也提到了各种状况的“布阵”形式,十分值得参考。
更多
既然是高可用计划,并非有严格意义上的“毛病”,还需配合应用场景进行考量。
- 故障转移期间短暂的不可用,但其实官网的例子也给出了 parallel-syncs 参数来指定并行的同步实例数量,免得全副实例都在同步呈现整体不可用的状况,相对来说要比手工的故障转移更加不便。
- 分区逻辑须要自定义解决,尽管解决了主从下的高可用问题,然而 Sentinel 并没有提供分区解决方案,还需开发者思考如何建设。
- 既然是还是主从,如果异样的写流量搞垮了主节点,那么主动的“故障转移”会不会变成主动“劫难传递”,即 slave 晋升为 Master 之后挂掉,又进行晋升又被挂掉。
不过最初这点也是笔者猜想,并没有据说过呈现这种案例,可不用深究。
集群
概述
Redis Cluster 是官网在 3.0 版本后推出的分布式计划。
对开发者而言,“官网反对”一词是大概率十分美妙的,小到 issue,大到 feature。自定义去解决问题,老本总是要高一些。
有了官网的正式集群计划,从申请路由、故障转移、弹性伸缩几个纬度的应用上,将更为容易。
Cluster 不同于哨兵,是反对分区的。有说法 Cluster 是哨兵的降级,这是不谨严的。
二者纬度不一样,如果因为 Cluster 也有故障转移的性能,就说它是哨兵的降级款,略显牵强。
Cluster 在分区治理上,应用了“哈希槽”(hash slot)这么一个概念,一共有 16384 个槽位,每个实例负责一部分槽,通过 CRC16(key)&16383 这样的公式,计算出来 key 所对应的槽位。
尽管在节点和 key 二者中又引入了槽的概念,看起来不易了解,实际上因为颗粒度更细了,缩小了节点的扩容和膨胀难度,相比传统策略还是很有劣势。
当然,“槽”是虚构的概念,节点本身去保护“槽”的关系,并不是要真正下载启动个“槽服务”在跑。
应用形式
Redis 的各种玩法,都是从配置文件着手,集群也不例外。
cluster-enabled yescluster-config-file "redis-node.conf"
要害配置简洁明了,有两步
- 开启集群
- 指定集群配置文件
集群配置文件 (cluster-config-file) 为外部应用,能够不去指定,Redis 会帮忙创立一个。启动还是一般的形式 redis-server redis.conf
首先以集群形式启动了 N 台 Redis 实例,这当然还没完事。
接下来的步骤笔者称为“牵线搭桥调配槽”,听起来还算顺口。
“牵线搭桥调配槽”的形式也在一直降级,从间接用原始命令来解决,到应用脚本,以及当初的 Redis-cli 官网反对,应用哪种形式都能够。
redis-cli --cluster create 127.0.0.1:7000 127.0.0.1:7001 \127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 \--cluster-replicas 1
上方的命令即是 Redis 官网给出的 redis-cli 的形式用法,一行命令实现“三主三从”以及主动调配槽的操作。
这样集群就搭建实现了,当然,应用官网提供的 check 命令检查一下,也是有必要的。
redis-cli --cluster check 127.0.0.1:7001
更多
- 尽管是对分区良好反对,但也有一些分区的老问题,譬如:如果不在同一个“槽”的数据,是没法应用相似 mset 的多键操作。
- 在 select 命令页有提到, 集群模式下只能应用一个库,尽管平时个别也是这么用的,然而要理解一下。
- 运维上也要审慎,俗话说得好,“应用越简略底层越简单”,启动搭建是很不便,应用时面对带宽耗费,数据歪斜等等具体问题时,还需人工染指,或者钻研适合的配置参数。
结尾
趣谈
在写“主从”计划的时候,发现有一个乏味的事件:
笔者开始是记得主从的要害命令是 SLAVEOF,起初查阅官网的时候,发现命令曾经更改为 REPLICAOF,尽管 SLAVEOF 还能用。
官网的一些形容词汇,有的中央还是 Slave,也有些是用 Replication。
好奇的笔者查了一下相干的材料,并看了些 Redis 作者 antirez 的无关此时博客,发现曾经是两年前的事件了。
其实就是“Slave”这个变量名给了一些人机会,借此“喷”了一波作者,作者也做出了一部分斗争。
有趣味的盆友能够本人搜搜看,技术外的货色就不做评估了,看个乐呵就行。
笔者的次要目标还是:看官网文档的时候,别让不同的“词汇”蛊惑了。
END
本文对 Redis 这些拓展计划都作出了大抵形容。
具体应用上,还需注意具体配置,以及客户端反对等综合状况来考量。
近期热文举荐:
1.1,000+ 道 Java 面试题及答案整顿(2021 最新版)
2. 别在再满屏的 if/ else 了,试试策略模式,真香!!
3. 卧槽!Java 中的 xx ≠ null 是什么新语法?
4.Spring Boot 2.5 重磅公布,光明模式太炸了!
5.《Java 开发手册(嵩山版)》最新公布,速速下载!
感觉不错,别忘了顺手点赞 + 转发哦!