redis——集群

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

现实中redis需要若干台redis服务器的支持:
(1)从结构上,单个Redis服务器会产生单点故障,同时一台服务器需要承受所有的请求负载。这就需要为数据生成多个副本并分配在不同的服务器上。
(2)从容量上,单个Redis服务器的内存非常容易成为存储瓶颈,所以需要进行数据分片。
  同时拥有多个Redis服务器后就会面临如何管理集群的问题,包括如何增加节点,故障恢复等操作。

1. 复制
    通过持久化功能,Redis保证了即使在服务器重启的情况下也不会损失(或少量损失)数据。
    但是由于数据是存储在一台服务器上的,如果这台服务器出现硬盘故障等问题,也会导致数据丢失。为了避免单点故障,通常的做法是将数据库复制多个副本部署在不同的服务器上,这样即使有一台服务器出现故障,其他服务器依然可以继续提供服务。为此,Redis提供了复制(replication)功能,可以实现当一台服务器中的数据更新后,自动更新的数据同步到其他数据库上
2. 哨兵
    在一个典型的一主多从的Redis系统中,从数据库在整个系统中起到了数据冗余备份和读写分离的作用。当主数据库遇到异常中断服务后,开发者可以通过手动的方式选择一个从数据库升级为主数据库,以使得系统能够继续提供服务。然而整个过程相对麻烦且需要人工介入,难以实现自动化。为此, Redis2.8中提供了哨兵工具来实现自动的系统监控和故障恢复功能
3. 集群:
    即使使用哨兵,此时的Redis集群的每个数据库依然存在集群中的所有的数据库,从而导致集群的总数据存储量受限于内存最小的数据库节点,形成木桶效应。由于Redis中的所有数据都是基于内存存储,这一问题就尤为突出了,尤其是当使用Redis做持久化存储服务使用时。

   哨兵和集群是两个独立的功能,但从特性来看哨兵可以视为集群的子集,当不需要数据分片或者已经在客户端进行分片的场景下哨兵就足够使用了,但如果需要进行水平扩容,则集群是一个非常好的选择。


在Redis中使用复制功能非常容易,只需要在从数据库的配置文件中加入

salveof 主数据库地址 主数据库端口
salveof 127.0.0.1  6379

即可,主数据库无需进行任何配置。


哨兵的作用就是监控Redis系统的运行状况。它的功能包括以下两个:
   * 监控主数据库和从数据库是否运行正常。
   * 主数据库出现故障时自动将从数据库转换为主数据库。

sentinel monitor master-name ip redis-port quornum
sentinel monitor mymaster 127.0.0.1 6379 1

其中:
   master-name是一个有大小写字母,数字和".-_"组成的主数据库的名字,因为考虑到故障恢复后当前监控系统的主数据库的地址和端口会产生变化,所以哨兵提供了命令可以通过主数据库的名字获取当前系统的主数据库的地址和端口号。
    ip 表示当前系统中主数据库的地址,而redis-port则表示端口号。
    quornum 用来表示执行故障恢复操作前至少需要几个哨兵结点同意。
    
需要注意的是,配置哨兵监控一个系统时,只需要配置其监控主数据库即可,哨兵会自动发现所有复制该主数据库的从数据库。

和主数据库的连接建立完成后,哨兵会定时执行下面3个操作:
* 每10秒哨兵会向主数据库和从数据库发送info命令。
* 每2秒哨兵会向主数据库和从数据库的_sentinel_:hello频道发送自己的信息。
* 每1秒哨兵会向主数据,从数据库和其他哨兵结点发送PING命令。


领头哨兵将从停止服务的主数据库的从数据中挑选一个来充当新的主数据库。挑选的依据如下:
(1)所有在线的从数据库中,选择优先级最高的从数据库。优先级可以通过slave-priority选项来设置。
(2)如果有多个最高优先级的从数据库,则复制的命令偏移量越大(即复制越完整)越优先。
(3)如果以上条件都一样,则选择运行ID较小的从数据库。
选出一个从数据库后,领头哨兵将向从数据库发送SLAVEOF NO ONE命令将其升格为主数据库。而后领头哨兵向其他从数据库发送SLAVEOF 命令来使其成为新主数据库的从数据库。
最后一步则是更新内部的记录,将已经停止服务的旧的主数据库更新为新的主数据库的从数据库,使得当其恢复服务时自动以从服务器的身份继续服务。

