美文网首页缓存云服务web
Redis第8课:Redis Cluster—分布式解决方案

Redis第8课:Redis Cluster—分布式解决方案

作者: 米饭超人 | 来源:发表于2018-08-27 20:41 被阅读416次

    我们在使用 Redis 的时候,经常是会遇到一些问题。比如高可用问题、容量问题、并发性能问题等。于是开发者考虑能不能像服务器一样,当一台机器不够的时候,我们用多台机器形成 Redis Cluster 集群呢?

    在 Redis 团队的努力下,终于做出了一套解决方案。这套解决方案有以下特点。

    1. 去中心化。Redis Cluster 增加了1000个节点,性能随着节点而线性扩展。
    2. 管理简单方便。可根据实际情况去掉节点或者增加节点,移动分槽等。
    3. 官方推荐。
    4. 容易上手。

    根据以上 Redis 集群的特点,我们将从以下七个方面对 Redis Cluster 进行讲解。

    1. 为什么要有集群
    2. 如何进行数据分布
    3. 如何搭建集群
    4. 如何进行集群的伸缩
    5. 如何使用客户端去连接redis-cluter
    6. 理解集群原理
    7. 常见的开发运维的问题

    为什么要有集群

    首先是并发量,一般 QPS 到10万每秒已经非常牛了,随着公司业务的发展,或者当需要离散计算的时候,需要用到中间件缓存的时候,业务需要100万每秒。这个时候,我们就需要使用分布式了。

    其次是数据量,一般一个 Redis 的内存大约是16G~256G,假设我们在一台主从机器上配置了200G内存,但是业务需求是需要500G的时候,我们首先不会通过升级硬件,而是通过分布式。

    我们对并发量大和数据量剧增的时候,采取的最常用的手段就是加机器,对数据进行分区。做一个形象的比喻,我们的数据量相当于货物,当货物只有很少一部分的时候,我们可以使用驴来拉货;当货物多起来了的时候,已经超出驴能拉的范围,我们可以使用大象来拉货;当货物更多的时候,已经没有更强壮的动物了,这个时候我们可以考虑使用多只大象来拉货。

    分布式就是一种采用某种规则对多台机器管理的方式。采用分布式我们就是为了节省费用。

    如何进行数据分布

    什么是数据分布?数据分布有两种方式,顺序分区和哈希分区。

    顺序分布

    顺序分布就是把一整块数据分散到很多机器中,如下图所示。

    enter image description here

    顺序分布一般都是平均分配的。

    哈希分区

    如下图所示,1~100这整块数字,通过 hash 的函数,取余产生的数。这样可以保证这串数字充分的打散,也保证了均匀的分配到各台机器上。

    enter image description here

    两者的区别,请见下表。

    分布 特点 特点
    顺序分布 数据分散容易倾斜、键值业务相关、可顺序访问、支持批量 Big Table、HBase
    哈希分布 数据分散度高、键值分布业务无关、支持批量、无法顺序访问 一致性哈希、redis cluster、其他缓存

    由上表可知,哈希分布和顺序分布只是场景上的适用。哈希分布不能顺序访问,比如你想访问1~100,哈希分布只能遍历全部数据,同时哈希分布因为做了 hash 后导致与业务数据无关了。而顺序分布是会导致数据倾斜的,主要是访问的倾斜。每次点击会重点访问某台机器,这就导致最后数据都到这台机器上了,这就是顺序分布最大的缺点。其他的特点见表可知。

    但哈希分布其实是有个问题的,当我们要扩容机器的时候,专业上称之为“节点伸缩”,这个时候,因为是哈希算法,会导致数据迁移。在节点取余的时候,迁移数量和添加的节点数是有关的,这个时候建议使用翻倍扩容。

    这里需要说明的是节点取余到底是什么。

    比如之前是三个节点,那么现在加一个节点,就是四个节点。这个时候哈希算法就是从3的取余变成了4的取余,这个时候,原来的数字所在的位置肯定是需要发生变化的,整体的数据基本上都是做了漂移。

    整体的数据漂移其实是有问题的,对数据库的性能,硬件上都是考验,所以为了减少整体的数据漂移,我们就需要对哈希算法有个一致性哈希算法

    一致性哈希

    enter image description here

    上图就是一个一致性哈希的原理解析。假设我们有 n1~n4 这四台机器,我们对每一台机器分配一个唯一 token,每次有数据(图中黄色代表数据),一致性哈希算法规定每次都顺时针漂移数据,也就是图中黄色的数据都指向 n3。这个时候我们需要增加一个节点 n5,在 n2 和 n3 之间,数据还是会发生漂移,但是这个时候你是否注意到,其实只有 n2~n3 这部分的数据被漂移,其他的数据都是不会变的,这样就实现了部分漂移,而没有对所有数据进行漂移的弊端了。

    最后我们来介绍另外一个哈希算法,就是 Redis Cluster 的哈希算法 —— 虚拟槽分区。我们通过下面这张图来解释。

    enter image description here

    如上图所示,我们知道槽的范围是0~16383,如果此时有五个节点,key 会通过 CRC16 哈希算法,对16383取余,然后保存到 Redis Cluster 里,Redis Cluster 会根据数据判断是否是这个虚拟槽里的数据,如果不是这个槽范围的,由于 Redis Cluster 数据是共享的,于是就会告知数据应该存到那台机器上。

    如果你对虚拟槽理解还有问题,这是正常的。下面我们将通过讲解 Redis Cluster 的基本架构、安装使用让你真正认识虚拟槽的概念。

    基本架构

    先来看看,什么是分布式架构。分布式架构是一种彼此通讯的架构,通过每个节点之间负责对应的槽,每个节点都负责读写。如下图

    enter image description here

    那么 Redis Cluster 是怎样的架构呢?实际上我们可以通过安装来了解 Redis Cluster 的架构。了解Redis Cluster 架构,我们从了解节点、meet操作、指派槽、复制四个知识点开始。

    节点

    Redis Cluster 是有很多节点的,每个节点负责读和写。对某个节点进行配置文件设置,如下所示

    cluster-enabled:yes // 集群模式来启动
    

    meet 操作

    我们知道 Redis Cluster 是通过节点完成数据交换的,meet 操作则是这个过程的基础。

    enter image description here

    上图所示,A 和 C 之间有 meet 操作通讯数据,A 和 B 之间也有 meet 操作通讯,那么 B 和 C 之间也就可以相互通信。只要某个节点和另外的节点能够正常读写,那么任何节点之间其实也是可以相互进行数据交换的。

    可以说,所有节点都可以共享消息。

    指派槽

    我们只有对节点进行指派某个槽,每个 key 算出来的哈希值是否在某个槽内,它才能正常的读写。

    enter image description here

    如上图所示,当我们的 Redis Cluster 有三台机器的时候,把0~16383的槽平均分配给每台机器(Redis Cluster 制定给每个槽分配16384个槽,也就是0~16383)。每当 key 访问过来,Redis Cluster 会计算哈希值是否在这个区间里。它们彼此都知道对应的槽在哪台机器上。

    客户端只需要计算一个 key 的哈希值,然后传给 Redis Cluster 就可以了。

    复制

    Redis Cluster 是一个主从复制的过程。所以在这里就不解释了。

    安装 Redis Cluster

    安装 Redis Cluster 有两种方式,一种是原生安装,一种是官方工具安装。

    原生安装

    原生安装首先是通过配置开启节点;其次是通过 meet,实现节点间相互通讯;再次是指配槽,只有通过指配槽才能实现客户端数据的基本访问;最后是主从配置,才能够实现故障转移。

    配置开启 Redis

    代码如下。

    port 端口
    daemonize yes // 守护进程方式启动
    dir "/opt/redis/data/" // 目录
    dbfilename "dump-3339.rdb" // 端口来区分
    logfile "3339.log" //日志文件,使用端口区分
    cluster-enabled yes //代表开启cluster
    cluster-config-file nodes-3339.conf //clstuer开启各个节点的配置。
    

    配置完以后可以使用下面的命令,分别开启每一个 cluster:

    redis-server redis-端口.conf
    

    但是以上命令是相互独立的。下面我们进行 meet 操作:

    redis-cli -h 127.0.0.1 -p 7000 cluster meet 127.0.0.1 7001
    

    根据上面的命令自动感知两台,然后分别用上面的命令都和7000这个端口进行 meet 操作即可全部实现 meet 配置。

    Cluster 节点主要配置

    配置代码如下

    cluster-enabled yes // 使用cluster
    cluster-node-timeout 15000 // 默认超时配置
    cluster-config-file "nodes.conf" //集群节点,端口来区分
    cluster-require-full-coverage no //如果有一个节点坏掉了,对外就不提供服务了。默认是yes,必须配置为no。
    

    分配槽

    我们需要为每个端口配置对于的分配槽,代码如下

    redis-cli -h 127.0.0.1 -p 7000 cluster addslots {0...5461}
    redis-cli -h 127.0.0.1 -p 7001 cluster addslots {5462...10922}
    redis-cli -h 127.0.0.1 -p 7001 cluster addslots {10923...16383}
    

    根据有多少个端口,就分配好对应的槽就可以了。记住这个范围是0~16383。

    设置主从

    为了完成故障转移,就必须进行主从配置,代码如下

    redis-cli -h 127.0.0.1 -p 7001 cluster replicate ${nodeid-7000}
    

    这里注意 nodeid 和我们单机讲解的 runid 是不同的,runid 重启以后是会改变的,但是 nodeid 却不会。关于如何获取 nodeid,我们将会在后续进行讲解。

    官方工具安装

    Redis 官方给我们提供了官方安装工具,主要是通过 Ruby 安装。

    (1)安装 Ruby

    下载对应的 Ruby,代码如下

    wget https://cache.ruby-lang.org/ruby/2.3/ruby-2.3.1.tar.gz
    

    安装 Ruby,代码如下

    tar -xvf ruby-2.3.1.tar.gz
    ./configure -prefix=/usr/local/ruby //编译
    make
    make install //安装
    cd /usr/local/ruby
    cp bin/ruby /usr/local/bin //拷贝到此路径
    cp bin/gem /usr/local/bin //拷贝到此路径
    

    (2)安装 Rubygem Redis

    下载 Ruby 的 gem,代码如下

    wget http://rubygems.org/downloads/redis-3.3.0.gem
    

    安装,代码如下

    gem install -l redis-3.3.0.gem
    gem list --check redis gem
    

    (3)安装 redis-trib.rb

    代码如下

    cp ${redis_home}/src/redis-trib.rb /usr/local/bin
    

    通过复制就可以把 redis-trib.rb 文件拷贝到 bin 文件下,就可以使用了。

    总结

    最后,对本文的内容做下总结,主要有以下三点。

    1. 使用原生命令安装,理解 Redis Cluster 的架构。但是生产环境中不使用。
    2. 官方工具安装是非常简单和高效的。其实在生产环境中会使用脚本,会更加简单高效准确。一般生产环境都会使用。
    3. 其他部署还可以通过可视化部署,但是只存在少数企业中,大部分还是在使用官方工具安装的。

    相关文章

      网友评论

      本文标题:Redis第8课:Redis Cluster—分布式解决方案

      本文链接:https://www.haomeiwen.com/subject/saotwftx.html