精华内容
下载资源
问答
  • redis集群模式

    万次阅读 2020-10-12 22:31:31
    现在的redis也不断在更新,现在的rediscluster,原生的redis集群模式,就可以做到在多台机器上部署多个redis实例,每个实例存储一部分数据,同时每个redis可以挂redis从实例,自动确保说,如果redis主实例挂了,会...

    以前的redis要搞几个节点,每个节点存储一部分的数据,得借助一些中间件来实现,比如说有codis、twemproxy,有一些redis中间件,你读写redis中间件,redis中间件负责将你的数据分布式存储在多个机器上的redis实例中。

    现在的redis也不断在更新,现在的rediscluster,原生的redis集群模式,就可以做到在多台机器上部署多个redis实例,每个实例存储一部分数据,同时每个redis可以挂redis从实例,自动确保说,如果redis主实例挂了,会自动切换到redis从实例。
    按照以前的redis架构,master节点的数据和slave节点的数据是一摸一样的,master能容纳多大的数据量,那么slave也就只能容纳多大的数据量。使用缓存清理算法可以释放空间,将旧的很少使用的数据,给清除出内存,然后保证内存中就只有固定大小的内存,不可能超过master内存的物理上限的。
    这就是单master所导致的瓶颈问题。

    分布式数据存储的核心算法,数据分布的算法:
    hash算法 –>一致性hash算法 ->rediscluster的hashslot算法
    用不同的算法,就决定了在多个master节点的时候,数据如何分布到这些节点上的问题。

    (1) redis集群模式的工作原理

    1. 自动将数据进行分片,每个master上放一部分数据
    2. 提供内置的高可用支持,部分master不可用时,还能继续工作。
    3. 在rediscluster下,每个redis要开放两个端口,比如一个是6379这种4位数的端口,另外一个就是10000数值后的端口,比如16379端口。
      这个16379端口号是用来进行节点通信的,也就是clusterbus的东西,集群总线。
      clusterbus的通信,用来进行故障检测,配置更新,故障转移授权。
      clusterbus用了另外一种二进制的协议,主要用于节点间进行高效的数据交换,占用更少的网络带宽和处理时间。

    (2) hash算法
    原理:来了一个key之后,计算hash值,然后对节点数量(3)取模,取模结果一定是在0-2之间的,小于节点数量。
    这样计算后,就可以打到对应的3个masternode上去,这样就实现了最简单的数据分布算法。
    问题所在:一旦有一个masternode宕机了,请求过来后,会基于剩下的两个master去取模,原来是对3取模,现在是对2取模,原来的数据也不能用了,导致几乎大部分请求,全部无法拿到有效的缓存,大量的流量就会涌入数据库中。
    高并发的场景来说,是不可以接受这样的,1/3的流量不能走缓存,全部走数据库,那么数据库就会被压垮。所以,hash算法最大的问题就是,只要有任意一个master宕机,那么大量的数据就需要重新写入缓存,风险很大。
    (3) 一致性Hash算法+ 虚拟节点算法
    原理:有一个key过来以后,同样是计算hash值,然后会用hash值在圆环对应的各个点上(每个点都会有一个hash值)去比对,看hash值应该落在这个圆环的哪个部位。key落在圆环上以后,就会顺时针旋转去寻找距离自己最近的一个节点。
    一旦有一台圆环上的master宕机,过来key后,就会顺时针去下一个节点去取值,但是取不到值。
    一致性hash算法,保证,任何一个master宕机,只有之前在那个master上的数据会受到影响,因为照着顺时针走,全部在之前的master上找不到了,master宕机了,会顺时针走到下一个master去,也是找不到的。那么就会有1/3的流量瞬间涌入数据库中去查找数据。
    问题所在:缓存热点的问题,可能集中在某个hash区间内的值特别多,那么会导致大量的数据都涌入同一个master内,造成master的热点问题,性能出现瓶颈。

    虚拟节点算法:给每个master都做了均匀分布的虚拟节点。
    这样的话,在每个区间内,大量的数据,都会均匀的分布到不同的节点内,而不是按照顺时针的顺序去走,不会全部涌入同一个master内

    (4) hashsolt算法
    rediscluster有固定的16384个hashsolt,对每个key计算CRC16值,然后对16384取模,可以获取key对应的hashsolt。
    rediscluster中每个master都会持有部分slot,比如有3个master,那么可能每个master持有5000多个hashsolt。
    hashsolt让node的增加和移除变得很简单,增加一个master,就将其他master的hashsolt移动部分过去,减少一个master,就将它的hashsolt移动到其他master上去,移动hashsolt的成本是非常低的。
    在集群中,任何一台master宕机,另外两个节点不影响,因为key找的是hashsolt,找的不是机器

    (5) 在集群模式下,redis的key是如何寻址的?

    (6) rediscluster
    可以支撑N个redismasternode,每个masternode都可以挂载多个slavenode,能够继续保持读写分离的结构,对于每个master来说,写就写到master,然后读就从master对应的slave去读。
    高可用方面,因为每个master都有slave节点,那么如果master挂掉,rediscluster这套机制,就会自动将某个slave切换成master。
    简而言之,rediscluster就是(多master + 读写分离 + 高可用),我们只要基于rediscluster去搭建redis集群即可,不需要手工去搭建replication复制+主从架构+读写分离+哨兵集群+高可用

    (7) rediscluster和 replication + sentinal
    如果你的数据量很少,主要是承载高并发高性能的场景,比如你的缓存一般就是几个G,那么单机足够了,就搭建replication+一个master+多个slave,要几个slave跟你的要求的读吞吐量有关系,然后自己搭建一个sentinal集群,保证redis的高可用性。
    rediscluster,主要是针对海量数据+高可用的场景。

    (8) rediscluster节点间的内部通信机制

    1. 基础通信原理
      一、 rediscluster节点间采取gossip协议进行通信
      跟集中式不同,不是将集群元数据(节点信息,故障,等等)集中存储在某个节点上,而是互相之间不断通信,保持整个集群所有节点的数据是完整的。

    集中式:集群元数据集中式存储的一个典型代表,就是大数据领域的storm,分布式的大数据实时计算引擎,集中式的元数据存储的架构,底层基于zookeeper(分布式协调的中间件)的集群所有元数据维护。
    (好处:元数据的更新和读取,时效性非常好,一旦元数据出现了变更,立即就更新到集中式的存储中,其他的节点读取的时候就可以立即感知到。
    缺点:所有的元数据更新压力全部集中在一个地方,可能会导致元数据的存储有压力。)

    gossip协议:小道留言,所有节点都持有一份元数据,不同的节点如果出现了元数据的表更之后,就不断的将元数据发送给其他节点,让其他节点也进行元数据的变更。
    (好处:元数据的更新比较分散,不是集中在一个地方的,更新请求会陆陆续续打到节点上更新,有一定延时,降低了压力。
    缺点:元数据的更新有延时,可能导致集群的一些操作会有一些滞后。)

    二、 10000端口
    每个节点都有一个用于节点间通信的端口,就是自己提供服务的端口号+10000,比如7001,那么用于节点间通信的就是17001端口。

    三、 gossip协议
    gossip协议包含多种消息,包括ping,pong,meet,fail等等。

    meet:某个节点发送meet给新加入的节点,让新节点加入集群中,然后新节点就会开始与其他节点进行通信。
    redis-trib.rb add-node
    其实内部就是发送了一个gossipmeet消息,给新加入的节点,通知那个节点去加入我们的集群。

    ping:每个节点都会频繁给其他节点发送ping,其中包含自己的状态还有自己维护的集群元数据,互相通过ping交换元数据。

    pong:返回ping和meet,包含自己的状态和其他信息,也可以用于信息广播和更新

    fail:某个节点判断另一个节点fail之后,就发送fail给其他节点,通知其他节点,指定的节点宕机了。

    四、 ping消息深入

    ping很频繁,而且要携带一些元数据,所以可能会加重网络负担。

    每个节点每秒会执行10次ping,每次会选择5个最近没有通信的其他节点。

    当然如果发现某个节点通信延时达到了cluster_node_timeout/2,那么立即发送ping,避免数据交互交换延时过长,滞后的时间太长了。

    每次ping,一个是带上自己的节点信息,然后就是带上1\10其他接节点的信息,发送出去,进行数据交换。至少包含3个其他节点的信息,最多包含总结点n-2个其他节点的信息。

    1. 面向集群的jedis内部实现原理
      开发中:使用jedis,就是redis的javaclient客户端,我们现在是rediscluster,那么就是使用的jedisclusterapi
      jedisclusterapi与rediscluster集群交互的一些基本原理
      一、 基于重定向的客户端
      a、 请求重定向
      客户端可能会挑选任意一个redis实例去发送命令,每个redis实例接收到命令,都会计算hashslot。

    如果在本地就在本地处理,否则返回moved给客户端,让客户端进行重定向。

    clusterkeyslotmykey,可以查看一个key对应的hashslot是什么。

    用redis-cli的时候,可以加入-c参数,支持自动的请求重定向,redis-cli接收到moved之后,会自动重定向到对应的节点执行命令。
    b、 计算hashslot
    计算hashslot的算法,就是根据key计算CRC16值,然后对16384取模,拿到对应的hashslot。

    用hashtag可以手动指定key对应的slot,同一个hashtag下的key,都会在同一个hashslot中,比如setmykey:{100}
    c、 hashslot查找
    节点间通过gossip协议进行数交换,就只到每个hashslot在哪个节点上。
    二、 smartjedis
    a、 什么是smartjedis
    基于重定向的客户端,很消耗网络IO,因为大部分情况下,可能都会出现一次请求重定向,才能找到正确的节点。

    所以大部分的客户端,比如javaredis客户端,就是jedis,都是smart的。

    本地维护一份hashslot->node的映射表,缓存,大部分情况下,直接走本地缓存就可以找到hashslot->node,不需要通过节点进行moved重定向。

    b、 JedisCluster的工作原理
    其实就是维护了一个hash slot ->node映射表

    在JedisCluster初始化的时候,就会随机选择一个node,初始化hashslot->node映射表,同时为每个节点创建一个JedisPool连接池。

    每次基于JedisCluster执行操作,首先JedisCluster都会在本地就按key的hashslot,然后在本地映射表中找到对应的节点。

    如果那个node正好还是持有那个hashslot,那么就ok;如果说进行了reshard这样的操作,可能hashslot已经不在那个node上了,就会返回moved。

    如果JedisCluster API发现对应的节点返回moved,那么利用该节点的元数据,更新本地的hashslot->node映射表缓存。

    重复上面几个步骤,知道找到对应的节点,如果重试超过5次,那么就会报出JedisClusterMaxRedirectionException。

    jedis老版本,可能会出现在集群某个节点故障还没完成自动切换恢复时,频繁更新hashslot,频繁ping节点检查
    c、 hashslot迁移和ask重定向
    如果hashslot正在迁移,那么会返回ask重定向给jedis

    jedis接收到ask重定向之后,会重新定位到目标节点去执行,但是因为ask发生在hashslot迁移过程中,所以JedisClusterApi是不会更新hashslot本地缓存

    已经可以确定说,hashSlot已经迁移完了,moved是会更新hashslot -> node映射表缓存的
    3. 高可用性与主备切换原理
    rediscluster的高可用的原理,几乎跟哨兵是类似的。
    一、 判断节点宕机
    如果一个节点认为另一个节点宕机,那么就是pfail,主观宕机。

    如果多个节点都认为另一个节点宕机了,那么就是fail,客观宕机,跟哨兵的原理几乎一样的。

    在cluster-node-timeout内,某个节点一直没有返回pong,那么就被认为pfail。

    如果一个节点认为某个节点pfail了,那么会在gossip消息中,ping给其他节点,如果超过半数的节点都认为pfail了,那么就会变成fail。

    二、 从节点过滤
    对宕机的masternode,从其所有的slavenode中,选择一个切换成masternode。

    检查每个slavenode与masternode断开连接的时间,如果超过了cluster-node-timeout * cluster-salve-validity-factor,那么就没有资格切换成master。

    这个跟哨兵是一样的,从节点超时过滤的步骤。
    三、 从节点选举
    哨兵:对所有的slavenode进行排序,slavepriority,offset,runid

    每个从节点,都根据自己对master复制数据的offset,来设置一个选举时间,offset越大(复制数据越多)的节点,选举时间越靠前,优先进行选举。

    所有的masternode开始slave选举投票,给要进行选举的slave进行投票,如果大部分masternode(N/2+1)都投票给了某个从节点,那么选举通过,那个从节点可以切换成master。

    从节点执行主备切换,从节点切换为主节点。

    四、 与哨兵比较
    整个流程跟哨兵相比,非常类似,所以说,rediscluster功能强大,直接集成了replication和sentinal功能。

    展开全文
  • Redis集群模式

    千次阅读 2018-03-19 15:13:07
    此文由多处转载,自行组织,水平有限,有错误,望大家指正。 现在越来越多的项目都会利用到redis,多实例redis服务比单实例要...Redis官方 Cluster集群模式(服务端sharding) Jedis sharding集群(客户端shardin...

    此文由多处转载,自行组织,水平有限,有错误,望大家指正。

    现在越来越多的项目都会利用到redis,多实例redis服务比单实例要复杂的多,这里面涉及到定位、容错、扩容等技术问题。我们常用sharding技术来对此进行管理,其集群模式主要有以下几种方式:

    1. 主从复制
    2. 哨兵模式
    3. Redis官方 Cluster集群模式(服务端sharding)
    4. Jedis sharding集群(客户端sharding)
    5. 利用中间件代理

    我们现看看主从复制、和哨兵模式,这是其它集群的基础配置.

    主从复制(Master-Slave Replication)

    实现主从复制(Master-Slave Replication)的工作原理:Slave从节点服务启动并连接到Master之后,它将主动发送一个SYNC命令。Master服务主节点收到同步命令后将启动后台存盘进程,同时收集所有接收到的用于修改数据集的命令,在后台进程执行完毕后,Master将传送整个数据库文件到Slave,以完成一次完全同步。而Slave从节点服务在接收到数据库文件数据之后将其存盘并加载到内存中。此后,Master主节点继续将所有已经收集到的修改命令,和新的修改命令依次传送给Slaves,Slave将在本次执行这些数据修改命令,从而达到最终的数据同步。

    如果Master和Slave之间的链接出现断连现象,Slave可以自动重连Master,但是在连接成功之后,一次完全同步将被自动执行。

    主从复制配置
    • 修改从节点的配置文件:slaveof masterip masterport
    • 如果设置了密码,就要设置:masterauth master-password
    主从模式的优缺点

    优点:

    • 同一个Master可以同步多个Slaves。
    • Slave同样可以接受其它Slaves的连接和同步请求,这样可以有效的分载Master的同步压力。因此我们可以将Redis的Replication架构视为图结构。
    • Master Server是以非阻塞的方式为Slaves提供服务。所以在Master-Slave同步期间,客户端仍然可以提交查询或修改请求。
    • Slave Server同样是以非阻塞的方式完成数据同步。在同步期间,如果有客户端提交查询请求,Redis则返回同步之前的数据
    • 为了分载Master的读操作压力,Slave服务器可以为客户端提供只读操作的服务,写服务仍然必须由Master来完成。即便如此,系统的伸缩性还是得到了很大的提高。
    • Master可以将数据保存操作交给Slaves完成,从而避免了在Master中要有独立的进程来完成此操作。
    • 支持主从复制,主机会自动将数据同步到从机,可以进行读写分离。

    缺点:

    • Redis不具备自动容错和恢复功能,主机从机的宕机都会导致前端部分读写请求失败,需要等待机器重启或者手动切换前端的IP才能恢复。
    • 主机宕机,宕机前有部分数据未能及时同步到从机,切换IP后还会引入数据不一致的问题,降低了系统的可用性。
    • Redis的主从复制采用全量复制,复制过程中主机会fork出一个子进程对内存做一份快照,并将子进程的内存快照保存为文件发送给从机,这一过程需要确保主机有足够多的空余内存。若快照文件较大,对集群的服务能力会产生较大的影响,而且复制过程是在从机新加入集群或者从机和主机网络断开重连时都会进行,也就是网络波动都会造成主机和从机间的一次全量的数据复制,这对实际的系统运营造成了不小的麻烦。
    • Redis较难支持在线扩容,在集群容量达到上限时在线扩容会变得很复杂。为避免这一问题,运维人员在系统上线时必须确保有足够的空间,这对资源造成了很大的浪费。

    其实redis的主从模式很简单,在实际的生产环境中是很少使用的,我也不建议在实际的生产环境中使用主从模式来提供系统的高可用性,之所以不建议使用都是由它的缺点造成的,在数据量非常大的情况,或者对系统的高可用性要求很高的情况下,主从模式也是不稳定的。

    哨兵模式

    该模式是从Redis的2.6版本开始提供的,但是当时这个版本的模式是不稳定的,直到Redis的2.8版本以后,这个哨兵模式才稳定下来,无论是主从模式,还是哨兵模式,这两个模式都有一个问题,不能水平扩容,并且这两个模式的高可用特性都会受到Master主节点内存的限制。

    Sentinel(哨兵)进程是用于监控redis集群中Master主服务器工作的状态,在Master主服务器发生故障的时候,可以实现Master和Slave服务器的切换,保证系统的高可用。

    Sentinel(哨兵)进程的作用
    1. 监控(Monitoring): 哨兵(sentinel) 会不断地检查你的Master和Slave是否运作正常。
    2. 提醒(Notification):当被监控的某个Redis节点出现问题时, 哨兵(sentinel) 可以通过 API 向管理员或者其他应用程序发送通知。
    3. 自动故障迁移(Automatic failover):当一个Master不能正常工作时,哨兵(sentinel) 会开始一次自动故障迁移操作,它会将失效Master的其中一个Slave升级为新的Master, 并让失效Master的其他Slave改为复制新的Master;当客户端试图连接失效的Master时,集群也会向客户端返回新Master的地址,使得集群可以使用现在的Master替换失效Master。Master和Slave服务器切换后,Master的redis.conf、Slave的redis.conf和sentinel.conf的配置文件的内容都会发生相应的改变,即,Master主服务器的redis.conf配置文件中会多一行slaveof的配置,sentinel.conf的监控目标会随之调换。
    Sentinel(哨兵)进程的工作方式
    1. 每个Sentinel(哨兵)进程以每秒钟一次的频率向整个集群中的Master主服务器,Slave从服务器以及其他Sentinel(哨兵)进程发送一个 PING 命令。
    2. 如果一个实例(instance)距离最后一次有效回复 PING 命令的时间超过 down-after-milliseconds 选项所指定的值, 则这个实例会被 Sentinel(哨兵)进程标记为主观下线(SDOWN)
    3. 如果一个Master主服务器被标记为主观下线(SDOWN),则正在监视这个Master主服务器的所有 Sentinel(哨兵)进程要以每秒一次的频率确认Master主服务器的确进入了主观下线状态
    4. 当有足够数量的 Sentinel(哨兵)进程(大于等于配置文件指定的值)在指定的时间范围内确认Master主服务器进入了主观下线状态(SDOWN), 则Master主服务器会被标记为客观下线(ODOWN)
    5. 在一般情况下, 每个 Sentinel(哨兵)进程会以每 10 秒一次的频率向集群中的所有Master主服务器、Slave从服务器发送 INFO 命令。
    6. 当Master主服务器被 Sentinel(哨兵)进程标记为客观下线(ODOWN)时,Sentinel(哨兵)进程向下线的 Master主服务器的所有 Slave从服务器发送 INFO 命令的频率会从 10 秒一次改为每秒一次。
    7. 若没有足够数量的 Sentinel(哨兵)进程同意 Master主服务器下线, Master主服务器的客观下线状态就会被移除。若 Master主服务器重新向 Sentinel(哨兵)进程发送 PING 命令返回有效回复,Master主服务器的主观下线状态就会被移除。
    哨兵模式的优缺点

    优点:

    • 哨兵集群模式是基于主从模式的,所有主从的优点,哨兵模式同样具有。
    • 主从可以切换,故障可以转移,系统可用性更好。
    • 哨兵模式是主从模式的升级,系统更健壮,可用性更高。

    缺点:

    • Redis较难支持在线扩容,在集群容量达到上限时在线扩容会变得很复杂。为避免这一问题,运维人员在系统上线时必须确保有足够的空间,这对资源造成了很大的浪费。
    • 配置复杂

    Redis官方 Cluster集群模式

    Redis Cluster是一种服务器Sharding技术,3.0版本开始正式提供。
    这里写图片描述

    在这个图中,每一个蓝色的圈都代表着一个redis的服务器节点。它们任何两个节点之间都是相互连通的。客户端可以与任何一个节点相连接,然后就可以访问集群中的任何一个节点。对其进行存取和其他操作。

    Redis集群数据分片

    在redis的每一个节点上,都有这么两个东西,一个是插槽(slot)可以理解为是一个可以存储两个数值的一个变量这个变量的取值范围是:0-16383。还有一个就是cluster我个人把这个cluster理解为是一个集群管理的插件。当我们的存取的key到达的时候,redis会根据crc16的算法得出一个结果,然后把结果对 16384 求余数,这样每个 key 都会对应一个编号在 0-16383 之间的哈希槽,通过这个值,去找到对应的插槽所对应的节点,然后直接自动跳转到这个对应的节点上进行存取操作。
    这里写图片描述

    还有就是因为如果集群的话,是有好多个redis一起工作的,那么,就需要这个集群不是那么容易挂掉,所以呢,理论上就应该给集群中的每个节点至少一个备用的redis服务。这个备用的redis称为从节点(slave)。那么这个集群是如何判断是否有某个节点挂掉了呢?

    首先要说的是,每一个节点都存有这个集群所有主节点以及从节点的信息。

    它们之间通过互相的ping-pong判断是否节点可以连接上。如果有一半以上的节点去ping一个节点的时候没有回应,集群就认为这个节点宕机了,然后去连接它的备用节点。如果某个节点和所有从节点全部挂掉,我们集群就进入faill状态。还有就是如果有一半以上的主节点宕机,那么我们集群同样进入发力了状态。这就是我们的redis的投票机制,具体原理如下图所示:
    这里写图片描述

    • 投票过程是集群中所有master参与,如果半数以上master节点与master节点通信超时(cluster-node-timeout),认为当前master节点挂掉.
    • 什么时候整个集群不可用(cluster_state:fail)?
      1. 如果集群任意master挂掉,且当前master没有slave.集群进入fail状态,也可以理解成集群的slot映射[0-16383]不完整时进入fail状态. ps : redis-3.0.0.rc1加入cluster-require-full-coverage参数,默认关闭,打开集群兼容部分失败.
      2. 如果集群任意master挂掉,且当前master没有slave.集群进入fail状态,也可以理解成集群的slot映射[0-16383]不完整时进入fail状态. ps : redis-3.0.0.rc1加入cluster-require-full-coverage参数,默认关闭,打开集群兼容部分失败.

    Redis 3.0的集群方案有以下两个问题。

    1. 一个Redis实例具备了“数据存储”和“路由重定向”,完全去中心化的设计。这带来的好处是部署非常简单,直接部署Redis就行,不像Codis有那么多的组件和依赖。但带来的问题是很难对业务进行无痛的升级,如果哪天Redis集群出了什么严重的Bug,就只能回滚整个Redis集群。
    2. 对协议进行了较大的修改,对应的Redis客户端也需要升级。升级Redis客户端后谁能确保没有Bug?而且对于线上已经大规模运行的业务,升级代码中的Redis客户端也是一个很麻烦的事情。

    Redis Cluster是Redis 3.0以后才正式推出,时间较晚,目前能证明在大规模生产环境下成功的案例还不是很多,需要时间检验。

    Jedis sharding集群

    Redis Sharding可以说是在Redis cluster出来之前业界普遍的采用方式,其主要思想是采用hash算法将存储数据的key进行hash散列,这样特定的key会被定为到特定的节点上。

    这里写图片描述

    庆幸的是,Java Redis客户端驱动Jedis已支持Redis Sharding功能,即ShardedJedis以及结合缓存池的ShardedJedisPool

    Jedis的Redis Sharding实现具有如下特点:

    1. 采用一致性哈希算法,将key和节点name同时hashing,然后进行映射匹配,采用的算法是MURMUR_HASH。采用一致性哈希而不是采用简单类似哈希求模映射的主要原因是当增加或减少节点时,不会产生由于重新匹配造成的rehashing。一致性哈希只影响相邻节点key分配,影响量小。
    2. 为了避免一致性哈希只影响相邻节点造成节点分配压力,ShardedJedis会对每个Redis节点根据名字(没有,Jedis会赋予缺省名字)会虚拟化出160个虚拟节点进行散列。根据权重weight,也可虚拟化出160倍数的虚拟节点。用虚拟节点做映射匹配,可以在增加或减少Redis节点时,key在各Redis节点移动再分配更均匀,而不是只有相邻节点受影响。
    3. ShardedJedis支持keyTagPattern模式,即抽取key的一部分keyTag做sharding,这样通过合理命名key,可以将一组相关联的key放入同一个Redis节点,这在避免跨节点访问相关数据时很重要。

    当然,Redis Sharding这种轻量灵活方式必然在集群其它能力方面做出妥协。比如扩容,当想要增加Redis节点时,尽管采用一致性哈希,毕竟还是会有key匹配不到而丢失,这时需要键值迁移。
    作为轻量级客户端sharding,处理Redis键值迁移是不现实的,这就要求应用层面允许Redis中数据丢失或从后端数据库重新加载数据。但有些时候,击穿缓存层,直接访问数据库层,会对系统访问造成很大压力。

    利用中间件代理

    中间件的作用是将我们需要存入redis中的数据的key通过一套算法计算得出一个值。然后根据这个值找到对应的redis节点,将这些数据存在这个redis的节点中。

    常用的中间件有这几种

    • Twemproxy
    • Codis
    • nginx

    具体用法就不赘述了,可以自行百度。

    总结

    1. 客户端分片(sharding)需要客户端维护分片算法,这是一种静态的分片方案,需要增加或者减少Redis实例的数量,需要手工调整分片的程序。
    2. 利用中间件的情况则会影响到redis的性能,具体看中间件而定,毕竟所有请求都要经过中间件一层过滤
    3. 官方提供方案,现时点成功案例不多。
    展开全文
  • Redis集群模式之分布式集群模式

    千次阅读 2018-03-23 22:01:11
    Redis集群模式主要有2种: 主从集群 分布式集群。 前者主要是为了高可用或是读写分离,后者为了更好的存储数据,负载均衡。 本文主要讲解主从集群。本章主要讲解后一半部分,Redis集群。 与本文相关的代码与...

    前言

    Redis集群模式主要有2种:

    • 主从集群
    • 分布式集群。

    前者主要是为了高可用或是读写分离,后者为了更好的存储数据,负载均衡。
    本文主要讲解主从集群。本章主要讲解后一半部分,Redis集群。

    与本文相关的代码与配置文件都已经上传至github上:
    地址: https://github.com/SeanYanxml/bigdata


    原理

    Redis为了实现负载均衡,提供集群模式。以三个节点为例,集群模式相当于将1-15000片分片,分为1-5000、5000-10000、10000-15000。每个节点分一段数据片。这样的话,当一个节点宕机后,这个节点没有备份的话,此段分片将不再可以使用。所以,官方推荐,集群内的每个节点都应该配备一个从节点,作为冷备。部署原理图如下所示(暂略)。


    部署

    由于没有那么多的机器,所以我们一般单机部署6个节点(3主3从),也就是官网推荐的模式。

    主要步骤如下:

    • 安装ruby,因为分配集群的代码时ruby脚本;
    • 分配集群
    • 查看集群结果

    部署代码

    # mkdir cluster-test
    # cd cluster-test
    # mkdir 7000 7001 7002 7003 7004 7005
    # 在文件夹内 分别放置redis.conf文件 文件内容见下
    # 启动6个节点
    # nohup ../../src/redis-server  redis.conf > start.log 2>&1 &
    # 使用ruby脚本分配集群资源
    ./redis-trib.rb create --replicas 1 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
    # redis.conf
    port 7000
    cluster-enabled yes
    cluster-config-file nodes.conf
    cluster-node-timeout 5000
    appendonly yes
    ### 启动redis进程7000 7001 7002 7003 7004 7005
    
    touch start-all.sh
    ###  内容如下
    cd 7000
    nohup ../../src/redis-server  redis.conf > start.log 2>&1 &
    cd ../7001
    nohup ../../src/redis-server  redis.conf > start.log 2>&1 &
    cd ../7002
    nohup ../../src/redis-server  redis.conf > start.log 2>&1 &
    cd ../7003
    nohup ../../src/redis-server  redis.conf > start.log 2>&1 &
    cd ../7004
    nohup ../../src/redis-server  redis.conf > start.log 2>&1 &
    cd ../7005
    nohup ../../src/redis-server  redis.conf > start.log 2>&1 &
    
    chmod +x start-all.sh
    ./start-all.sh
    
    ps -ef|grep redis 查看进程
    [cpic@cpic-redis2-77 src]$ ps -ef|grep redis
    cpic     19876     1  0 321 ?       05:14:19 ./redis-server *:6379
    cpic     19886     1  0 321 ?       06:17:36 ./redis-sentinel *:26379 [sentinel]
    cpic     25971     1  0 15:07 pts/0    00:00:00 ../../src/redis-server *:7000 [cluster]
    cpic     25972     1  0 15:07 pts/0    00:00:00 ../../src/redis-server *:7001 [cluster]
    cpic     25973     1  0 15:07 pts/0    00:00:00 ../../src/redis-server *:7002 [cluster]
    cpic     25974     1  0 15:07 pts/0    00:00:00 ../../src/redis-server *:7003 [cluster]
    cpic     25975     1  0 15:07 pts/0    00:00:00 ../../src/redis-server *:7004 [cluster]
    cpic     25976     1  0 15:07 pts/0    00:00:00 ../../src/redis-server *:7005 [cluster]
    cpic     26273 24815  0 15:15 pts/0    00:00:00 grep --color=auto redis

    成功结果

    create 脚本初始化后脚本
    [root@cpic-redis-76 src]# ./redis-trib.rb create --replicas 1 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
    >>> Creating cluster
    >>> Performing hash slots allocation on 6 nodes...
    Using 3 masters:
    127.0.0.1:7000
    127.0.0.1:7001
    127.0.0.1:7002
    Adding replica 127.0.0.1:7003 to 127.0.0.1:7000
    Adding replica 127.0.0.1:7004 to 127.0.0.1:7001
    Adding replica 127.0.0.1:7005 to 127.0.0.1:7002
    M: 562665aca5f7db25bbd81e7b971c2f4c9aa65f96 127.0.0.1:7000
       slots:0-5460 (5461 slots) master
    M: 6f93b84f7da7d6ea1b77bce1709432de472bbbe3 127.0.0.1:7001
       slots:5461-10922 (5462 slots) master
    M: 6522a9ddec5b40cade141793351df44fe40a529f 127.0.0.1:7002
       slots:10923-16383 (5461 slots) master
    S: f122aea6aa02be27f77454c0fcde9c65b891cd47 127.0.0.1:7003
       replicates 562665aca5f7db25bbd81e7b971c2f4c9aa65f96
    S: e5b5bbd378d8b80250dca6fb5db80e755f88c53c 127.0.0.1:7004
       replicates 6f93b84f7da7d6ea1b77bce1709432de472bbbe3
    S: 93ac017741ad4e65a4de3cb17ae295e6e5505b9a 127.0.0.1:7005
       replicates 6522a9ddec5b40cade141793351df44fe40a529f
    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 127.0.0.1:7000)
    M: 562665aca5f7db25bbd81e7b971c2f4c9aa65f96 127.0.0.1:7000
       slots:0-5460 (5461 slots) master
       1 additional replica(s)
    M: 6f93b84f7da7d6ea1b77bce1709432de472bbbe3 127.0.0.1:7001
       slots:5461-10922 (5462 slots) master
       1 additional replica(s)
    S: e5b5bbd378d8b80250dca6fb5db80e755f88c53c 127.0.0.1:7004
       slots: (0 slots) slave
       replicates 6f93b84f7da7d6ea1b77bce1709432de472bbbe3
    M: 6522a9ddec5b40cade141793351df44fe40a529f 127.0.0.1:7002
       slots:10923-16383 (5461 slots) master
       1 additional replica(s)
    S: 93ac017741ad4e65a4de3cb17ae295e6e5505b9a 127.0.0.1:7005
       slots: (0 slots) slave
       replicates 6522a9ddec5b40cade141793351df44fe40a529f
    S: f122aea6aa02be27f77454c0fcde9c65b891cd47 127.0.0.1:7003
       slots: (0 slots) slave
       replicates 562665aca5f7db25bbd81e7b971c2f4c9aa65f96
    [OK] All nodes agree about slots configuration.
    >>> Check for open slots...
    >>> Check slots coverage...
    [OK] All 16384 slots covered.
    # 自动生成的node.conf文件
    [root@cpic-redis-76 7005]# cat nodes.conf
    1c7cbff1069612078d63329e5841c7430757a2cd 127.0.0.1:7003@17003 slave f5cc2de688640de572d16d72c2f174de027609a6 0 1516672833000 4 connected
    dd09a06827e9bfeab3876f4464cd467f6d1279f0 127.0.0.1:7002@17002 master - 0 1516672833086 3 connected 10923-16383
    5863f9ee11d3ee3beef466d76f48f221b48aa6b5 127.0.0.1:7004@17004 slave 3ed6531ec985e50e87ab8436d49f4c32ce82bdef 0 1516672832000 5 connected
    3ed6531ec985e50e87ab8436d49f4c32ce82bdef 127.0.0.1:7001@17001 master - 0 1516672832000 2 connected 5461-10922
    9013209020c2fe2322df8c420b1c251fe9c84955 127.0.0.1:7005@17005 myself,slave dd09a06827e9bfeab3876f4464cd467f6d1279f0 0 1516672831000 6 connected
    f5cc2de688640de572d16d72c2f174de027609a6 127.0.0.1:7000@17000 master - 0 1516672832885 1 connected 0-5460
    vars currentEpoch 6 lastVoteEpoch 0
    # 启动的log日志
    [root@cpic-redis-76 7005]# cat start.log
    nohup: 忽略输入
    5627:C 22 Jan 21:02:58.212 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
    5627:C 22 Jan 21:02:58.212 # Redis version=4.0.6, bits=64, commit=00000000, modified=0, pid=5627, just started
    5627:C 22 Jan 21:02:58.212 # Configuration loaded
    5627:M 22 Jan 21:02:58.214 * Increased maximum number of open files to 10032 (it was originally set to 1024).
    5627:M 22 Jan 21:02:58.215 * Node configuration loaded, I'm 9013209020c2fe2322df8c420b1c251fe9c84955
    5627:M 22 Jan 21:02:58.216 * Running mode=cluster, port=7005.
    5627:M 22 Jan 21:02:58.216 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
    5627:M 22 Jan 21:02:58.216 # Server initialized
    5627:M 22 Jan 21:02:58.216 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
    5627:M 22 Jan 21:02:58.216 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
    5627:M 22 Jan 21:02:58.216 * Ready to accept connections
    5627:M 23 Jan 10:00:27.212 # configEpoch set to 6 via CLUSTER SET-CONFIG-EPOCH
    5627:M 23 Jan 10:00:27.286 # IP address for this node updated to 127.0.0.1
    5627:S 23 Jan 10:00:31.238 * Before turning into a slave, using my master parameters to synthesize a cached master: I may be able to synchronize with the new master with just a partial transfer.
    5627:S 23 Jan 10:00:31.239 # Cluster state changed: ok
    5627:S 23 Jan 10:00:31.981 * Connecting to MASTER 127.0.0.1:7002
    5627:S 23 Jan 10:00:31.981 * MASTER <-> SLAVE sync started
    5627:S 23 Jan 10:00:31.981 * Non blocking connect for SYNC fired the event.
    5627:S 23 Jan 10:00:31.981 * Master replied to PING, replication can continue...
    5627:S 23 Jan 10:00:31.982 * Trying a partial resynchronization (request 033127a1144abc3683a83a6b7257c2b56d2bd0b8:1).
    5627:S 23 Jan 10:00:31.983 * Full resync from master: e5e51569d1f49762952e6cc05e1f13ddff68719e:0
    5627:S 23 Jan 10:00:31.983 * Discarding previously cached master state.
    5627:S 23 Jan 10:00:32.084 * MASTER <-> SLAVE sync: receiving 175 bytes from master
    5627:S 23 Jan 10:00:32.084 * MASTER <-> SLAVE sync: Flushing old data
    5627:S 23 Jan 10:00:32.084 * MASTER <-> SLAVE sync: Loading DB in memory
    5627:S 23 Jan 10:00:32.084 * MASTER <-> SLAVE sync: Finished with success
    5627:S 23 Jan 10:00:32.085 * Background append only file rewriting started by pid 10164
    5627:S 23 Jan 10:00:32.108 * AOF rewrite child asks to stop sending diffs.
    10164:C 23 Jan 10:00:32.108 * Parent agreed to stop sending diffs. Finalizing AOF...
    10164:C 23 Jan 10:00:32.108 * Concatenating 0.00 MB of AOF diff received from parent.
    10164:C 23 Jan 10:00:32.108 * SYNC append only file rewrite performed
    10164:C 23 Jan 10:00:32.109 * AOF rewrite: 0 MB of memory used by copy-on-write
    5627:S 23 Jan 10:00:32.181 * Background AOF rewrite terminated with success
    5627:S 23 Jan 10:00:32.181 * Residual parent diff successfully flushed to the rewritten AOF (0.00 MB)
    5627:S 23 Jan 10:00:32.181 * Background AOF rewrite finished successfully

    BUG

    • BUG1
    [root@cpic-redis-76 src]# ./redis-trib.rb create --replicas 1 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
    >>> Creating cluster
    [ERR] Node 127.0.0.1:7005 is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0.
    解决办法: 删掉原有数据dump.rdb/appendonly.aof/nodes.conf文件。
    • BUG2
    ruby安装一些列困难。

    详见Redis Cluster 运维环境安装记录


    Reference

    Redis Cluster 运维环境安装记录

    展开全文
  • Redis集群模式搭建

    2021-01-20 12:16:10
    最近学习springboot集成redis,因此本人打算在虚机上搭建一套redis集群 查阅相关资料,Redis集群中要求必须是奇数节点,所以至少要有三个节点。但是每个节点还需要一个备份节点,因此redis集群需要最低配置6个节点。...
  • Redis集群模式与代理模式

    万次阅读 2020-09-08 17:59:22
    Redis集群模式与代理模式 为了解决redis主从复制或者哨兵模式一个实例存储全量的数据,内存空间可能不足的问题,需要对数据进行分区(Partitioning)。 分区的实现方式 客户端分区:例如原来一个商城的所有缓存都...

    Redis集群模式与代理模式

    为了解决redis主从复制或者哨兵模式一个实例存储全量的数据,内存空间可能不足的问题,需要对数据进行分区(Partitioning)。

    分区的实现方式

    • 客户端分区:例如原来一个商城的所有缓存都存在一个redis,现在按模块进行区分,订单模块放到一个redis,支付模块放到一个redis。
    • 代理分区:客户端将请求发送给代理端,代理根据一致性哈希算法算出key对应在哪个redis实例上,然后将请求发送给对应的redis实例,最后将结果返回给客户端。
    • 查询路由:将请求随机发给一个redis实例,然后这个实例会将请求转发给正确的redis实例,集群模式就是基于这个原理。

    集群模式

    集群模式会自动对数据进行分区,存储到不同的节点上,集群通过分区来提供一定程度的可用性,当某个节点宕机或者不可达的情况下继续处理请求。

    那么集群模式怎么对数据进行分片呢?使用哈希槽。

    Redis集群有16384个哈希槽,每个key通过CRC16校验后对16384取模来决定放置哪个槽。集群的每个节点负责一部分hash槽,举个例子,比如当前集群有3个节点,那么:

    • 节点A包含0到5500号哈希槽。
    • 节点B包含5501到11000号哈希槽。
    • 节点C包含11001到16384号哈希槽。
      如果要添加节点D,可以从节点A, B, C中分出部分槽到D上,如果要移除节点A,可以将A中的槽移到B和C节点上,然后将没有任何槽的A节点从集群中移除即可。由于从一个节点将哈希槽移动到另一个节点并不会停止服务,所以无论添加删除或者改变某个节点的哈希槽的数量都不会造成集群不可用的状态。

    另外集群模式中还使用了主从复制模型,每个master节点都要有1个或者多个slave,也就是上面具有A,B,C三个节点的集群中的每个节点还需要添加一个从节点,这样master节点挂了后,slave就会成为新的master继续提供服务,整个集群便不会因为key找不到对应的槽而不可用了。

    在这里插入图片描述

    快速搭建集群环境,create-cluster位于redis源码目录/root/redis-6.0.6/utils/create-cluster:

    # ./create-cluster start
    Starting 30001
    Starting 30002
    Starting 30003
    Starting 30004
    Starting 30005
    Starting 30006
    # ./create-cluster create
    >>> 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:30005 to 127.0.0.1:30001
    Adding replica 127.0.0.1:30006 to 127.0.0.1:30002
    Adding replica 127.0.0.1:30004 to 127.0.0.1:30003
    >>> Trying to optimize slaves allocation for anti-affinity
    [WARNING] Some slaves are in the same host as their master
    M: 0107a13e16bdf51da044f49fa5613ac63ec40bbe 127.0.0.1:30001
       slots:[0-5460] (5461 slots) master
    M: ef25f43ffd11573c3bd173e81163aa08754b895f 127.0.0.1:30002
       slots:[5461-10922] (5462 slots) master
    M: f0f906cf8a87dd8bafc3a8debcdcdf1af707d8c5 127.0.0.1:30003
       slots:[10923-16383] (5461 slots) master
    S: dac8c0c91741d3068ce057831945cd6d16b8becc 127.0.0.1:30004
       replicates 0107a13e16bdf51da044f49fa5613ac63ec40bbe
    S: 885736999bfbef09f5fcaa1dc7639cc360b19d81 127.0.0.1:30005
       replicates ef25f43ffd11573c3bd173e81163aa08754b895f
    S: 4bd69bbac358d9aa988caf2d9e0fc84395a08b6e 127.0.0.1:30006
       replicates f0f906cf8a87dd8bafc3a8debcdcdf1af707d8c5
    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 127.0.0.1:30001)
    M: 0107a13e16bdf51da044f49fa5613ac63ec40bbe 127.0.0.1:30001
       slots:[0-5460] (5461 slots) master
       1 additional replica(s)
    S: 885736999bfbef09f5fcaa1dc7639cc360b19d81 127.0.0.1:30005
       slots: (0 slots) slave
       replicates ef25f43ffd11573c3bd173e81163aa08754b895f
    S: dac8c0c91741d3068ce057831945cd6d16b8becc 127.0.0.1:30004
       slots: (0 slots) slave
       replicates 0107a13e16bdf51da044f49fa5613ac63ec40bbe
    S: 4bd69bbac358d9aa988caf2d9e0fc84395a08b6e 127.0.0.1:30006
       slots: (0 slots) slave
       replicates f0f906cf8a87dd8bafc3a8debcdcdf1af707d8c5
    M: ef25f43ffd11573c3bd173e81163aa08754b895f 127.0.0.1:30002
       slots:[5461-10922] (5462 slots) master
       1 additional replica(s)
    M: f0f906cf8a87dd8bafc3a8debcdcdf1af707d8c5 127.0.0.1:30003
       slots:[10923-16383] (5461 slots) master
       1 additional replica(s)
    [OK] All nodes agree about slots configuration.
    >>> Check for open slots...
    >>> Check slots coverage...
    [OK] All 16384 slots covered.
    

    就这样,集群模式搭建好了,大体架构如下:

    在这里插入图片描述

    使用redis-cli -c -p 30001对30001节点进行连接,注意要带上-c参数,不然set时会报错(error) MOVED 5798 127.0.0.1:30002

    # redis-cli -c -p 30001
    127.0.0.1:30001> set name morris
    -> Redirected to slot [5798] located at 127.0.0.1:30002
    OK
    

    由于集群模式中对数据进行了分片,对key进行聚合操作以及事务等都很难实现,如果想要某些key落在同一个redis实例中,该怎么实现呢?键哈希标签。

    键哈希标签(Keys hash tags):可以确保带有相同标签的键都会在同一个哈希槽。

    127.0.0.1:30001> set {xxx}name morris
    OK
    127.0.0.1:30001> set {xxx}age 18
    OK
    127.0.0.1:30001> keys *
    1) "{xxx}age"
    2) "{xxx}name"
    

    将快速搭建的集群关闭:

    # ./create-cluster stop   关闭redis
    # ./create-cluster clean  清理数据
    

    下面使用命令来搭建集群,有关集群使用的命令如下:

    # redis-cli --cluster help
    Cluster Manager Commands:
      create         host1:port1 ... hostN:portN
                     --cluster-replicas <arg>
      check          host:port
                     --cluster-search-multiple-owners
      info           host:port
      fix            host:port
                     --cluster-search-multiple-owners
                     --cluster-fix-with-unreachable-masters
      reshard        host:port
                     --cluster-from <arg>
                     --cluster-to <arg>
                     --cluster-slots <arg>
                     --cluster-yes
                     --cluster-timeout <arg>
                     --cluster-pipeline <arg>
                     --cluster-replace
      rebalance      host:port
                     --cluster-weight <node1=w1...nodeN=wN>
                     --cluster-use-empty-masters
                     --cluster-timeout <arg>
                     --cluster-simulate
                     --cluster-pipeline <arg>
                     --cluster-threshold <arg>
                     --cluster-replace
      add-node       new_host:new_port existing_host:existing_port
                     --cluster-slave
                     --cluster-master-id <arg>
      del-node       host:port node_id
      call           host:port command arg arg .. arg
      set-timeout    host:port milliseconds
      import         host:port
                     --cluster-from <arg>
                     --cluster-copy
                     --cluster-replace
      backup         host:port backup_directory
      help           
    
    For check, fix, reshard, del-node, set-timeout you can specify the host and port of any working node in the cluster.
    

    先借助之前的脚本,启动6个redis实例:

    # ./create-cluster start
    

    创建集群:

    # redis-cli --cluster create 127.0.0.1:30001 127.0.0.1:30002 127.0.0.1:30003 127.0.0.1:30004 127.0.0.1:30005 127.0.0.1:30006 --cluster-replicas 1
    

    如果由配置文件启动的redis,需要开启如下配置,否则无法使用集群:

    cluster-enabled yes
    

    代理模式

    目前比较流行的代理框架:

    • predixy:高性能全特征redis代理,支持Redis Sentinel和Redis Cluster。
    • twemproxy:快速、轻量级memcached和redis代理,Twitter推特公司开发。
    • codis:redis集群代理解决方案,豌豆荚公司开发,需要修改redis源码。

    predixy

    github地址:https://github.com/joyieldInc/predixy

    直接下载已经编译好的二进制文件,下载地址:https://github.com/joyieldInc/predixy/releases/download/1.0.5/predixy-1.0.5-bin-amd64-linux.tar.gz

    按照如下架构进行部署:
    在这里插入图片描述
    修改配置文件predixy-1.0.5/conf/predixy.conf

    Bind 127.0.0.1:7617 # 开启
    
    Include sentinel.conf  # 开启
    # Include try.conf # 注释掉
    

    predixy-1.0.5/conf/sentinel.conf中增加如下配置:

    SentinelServerPool {
        Databases 16
        Hash crc16
        HashTag "{}"
        Distribution modula
        MasterReadPriority 60
        StaticSlaveReadPriority 50
        DynamicSlaveReadPriority 50
        RefreshInterval 1
        ServerTimeout 1
        ServerFailureLimit 10
        ServerRetryTimeout 1
        KeepAlive 120
        Sentinels {
            + 127.0.0.1:26379
            + 127.0.0.1:26380
            + 127.0.0.1:26381
        }
        Group ooxx {
        }
        Group xxoo {
        }
    }
    

    找一个目录用来存放redis的数据:

    # mkdir 26379
    # mkdir 26380
    # mkdir 26381
    # mkdir 36379
    # mkdir 36380
    # mkdir 46379
    # mkdir 46380
    

    在26379、26380、26381目录下新建sentinel.conf文件,内容如下:

    port 26379
    sentinel monitor xxoo 127.0.0.1 36379 2
    

    启动三台哨兵:

    # redis-server 26379/sentinel.conf --sentinel
    # redis-server 26380/sentinel.conf --sentinel
    # redis-server 26381/sentinel.conf --sentinel
    

    启动两主两从:

    # redis-server --dir 36379 --port 36379
    # redis-server --dir 36380 --port 36380 --replicaof 127.0.0.1 36379
    # redis-server --dir 46379 --port 46379
    # redis-server --dir 46380 --port 46380 --replicaof 127.0.0.1 46379
    

    启动predixy,并使用:

    # sh bin/predixy conf/predixy.conf
    # redis-cli -p 7617
    127.0.0.1:7617> set name morris
    OK
    127.0.0.1:7617> set age 18
    OK
    

    twemproxy

    github地址:https://github.com/twitter/twemproxy

    安装twemproxy之前先安装automake和libtool:

    # yum install -y automake libtool
    # git clone git@github.com:twitter/twemproxy.git
    # cd twemproxy
    # autoreconf -fvi
    # ./configure
    # make
    

    编译完后会在twemproxy/src目录下生成nutcracker命令,我们把他加入到系统环境中。

    # cp src/nutcracker /usr/bin/
    

    将nutcracker安装成为服务,并配置随开机启动:

    # cp scripts/nutcracker.init /etc/init.d/nutcracker
    # chkconfig --add nutcracker
    

    新建目录/etc/nutcracker,并把配置文件复制到里面:

    # mkdir /etc/nutcracker
    # cp conf/*.yml /etc/nutcracker/
    

    修改配置文件:

    # vi /etc/nutcracker/nutcracker.yml
    alpha:
      listen: 127.0.0.1:22121
      hash: fnv1a_64
      distribution: ketama
      auto_eject_hosts: true
      redis: true
      server_retry_timeout: 2000
      server_failure_limit: 1
      servers:
       - 127.0.0.1:6380:1
       - 127.0.0.1:6381:1
       - 127.0.0.1:6382:1
    

    启动nutcracker并使用:

    # systemctl start nutcracker
    # redis-cli -p 22121
    127.0.0.1:22121> set name morris
    OK
    127.0.0.1:22121> set age 18
    OK
    127.0.0.1:22121> get name
    "morris"
    127.0.0.1:22121> get age
    "18"
    127.0.0.1:22121> key *
    Error: Server closed the connection
    127.0.0.1:22121> watch name
    Error: Server closed the connection
    127.0.0.1:22121> 
    
    展开全文
  • Redis 集群模式&管道模式

    千次阅读 2018-07-08 16:37:42
    参考资料:Redis集群模式:redis集群 应该注意的问题:https://blog.csdn.net/zhang89xiao/article/details/51273970Redis连接池---jedis-2.9.0+commons-pool2-2.4.2:...
  • redis集群模式批量删除key

    千次阅读 2019-10-11 20:21:55
    redis集群模式批量删除key 集群模式下批量删除以"key:"开头的key的命令 redis-cli -c -h 127.0.0.1 -p 6379 keys “key:*” |awk -FS ‘{system("redis-cli -c -h 127.0.0.1 -p 6379 del "$1)}’ ...
  • Redis:Redis集群模式(Cluster)原理

    千次阅读 2019-05-09 00:47:43
    1.前言 由于Redis主从复制模式和Redis哨兵模式采用的都是复制Master节点的数据,实现读写分离。但是这种设计存在一个严重的问题,它没有真正意义上实现数据分片...所有Redis集群模式就是用来解决这个问题。 2. Redi...
  • Springboot2.x集成Redis集群模式

    千次阅读 2019-12-17 22:51:17
    Springboot2.x集成Redis集群模式 说明 Redis集群模式是Redis高可用方案的一种实现方式,通过集群模式可以实现Redis数据多处存储,以及自动的故障转移。如果想了解更多集群模式的相关知识介绍,欢迎往上爬楼。 准备...
  • 解决redis集群模式下,jedis不能批量操作问题..............................................................................
  • Redis 集群模式详解 首先 Redis 有三种集群模式,分别是 主从模式 Sentinel 模式(哨兵模式) Cluster 模式 关于 Redis 的相关信息可以去 Redis 官网 https://redis.io 查看,当前 Redis 最新版本是 6.0.10 安装包...
  • 前面几篇博文介绍了 Redis主从 、 Redis哨兵模式 , 现在我们来了解下更加牛逼的Redis集群模式。 集群的主要目的是解决可扩展性。 在Redis3.0之前(3.0版本开始支持集群功能)主要是通过客户端分片、代理协助分片...
  • redis集群模式是怎么实现的 1.redis的三种集群方式 1.主从模式 2.redis哨兵(Sentinel)模式 3.Cluster模式 2.redis的具体实现方式 1.主从模式 ① 在主从模式中,数据库分为两类:主数据库master和从数据库slave,其中有...
  • Redis集群模式介绍

    千次阅读 2018-10-24 21:17:21
    1.1 Redis 集群方案的演变 大规模数据存储系统都会面临的一个问题就是如何横向拓展。当你的数据集越来越大,一主多从的模式已经无法支撑这么大量的数据存储,于是你首先考虑将多个主从模式结合在一起对外提供服务,...
  • 但是真正应用中通常还要考虑redis和zookeeper集群环境下怎么去安全的实现一个分布式锁,因为在集群环境下存在多节点同步数据操作都可能会影响安全性,那么这篇文章就写一下如何基于redis集群模式使用分布式锁。...
  • Redis集群模式部署

    万次阅读 2018-02-02 19:46:48
    1. Redis部署 以下以Linux(CentOS)系统为例 1.1 下载和编译 $ wget http://download.redis.io/releases/redis-4.0.7.tar.gz $ tar xzf redis-4.0.7.tar.gz $ cd redis-4.0.7 $ make 编译完成后会在src...
  • redis 集群模式的工作原理能说一下么?在集群模式下,redis 的 key 是如何寻址的?分布式寻址都有哪些算法?了解一致性 hash 算法吗?在前几年,redis 如果要搞几个节点,每个节点存储一部分的数据,得借助一些...
  • Redis数据库(四)——Redis集群模式(主从复制、哨兵、Cluster)一、Redis主从复制1、主从复制流程二、哨兵模式1、哨兵模式集群架构2、哨兵模式主要功能3、哨兵监控整个系统节点的过程4、主观下线5、客观下线6、...
  • 面试题redis 集群模式的工作原理能说一下么?在集群模式下,redis 的 key 是如何寻址的?分布式寻址都有哪些算法?了解一致性 hash 算法吗?面试官心理分析在...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 98,541
精华内容 39,416
关键字:

redis集群模式

redis 订阅