哨兵的部署:
    哨兵以独立进程的方式对一个主从系统进行监控,监控的效果好坏与否取决于哨兵的视角是否有代表性。如果一个主从系统中配置的哨兵较少,哨兵对整个系统的判断的可靠性就会降低。极端情况下,当只有一个哨兵时,哨兵本身就可能会发生单点故障。整体来讲,相对稳妥的哨兵部署方案是使得哨兵的视角尽可能地与每个节点的视角一致,即:
    (1)为每个结点(无论是主数据库还是从数据库)部署一个哨兵;
    (2)使得每个哨兵与其对应的节点的网络环境相同或相近。
    这样的部署方案可以保证哨兵的视角拥有较高的代表性和可靠性。
    同时设置quorum的值为N/2+1(其中N为哨兵节点数量),这样使得只有当大部分哨兵节点同意后才会进行故障恢复   


集群:    
       集群的特点在于拥有和单机实例同样的性能,同时在网络分区后能够提供一定的可访问性以及对主数据库故障恢复的支持。另外集群支持几乎所有的单机实例支持的命令,对于涉及多个的命令(如MGET),如果每个键都位于同一个节点中,才可以正常支持,否则会提示错误。除此之外集群还有一个限制是只能使用默认的0号数据库,如果执行SELECT 切换数据库则会提示错误。
     哨兵和集群是两个独立的功能,但从特性来看哨兵可以视为集群的子集,当不需要数据分片或者已经在客户端进行分片的场景下哨兵就足够使用了,但如果需要进行水平扩容,则集群是一个非常好的选择

配置集群:
    使用集群,只需要将每个数据库节点的cluster-enabled配置选项打开即可。每个集群中至少需要3个主数据库才能正常运行。

cluster-enabled yescluster-config-file nodes.config

实验:

cluster-enabled yes
cluster-config-file nodes.7000.conf #个性化
cluster-node-timeout 5000
appendonly yes
appendfilename "appendonly.7000.aof" #个性化
daemonize yes
pidfile #个性化
log #个性化

以7000-70005六个不同的port启动。

[root@localhost 7005]# ps -aux|grep redis
Warning: bad syntax, perhaps a bogus '-'? See /usr/share/doc/procps-3.2.8/FAQ
root      4423  0.0  0.1 133540  7552 ?        Ssl  14:54   0:00 /mnt/shares/redis/redis-3.2.0/src/redis-server 127.0.0.1:7000 [cluster]
root      4432  0.0  0.1 133540  7556 ?        Ssl  14:54   0:00 /mnt/shares/redis/redis-3.2.0/src/redis-server 127.0.0.1:7001 [cluster]
root      4441  0.0  0.1 133540  7556 ?        Ssl  14:55   0:00 /mnt/shares/redis/redis-3.2.0/src/redis-server 127.0.0.1:7002 [cluster]
root      4449  0.0  0.1 133540  7556 ?        Ssl  14:55   0:00 /mnt/shares/redis/redis-3.2.0/src/redis-server 127.0.0.1:7003 [cluster]
root      4454  0.0  0.1 133540  7556 ?        Ssl  14:55   0:00 /mnt/shares/redis/redis-3.2.0/src/redis-server 127.0.0.1:7004 [cluster]
root      4460  0.0  0.1 133540  7552 ?        Ssl  14:56   0:00 /mnt/shares/redis/redis-3.2.0/src/redis-server 127.0.0.1:7005 [cluster]
root      4464  0.0  0.0 103252   840 pts/1    S+   14:56   0:00 grep redis

初始化集群

其中create参数表示要初始化集群, --replicas 1 表示每个主数据库拥有的从数据库个数为1,所以下面整个集群共有3(6/2)个主数据库以及3个从数据库。

