最近在面试过程当中被面试官问到 Redis 集群数据是如何复制的,因为以前没有准备直接懵了。过后查了查这个问题其实也挺简单,若是你以前也不知道,没问题,赶忙浅尝辄止,速度3遍便可入门。html
阅读本文,你可能会有哪些收获呢?前端
Redis 支持三种集群方案node
经过持久化功能,Redis保证了即便在服务器重启的状况下也不会丢失(或少许丢失)数据,由于持久化会把内存中数据保存到硬盘上,重启会从硬盘上加载数据。 可是因为数据是存储在一台服务器上的,若是这台服务器出现硬盘故障等问题,也会致使数据丢失。linux
为了不单点故障,一般的作法是将数据库复制多个副本以部署在不一样的服务器上,这样即便有一台服务器出现故障,其余服务器依然能够继续提供服务。nginx
为此, Redis 提供了复制(replication)功能,能够实现当一台数据库中的数据更新后,自动将更新的数据同步到其余数据库上。面试
在复制的概念中,数据库分为两类,一类是主数据库(master),另外一类是从数据库(slave)。主数据库能够进行读写操做,当写操做致使数据变化时会自动将数据同步给从数据库。而从数据库通常是只读的,并接受主数据库同步过来的数据。一个主数据库能够拥有多个从数据库,而一个从数据库只能拥有一个主数据库。redis
总结:引入主从复制机制的目的有两个算法
主从复制优势shell
主从复制缺点数据库
第一种主从同步/复制的模式,当主服务器宕机后,须要手动把一台从服务器切换为主服务器,这就须要人工干预,费事费力,还会形成一段时间内服务不可用。这不是一种推荐的方式,更多时候,咱们优先考虑哨兵模式。
哨兵模式是一种特殊的模式,首先 Redis 提供了哨兵的命令,哨兵是一个独立的进程,做为进程,它会独立运行。其原理是哨兵经过发送命令,等待Redis服务器响应,从而监控运行的多个 Redis 实例。
然而一个哨兵进程对Redis服务器进行监控,也可能会出现问题,为此,咱们可使用多个哨兵进行监控。各个哨兵之间还会进行监控,这样就造成了多哨兵模式。
假设主服务器宕机,哨兵1先检测到这个结果,系统并不会立刻进行 failover 过程,仅仅是哨兵1主观的认为主服务器不可用,这个现象成为主观下线。当后面的哨兵也检测到主服务器不可用,而且数量达到必定值时,那么哨兵之间就会进行一次投票,投票的结果由一个哨兵发起,进行 failover 操做。切换成功后,就会经过发布订阅模式,让各个哨兵把本身监控的从服务器实现切换主机,这个过程称为客观下线。这样对于客户端而言,一切都是透明的。
优势:
缺点:
Redis Cluster是一种服务器 Sharding 技术,3.0版本开始正式提供。
Redis 的哨兵模式基本已经能够实现高可用,读写分离 ,可是在这种模式下每台 Redis 服务器都存储相同的数据,很浪费内存,因此在 redis3.0上加入了 Cluster 集群模式,实现了 Redis 的分布式存储,也就是说每台 Redis 节点上存储不一样的内容。
在这个图中,每个蓝色的圈都表明着一个 redis 的服务器节点。它们任何两个节点之间都是相互连通的。客户端能够与任何一个节点相链接,而后就能够访问集群中的任何一个节点。对其进行存取和其余操做。
Redis 集群没有使用一致性 hash,而是引入了哈希槽【hash slot】的概念。
Redis 集群有16384 个哈希槽,每一个 key 经过 CRC16 校验后对 16384 取模来决定放置哪一个槽。集群的每一个节点负责一部分hash槽,举个例子,好比当前集群有3个节点,那么:
这种结构很容易添加或者删除节点。好比若是我想新添加个节点 D , 我须要从节点 A, B, C 中得部分槽到 D 上。若是我想移除节点 A ,须要将 A 中的槽移到 B 和 C 节点上,而后将没有任何槽的 A 节点从集群中移除便可。因为从一个节点将哈希槽移动到另外一个节点并不会中止服务,因此不管添加删除或者改变某个节点的哈希槽的数量都不会形成集群不可用的状态。
在 Redis 的每个节点上,都有这么两个东西,一个是插槽(slot),它的的取值范围是:0-16383。还有一个就是 cluster,能够理解为是一个集群管理的插件。当咱们的存取的 Key到达的时候,Redis 会根据 CRC16 的算法得出一个结果,而后把结果对 16384 求余数,这样每一个 key 都会对应一个编号在 0-16383 之间的哈希槽,经过这个值,去找到对应的插槽所对应的节点,而后直接自动跳转到这个对应的节点上进行存取操做。
为了保证高可用,redis-cluster集群引入了主从复制模型,一个主节点对应一个或者多个从节点,当主节点宕机的时候,就会启用从节点。当其它主节点 ping 一个主节点 A 时,若是半数以上的主节点与 A 通讯超时,那么认为主节点 A 宕机了。若是主节点 A 和它的从节点 A1 都宕机了,那么该集群就没法再提供服务了。
理论课结束了,不如实操下感觉一下?
前提条件
# redis 准备 $ cd /opt $ wget http://download.redis.io/releases/redis-5.0.5.tar.gz $ tar xzf redis-5.0.5.tar.gz $ cd redis-5.0.5 $ make $ make install
生产环境作集群通常会采用多个独立主机,这里作演示在一台虚拟机上同时运行多个节点的,这点注意一下。
主要有两步
节点 | 配置文件 | 端口 |
---|---|---|
master | redis6379.conf | 6379 |
slave1 | redis6380.conf | 6380 |
slave1 | redis6381.conf | 6380 |
内容以下
# redis6379.conf master # 包含命令,有点复用的意思 include /opt/redis-5.0.5/redis.conf pidfile /var/run/redis_6379.pid port 6379 dbfilename dump6379.rdb logfile "my-redis-6379.log" # redis6380.conf slave1 include /opt/redis-5.0.5/redis.conf pidfile /var/run/redis_6380.pid port 6380 dbfilename dump6380.rdb logfile "my-redis-6380.log" # 最后一行设置了主节点的 ip 端口 replicaof 127.0.0.1 6379 # redis6381.conf slave2 include /opt/redis-5.0.5/redis.conf pidfile /var/run/redis_6381.pid port 6381 dbfilename dump6381.rdb logfile "my-redis-6381.log" # 最后一行设置了主节点的 ip 端口 replicaof 127.0.0.1 6379 ## 注意 redis.conf 要调整一项,设置后台运行,对我们操做比较友好 daemonize yes
启动节点,而后查看节点信息
# 顺序启动节点 $ redis-server redis6379.conf $ redis-server redis6380.conf $ redis-server redis6381.conf # 进入redis 客户端,开多个窗口查看方便些 $ redis-cli -p 6379 $ info replication
info replication 命令能够查看链接该数据库的其它库的信息,可看到有两个 slave 链接到 master
在 master 节点设置值,在 slave1/slave2 节点能够查看数据同步状况
# master $ redis-cli -p 6379 127.0.0.1:6379> set k1 v1 OK # slave1 $ redis-cli -p 6380 127.0.0.1:6380> get k1 "v1"
上面也说了哨兵其实主动复制的自动版,因此须要先配置好主从复制,不一样点在于要增长几个哨兵进行监控。
主要有两步:
通常来讲,哨兵模式的集群是:一主,二从,三哨兵。
那我们就来演示一下三个哨兵的集群。
节点 | 配置 | 端口 |
---|---|---|
master | redis6379.conf | 6379 |
slave1 | redis6380.conf | 6380 |
slave2 | redis6381.conf | 6381 |
sentinel1 | sentinel1.conf | 26379 |
sentinel2 | sentinel2.conf | 26380 |
sentinel3 | sentinel3.conf | 26381 |
哨兵的配置其实跟 redis.conf 有点像,能够看一下自带的 sentinel.conf
这里我们建立三个哨兵文件, 哨兵文件的区别在于启动端口不一样
# 文件内容 # sentinel1.conf port 26379 sentinel monitor mymaster 127.0.0.1 6379 1 # sentinel2.conf port 26380 sentinel monitor mymaster 127.0.0.1 6379 1 # sentinel3.conf port 26381 sentinel monitor mymaster 127.0.0.1 6379 1
先把 master-slave 启动!
而后,挨个把三个都启动了
$ redis-sentinel sentinel1.conf $ redis-sentinel sentinel2.conf $ redis-sentinel sentinel3.conf
启动以后日志以下,能够看到监听到的主/从节点状况以及哨兵集群状况
咱们在 master(6379) 节点 执行 shutdown
,而后观察哨兵会帮我作什么?
能够看到哨兵扫描到了 master 下线, 而后通过一系列判断,投票等操做从新选举了master(6381) 节点
能够查看到,6381 已成为 master
而后咱们能够看到, 即便咱们把原 master 节点恢复运行, 它也只是 slave 身份了存在了, 失去了大哥的身份, 可谓是风水轮流转了
Redis 的 Cluster 集群模式, 启动还挺简单
主要有两步
根据官方推荐,集群部署至少要 3 台以上的master节点,最好使用 3 主 3 从六个节点的模式。
节点 | 配置 | 端口 |
---|---|---|
cluster-master1 | redis7001.conf | 7001 |
cluster-master2 | redis7002.conf | 7002 |
cluster-master3 | redis7003.conf | 7003 |
cluster-slave1 | redis7004.conf | 7004 |
cluster-slave2 | redis7006.conf | 7005 |
cluster-slave3 | redis7006.conf | 7006 |
我们准备 6 个配置文件 ,端口 7001,7002,7003,7004,7005,7006
分别命名成 redis7001.conf ......redis7006.conf
redis7001.conf 配置文件内容以下(记得复制6份并替换端口号)
# 端口 port 7001 # 启用集群模式 cluster-enabled yes # 根据你启用的节点来命名,最好和端口保持一致,这个是用来保存其余节点的名称,状态等信息的 cluster-config-file nodes_7001.conf # 超时时间 cluster-node-timeout 5000 appendonly yes # 后台运行 daemonize yes # 非保护模式 protected-mode no pidfile /var/run/redis_7001.pid
redis-server redis7001.conf ... redis-server redis7006.conf
看如下启动状况
# 执行命令 # --cluster-replicas 1 命令的意思是建立master的时候同时建立一个slave $ redis-cli --cluster create 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 127.0.0.1:7006 --cluste r-replicas 1
# 执行成功结果以下 # 咱们能够看到 7001,7002,7003 成为了 master 节点, # 分别占用了 slot [0-5460],[5461-10922],[10923-16383] >>> Performing hash slots allocation on 6 nodes... Master[0] -> Slots 0 - 5460 Master[1] -> Slots 5461 - 10922 Master[2] -> Slots 10923 - 16383 Adding replica 127.0.0.1:7005 to 127.0.0.1:7001 Adding replica 127.0.0.1:7006 to 127.0.0.1:7002 Adding replica 127.0.0.1:7004 to 127.0.0.1:7003 >>> Trying to optimize slaves allocation for anti-affinity [WARNING] Some slaves are in the same host as their master M: 0313641a28e42014a48cdaee47352ce88a2ae083 127.0.0.1:7001 slots:[0-5460] (5461 slots) master M: 4ada3ff1b6dbbe57e7ba94fe2a1ab4a22451998e 127.0.0.1:7002 slots:[5461-10922] (5462 slots) master M: 719b2f9daefb888f637c5dc4afa2768736241f74 127.0.0.1:7003 slots:[10923-16383] (5461 slots) master S: 987b3b816d3d1bb07e6c801c5048b0ed626766d4 127.0.0.1:7004 replicates 4ada3ff1b6dbbe57e7ba94fe2a1ab4a22451998e S: a876e977fc2ff9f18765a89c12fbd2c5b5b1f3bf 127.0.0.1:7005 replicates 719b2f9daefb888f637c5dc4afa2768736241f74 S: ac8d6c4067dec795168ca705bf16efaa5f04095a 127.0.0.1:7006 replicates 0313641a28e42014a48cdaee47352ce88a2ae083 Can I set the above configuration? (type 'yes' to accept): yes # 这里有个要手动输入 yes 确认的过程 >>> Nodes configuration updated >>> Assign a different config epoch to each node >>> Sending CLUSTER MEET messages to join the cluster Waiting for the cluster to join ... >>> Performing Cluster Check (using node 127.0.0.1:7001) M: 0313641a28e42014a48cdaee47352ce88a2ae083 127.0.0.1:7001 slots:[0-5460] (5461 slots) master 1 additional replica(s) M: 4ada3ff1b6dbbe57e7ba94fe2a1ab4a22451998e 127.0.0.1:7002 slots:[5461-10922] (5462 slots) master 1 additional replica(s) S: ac8d6c4067dec795168ca705bf16efaa5f04095a 127.0.0.1:7006 slots: (0 slots) slave replicates 0313641a28e42014a48cdaee47352ce88a2ae083 S: a876e977fc2ff9f18765a89c12fbd2c5b5b1f3bf 127.0.0.1:7005 slots: (0 slots) slave replicates 719b2f9daefb888f637c5dc4afa2768736241f74 M: 719b2f9daefb888f637c5dc4afa2768736241f74 127.0.0.1:7003 slots:[10923-16383] (5461 slots) master 1 additional replica(s) S: 987b3b816d3d1bb07e6c801c5048b0ed626766d4 127.0.0.1:7004 slots: (0 slots) slave replicates 4ada3ff1b6dbbe57e7ba94fe2a1ab4a22451998e [OK] All nodes agree about slots configuration. >>> Check for open slots... >>> Check slots coverage... [OK] All 16384 slots covered.
# 注意 集群模式下要带参数 -c,表示集群,不然不能正常存取数据!!! [root@localhost redis-5.0.5]# redis-cli -p 7100 -c # 设置 k1 v1 127.0.0.1:7001> set k1 v1 -> Redirected to slot [12706] located at 127.0.0.1:7003 OK # 这能够看到集群的特色:把数据存到计算得出的 slot,这里还自动跳到了 7003 127.0.0.1:7003> get k1 "v1" # 咱们还回到 7001 获取 k1 试试 [root@localhost redis-5.0.5]# redis-cli -p 7001 -c 127.0.0.1:7001> get k1 -> Redirected to slot [12706] located at 127.0.0.1:7003 "v1" # 咱们能够看到重定向的过程 127.0.0.1:7003>
Docker 版 ?
也许会弄
B站-尚硅谷周阳老师的视频课--推荐新手看一看,对实操有帮助
到这里关于 Redis 的集群模式就了解的差很少了,完结,撒花 ~不要只看不敲哦,只看或者只收藏不敲等于耍流氓 !