[root@localhost src]# ./redis-trib.rb create --replicas 1 172.16.81.107:7000 172.16.81.107:7001 172.16.81.107:7002 172.16.81.107:7003 172.16.81.107:7004 172.16.81.107:7005  
>>> Creating cluster
>>> Performing hash slots allocation on 6 nodes...
Using 3 masters:
172.16.81.107:7000
172.16.81.107:7001
172.16.81.107:7002
Adding replica 172.16.81.107:7003 to 172.16.81.107:7000
Adding replica 172.16.81.107:7004 to 172.16.81.107:7001
Adding replica 172.16.81.107:7005 to 172.16.81.107:7002
M: 9e3a1e4883393552357e41507f3da851370dbe4b 172.16.81.107:7000slots:0-5460 (5461 slots) master
M: de7a63cd01e477c49a31f53837b72c7814f4b274 172.16.81.107:7001slots:5461-10922 (5462 slots) master
M: c7b1fbf25def810a42f5f61a0b16e62f538861b7 172.16.81.107:7002slots:10923-16383 (5461 slots) master
S: d86d4a4f6246362e06f2a266f2a9fec3c5942541 172.16.81.107:7003replicates 9e3a1e4883393552357e41507f3da851370dbe4b
S: 43b99ad59f4519f915c86a6ff5bd6189e211e080 172.16.81.107:7004replicates de7a63cd01e477c49a31f53837b72c7814f4b274
S: 7ffe9792caf077cee3f8d545278d08afbf456d77 172.16.81.107:7005replicates c7b1fbf25def810a42f5f61a0b16e62f538861b7
Can I set the above configuration? (type 'yes' to accept): 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 172.16.81.107:7000)
M: 9e3a1e4883393552357e41507f3da851370dbe4b 172.16.81.107:7000slots:0-5460 (5461 slots) master
M: de7a63cd01e477c49a31f53837b72c7814f4b274 172.16.81.107:7001slots:5461-10922 (5462 slots) master
M: c7b1fbf25def810a42f5f61a0b16e62f538861b7 172.16.81.107:7002slots:10923-16383 (5461 slots) master
M: d86d4a4f6246362e06f2a266f2a9fec3c5942541 172.16.81.107:7003slots: (0 slots) masterreplicates 9e3a1e4883393552357e41507f3da851370dbe4b
M: 43b99ad59f4519f915c86a6ff5bd6189e211e080 172.16.81.107:7004slots: (0 slots) masterreplicates de7a63cd01e477c49a31f53837b72c7814f4b274
M: 7ffe9792caf077cee3f8d545278d08afbf456d77 172.16.81.107:7005slots: (0 slots) masterreplicates c7b1fbf25def810a42f5f61a0b16e62f538861b7
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

集群中所有节点信息:

[root@localhost src]# redis-cli -p 7001
127.0.0.1:7001> cluster nodes
de7a63cd01e477c49a31f53837b72c7814f4b274 127.0.0.1:7001 myself,master - 0 0 2 connected 5461-10922
7ffe9792caf077cee3f8d545278d08afbf456d77 127.0.0.1:7005 slave c7b1fbf25def810a42f5f61a0b16e62f538861b7 0 1464161662246 3 connected
9e3a1e4883393552357e41507f3da851370dbe4b 127.0.0.1:7000 master - 0 1464161661243 1 connected 0-5460
c7b1fbf25def810a42f5f61a0b16e62f538861b7 127.0.0.1:7002 master - 0 1464161661744 3 connected 10923-16383
43b99ad59f4519f915c86a6ff5bd6189e211e080 127.0.0.1:7004 slave de7a63cd01e477c49a31f53837b72c7814f4b274 0 1464161660741 2 connected
d86d4a4f6246362e06f2a266f2a9fec3c5942541 127.0.0.1:7003 slave 9e3a1e4883393552357e41507f3da851370dbe4b 0 1464161661744 1 connected

节点的增加:

CLUSTER MSET ip port

 ip ,port 是集群中任意一个节点的地址和端口号,新节点(A)接收到客户端发来的命令后,
 会与该地址和端口号的节点B进行握手,使B将A认作当前集群中的一员。当B与A握手成功后,B会使用Gossip协议将节点A的信息通知给集群中的每一个节点。通过这一方式,即使集群中有多个节点,也只需要选择MSET其中任意一个节点,即可使新节点最终加入整个集群中。
 

启动一个port为7006的节点:

[root@localhost 7006]# /mnt/shares/redis/redis-3.2.0/src/redis-server ./redis.conf

执行下面的命令把新节点添加到集群中:

[root@localhost src]# ./redis-trib.rb add-node 127.0.0.1:7006 127.0.0.1:7000
>>> Adding node 127.0.0.1:7006 to cluster 127.0.0.1:7000
>>> Performing Cluster Check (using node 127.0.0.1:7000)
M: 9e3a1e4883393552357e41507f3da851370dbe4b 127.0.0.1:7000slots:0-5460 (5461 slots) master1 additional replica(s)
S: 7ffe9792caf077cee3f8d545278d08afbf456d77 127.0.0.1:7005slots: (0 slots) slavereplicates c7b1fbf25def810a42f5f61a0b16e62f538861b7
S: 43b99ad59f4519f915c86a6ff5bd6189e211e080 127.0.0.1:7004slots: (0 slots) slavereplicates de7a63cd01e477c49a31f53837b72c7814f4b274
S: d86d4a4f6246362e06f2a266f2a9fec3c5942541 127.0.0.1:7003slots: (0 slots) slavereplicates 9e3a1e4883393552357e41507f3da851370dbe4b
M: c7b1fbf25def810a42f5f61a0b16e62f538861b7 127.0.0.1:7002slots:10923-16383 (5461 slots) master1 additional replica(s)
M: de7a63cd01e477c49a31f53837b72c7814f4b274 127.0.0.1:7001slots:5461-10922 (5462 slots) master1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
>>> Send CLUSTER MEET to node 127.0.0.1:7006 to make it join the cluster.
[OK] New node added correctly.
127.0.0.1:7000> cluster nodes
47a241ed17b89f501d3ea6e337456fab2ddd1e93 127.0.0.1:7006 master - 0 1464163321583 0 connected
7ffe9792caf077cee3f8d545278d08afbf456d77 127.0.0.1:7005 slave c7b1fbf25def810a42f5f61a0b16e62f538861b7 0 1464163320582 6 connected
43b99ad59f4519f915c86a6ff5bd6189e211e080 127.0.0.1:7004 slave de7a63cd01e477c49a31f53837b72c7814f4b274 0 1464163320082 5 connected
d86d4a4f6246362e06f2a266f2a9fec3c5942541 127.0.0.1:7003 slave 9e3a1e4883393552357e41507f3da851370dbe4b 0 1464163320082 4 connected
c7b1fbf25def810a42f5f61a0b16e62f538861b7 127.0.0.1:7002 master - 0 1464163322084 3 connected 10923-16383
9e3a1e4883393552357e41507f3da851370dbe4b 127.0.0.1:7000 myself,master - 0 0 1 connected 0-5460
de7a63cd01e477c49a31f53837b72c7814f4b274 127.0.0.1:7001 master - 0 1464163321083 2 connected 5461-10922

插槽的分配:
    未完成

获取与插槽对应的结点:
    当客户端向集群中的任意一个结点发送命令后,该结点会判断相应的键是否在当前结点中,
    如果键在该结点中,则会像单机实例一样正常处理该命令;
    如果键不在该结点中,就会返回一个MOVE重定向请求,告诉客户端这个键目前由哪个结点负责,然后客户端再将同样的请求向目标节点重新发送一次以获取结果。
    
    Redis命令行客户端提供了集群模式来支持自动重定向,使用-c参数来启用:

redis-cli -c -p 6380

加入参数-c后,如果当前结点并不负责要处理的键,Redis命令行客户端会进行自动命令重定向。而这一过程正是每个支持集群的客户端应该实现的。
    
故障恢复:
    在集群中,当一个主数据库下线时,就会出现一部分插槽无法写入的问题。这时如果该主数据库拥有至少一个从数据库,集群就进行故障恢复操作来将其中一个从数据库转变成主数据库来保证 集群的完整。选择哪个从数据库来作为主数据库的过程与在哨兵中选择领头哨兵的过程一样,都是 Raft算法,过程如下:
    1. 发现复制的主数据库下线的从数据库(下面称作A)向每个集群中的节点发送请求,要求对方选自己成为主数据库。
    2. 如果收到请求的节点没有选过其他人,则会同意将A设置为主数据库。
    3. 如果A发现有超过集群中节点总数一半的节点同意选自己成为主数据库,则A则成功成为主数据库。
    4. 当有多个从数据库结点同时参选主数据库,则会出现没有任何节点当选的可能。此时每个参选结点节点将等待一个随机时间重新发起参选请求,进行下一轮选举,直到选举成功。
       
       当某个从数据库当选为主数据库后,会通过命令SLAVEOF ON ONE 将自己转换成主数据库,并将旧的主数据库的插槽转换给自己负责。
      
      如果一个至少负责一个插槽的主数据库下线且没有相应的从数据库可以进行故障恢复,则整个集群默认会进入下线状态无法继续工作。如果想在这种情况下使集群仍能正常工作,可以
      修改配置cluster-require-full-coverage 为no(默认yes)   

cluster-require-full-coverage no

 

转载于:https://my.oschina.net/lvhuizhenblog/blog/680287

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/261232.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

POJ 2409 Let it Bead (Polya定理)

题意 用k种颜色对n个珠子构成的环上色,旋转翻转后相同的只算一种,求不等价的着色方案数。 思路 Polya定理 X是对象集合{1, 2, ……, n}, 设G是X上的置换群,用M种颜色染N种对象,则不同的染色方案数为: λ(g)…

java10支持mybatis_写了10年的代码,我最怕写Mybatis这些配置,现在有详解了

作者 | 阿进的写字台链接 | www.cnblogs.com/homejim/p/9782403.html在使用 mybatis 过程中, 当手写 JavaBean和XML 写的越来越多的时候, 就越来越同意出错。这种重复性的工作, 我们当然不希望做那么多。还好, mybatis 为我们提供…

webservice-WebService试题

ylbtech-doc:webservice-WebService试题WebService试题 1.A,返回顶部001.{WebService题目}下列是Web服务体系结构中的角色的是()(选择3项) A)服务提供者 B)服务请求者 C&#…

Session的模拟

Session相关的mock Session相关的mock主要有以下两个步骤: 1) HttpContext对象的实例化 session属于HttpContext对象,所以简单来说,就是我们需要构造一个HttpContext,对象然后在给其中的Session附值。然后再把它指定到…

C++ STL的基本基本原理

STL都是在内存的堆区分配的,但是其析构也是STL帮我们做好的,不用手动去delete。 1.vector 逻辑地址连续的一片内存空间,当空间不足,重新申请新的地址空间,将原有的数据复制过去,而新的地址空间的大小C没有规…

iOS 修改项目名称

2019独角兽企业重金招聘Python工程师标准>>> 1. [代码]iOS 修改项目名称 1 2. [图片] 1.png 3. [图片] 2.png 4. [图片] 3.png 5. [图片] 4.png 6. [图片] 5.png 转载于:https://my.oschina.net/5951008876/blog/681857

java wait源码_Java精通并发-透过openjdk源码分析wait与notify方法的本地实现

上一次https://www.cnblogs.com/webor2006/p/11442551.html中通过openjdk从c的底层来审视了ObjectMonitor的底层实现,这次继续来探究底层,对于wait()和notify()的底层细节到底是啥样的呢?下面还是先来到openjdk中来打开ObjectMonitor.hpp&…

listActivity和ExpandableListActivity的简单用法

今天自己简单的总结了listActivity和ExpandableListActivity二者的简单用法。 首先,先说一下listActivity的用法: ListActivity是一个绑定到一个数据源,并且用来显示这一串数据的Activity。ListActivity拥有一个listview对象来实现数据源的绑…

搭建git for windows服务器(100%可以成功)【转】

转自:http://blog.csdn.net/code_style/article/details/38764203 既然Git在linux下面非常好用,为什么还要搭建git windows的服务器,因为不是所有的用户都需要在linux下面做开发,对吧,还有很多用户选择使用windows做开…

【转】高性能WEB开发系列之重绘与回流

原文转载:http://www.cnblogs.com/wangzhichao/archive/2011/05/16/2047633.html页面呈现流程 在讨论页面重绘、回流之前。需要对页面的呈现流程有些了解,页面是怎么把html结合css等显示到浏览器上的,下面的流程图显示了浏览器对页面的呈现的…

[数据结构与算法] 单链表的简单demo

Vc6之下编译通过。。 1 /*******************************************************2 * : Project: 单链表数据结构演示3 * : File: link_list.h4 * : Function: 提供单链表操作的数据结构定义及方法声明5 * : History: 2013-10-01 22:37:056 * : Auth…

c++ 17介绍

作者:hearts zh链接:https://www.zhihu.com/question/32222337/answer/55238928来源:知乎著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。其实现在的proposal很多很多,不出意外也会有相当一部分…

“高考”机器人横空出世 2017年居然要考“大学”

文/辛东方,80后作家、专栏作者、专注互联网科技领域人工智能的发展,科学技术的全力配合,已经把人类的智慧实实在在的体现到了智能化设备上。按照目前的发展速度,人工智能要想真正突破技术难关,达到进一步的智能化&…

谁说菜鸟不会数据分析--数据分析那些事儿

一、数据分析是“神马” 1、 何谓数据分析 简单来说,数据分析就是对数据进行分析,较为专业的说法,数据分析是指用适当的统计分析方法对收集来的大量数据进行分析,将它们加以汇总、理解并消化,以求最大化地开发数据的功…

优集品 php,从细节处着眼 优集品打造成人世界的儿童节

在各大电商企业仍旧在史上最大规模的价格战中拼的不可开交之时,重视用户体验度,以商品传递生活理念而知名的全球优选设计百货--LivePort优集品(http://www.liveport.cn/),已然细心的为眼下即将来临的六一儿童节策划了一餐盛宴,为追…

java中ssm付款代码,ssm实现支付宝支付功能(图文详解)

目录1、支付宝沙箱环境测试2、支付宝整合到ssm环境3、微信支付整合到ssm环境一、支付宝测试环境代码测试1.下载电脑网站的官方demo:2.下载解压导入eclipsereadme.txt请好好看一下。只有一个Java配置类,其余都是JSP。3.配置AlipayConfig(1).注册蚂蚁金服开…

获取android手机的屏幕分辨率 android开发

2019独角兽企业重金招聘Python工程师标准>>> /** * 获取屏幕分辨率 */ private void getResolution() { // TODO Auto-generated method stub Display display getWindowManager().getDefaultDisplay(); DisplayMetrics displayMetrics new DisplayMetrics(); dis…

Python线程指南 ---转自 http://www.cnblogs.com/huxi/archive/2010/06/26/1765808.html

Python线程指南 ---转自 http://www.cnblogs.com/huxi/archive/2010/06/26/1765808.html 本文介绍了Python对于线程的支持,包括“学会”多线程编程需要掌握的基础以及Python两个线程标准库的完整介绍及使用示例。 注意:本文基于Python2.4完成&#xff0c…

有的日期输入框,可直接调用javascripts

转载于:https://www.cnblogs.com/rf-bear/p/5549126.html

TigerDLNA for ios 集成Tlplayer

好久没有写博客了,这次带着TigerDLNA for ios 跟大家见面 什么都不说先上图 1.优点 优点由于libTigerDLNA使用uiview封装,所以大家可以很方便的集成到自己的项目中。由于集成了tlplayer当然也可以只是作为一个播放器来使用,支持各种网络协议。…