redis主从复制
redis 的复制分为两部分操作 同步(SYNC)和 命令传播(command propagate)
上面介绍了redis复制的两种操作,而redis得主从复制正式基于 同步 和 命令传播 来实现得。下面两张图展示了redis复制的流程:
优点:
1、实现读写分离,提高了可用性,解决了单机故障2、主从复制期间master和slave都是非阻塞方式,仍然可用。
缺点:
1、master宕机期间,需要手动切换主机,同时会有部分数据不能及时同步从服务器,造成数据不一致(需要人工手动介入)
2、slave宕机后,多个slave恢复后,大量的SYNC同步会造成master IO压力倍增(可以手动规避启动时间)
3、在线扩容较复杂。
总结: redis主从复制的优点主要是提高了可用性缺点
Sentinel 哨兵Sentinel 哨兵介绍 Sentinel 哨兵本质上是一个运行在特殊模式下的Redis实例,只是初始化的过程和工作与普通的Redis不同,本质上也是一个单独的进程。 Sentinel 哨兵 是Redis的高可用解决方案:一个或多个Sentinel实例(instance)组成的Sentinel系统(system)可以监视任意多个主服务器,以及这些主服务器属下的所有从服务器,并在主服务器下线时可以自动切换从服务器升级为主服务器。
下图是一个简单的Sentinel系统架构图,一个Sentinel系统监视一个主从集群,其中server1是Redis主服务器,server2/3/4是Redis 从服务器。主从之间利用上面的主从复制来达到主从一致。而Sentinel系统监视整个主从集群。
当Sentinel系统察觉到Server1主服务器下线时,就会终止server2/3/4的复制。
同时Sentinel将server2升级为主服务器,server3/4从新的主服务器进行复制。同时等待server1的再次上线。
Sentinel系统也可以主动降级主服务为从服务器,将从服务器升级为主服务器。
Sentinel 哨兵监控集群过程:
Sentinel 故障转移:
优点:
1、哨兵模式基于主从复制,因此主从复制的优点哨兵都具备2、哨兵具备了主从切换和故障转移,因此集群有了更高的可用性
缺点:
1、Redis较难支持在线扩容,在线扩容比较复杂。
总结: sentinel 哨兵主要用来监控redis主从集群,提高了redis 主从集群的可用性。
redis cluster
Redis Cluster是一种服务器 Sharding 技术,redis 3.0版本开始正式提供。 Sentinel基本已经实现了高可用,但是每台机器都存储相同内容,很浪费内存,所以Redis Cluster实现了分布式存储。每台机器节点上存储不同的内容。
redis 数据分片使用的是hash slot, redis集群有16384个哈希槽,每个Key通过CRC16校验后对16384取模来决定放置哪一个槽。 当存取redis key时候,redis会根据CRC16算法得到一个结果,然后把结果和16384求余,通过这个值去对应得节点获取数据。 这个时候,应用客户端实际上只需要连接其中任意一个节点即可,然后Redis Cluster 中每个节点都保存了其他节点得槽信息。这样当存取key计算完槽之后,通过保存槽信息从配置中获取节点信息,然后再去对应得节点获取数据。
redis-cluster集群引入了主从复制模型,一个主节点对应一个或者多个从节点,当主节点宕机的时候,就会启用从节点。当其它主节点 ping 一个主节点 A 时,如果半数以上的主节点与 A 通信超时,那么认为主节点 A 宕机了。如果主节点 A 和它的从节点 A1 都宕机了,那么该集群就无法再提供服务了
redis哨兵集群不足之处:
资源利用率低,只有一台主库对外提供服务 假如哨兵模式有3个节点,只有其中一个节点对外提供服务,其他两个节点都处于备份状态,这样就会造成资源的浪费,redis将数据都写在内存中,只有主节点工作,那么内存只有主节点上的那点内存,从节点上的内存也就造成了浪费 主库压力比较大,性能有瓶颈 只有主库在工作,所有的写都是主节点完成,这样就会造成主节点的压力比较大,从节点几乎没有压力 哨兵的不足之处就在于集群不是分布式存储,只是单节点去处理,如果集群时分布式存储,那么单点和压力的问题也就解决了
redis cluster适用场景:
当redis遇到单机、内存、并发、流量等瓶颈时,可以采用cluster架构方案达到负载均衡的目的
redis cluster之前的分布式方案:
客户端分区方案,优点分区逻辑可控,缺点是需要自己处理数据路由,高可用和故障转移等。代理方案,优点是简化客户端分布式逻辑和升级维护便利,缺点加重架构部署和性能消耗。
redis cluster的数据分布方式: 所有分布式数据库首先要解决把整个数据库集安装分区规则映射到多个节点的问题,也就是把数据集划分到多个节点上,redis cluster采用哈希分片规则,这样就能保证每个节点存储的数据量大致相同
redis cluster原理:
redis cluster会将数据自动进行分片,然后通过hash算法均匀的存放在集群中的每个节点,cluster架构在每台机器上都有一个或多个主节点和从节点,当一个节点上的master挂掉,会自动将这台机器上的某个slave切换为master
cluster架构的redis集群,可以横向扩容,由于cluster是分布式架构,单个机器的内存是32G,那么10个节点就是320G内存的存储
cluster架构数据分片是由hash来进行分配的,均匀的分散在各个节点
cluster架构槽位概念:每个cluster集群都有16384个槽位,这个槽位就是用来存储hash分配的分片,每一个槽位都需要分配到位,有一个槽位没有分配,整个集群都将无法使用,每一个槽位都有一个序号,它们不是顺序存放的,而是在节点一上比如有10-20序列槽位,节点二上有60-70序列的槽位,这两个节点都是10个槽位,序号不一定要顺序,但是数量一定要差不多,允许2%的误差
cluster集群架构图
通过hash分配数据分片到不同的redis主机
在应用端配置redis cluster地址时需要将所有节点的ip和端口都添加上
使用cluster集群创建的key,在哪个节点上创建的只能是自身节点可以查到数据,其他节点看不到
不太合理的架构图
cluster集群每个机器上都有多个master和slave,如果master节点的数据备份都在自己主机的slave上,那么当服务器1坏掉后,这个机器上的数据就丢失了,数据丢失整个应用就崩溃了
合理的架构图
每个节点slave都存放在别的主机,即使当前主机挂掉,另一台直接还原数据即可
Redis 单节点虽然有通过 RDB 和 AOF 持久化机制能将数据持久化到硬盘上,但数据是存储在一台服务器上的,如果服务器出现硬盘故障等问题,会导致数据不可用,而且读写无法分离,读写都在同一台服务器上,请求量大时会出现 I/O 瓶颈。
为了避免单点故障 和 读写不分离,Redis 提供了复制(replication)功能实现 master 数据库中的数据更新后,会自动将更新的数据同步到其他 slave 数据库上。
Redis 主从结构特点:一个 master 可以有多个 slave 节点;slave 节点可以有 slave 节点,从节点是级联结构。
普通的主从模式,当主数据库崩溃时,需要手动切换从数据库成为主数据库:
SLAVE NO ONE
命令将从数据库提升成主数据继续服务。SLAVEOF
命令将其设置成新的主数据库的从数据库,即可同步数据。第一种主从同步/复制的模式,当主服务器宕机后,需要手动把一台从服务器切换为主服务器,这就需要人工干预,费事费力,还会造成一段时间内服务不可用,这时候就需要哨兵模式登场了。哨兵模式是从 Redis 的 2.6 版本开始提供的,但是当时这个版本的模式是不稳定的,直到 Redis 的 2.8 版本以后,这个哨兵模式才稳定下来。
哨兵模式核心还是主从复制,只不过在相对于主从模式在主节点宕机导致不可写的情况下,多了一个竞选机制:从所有的从节点竞选出新的主节点。竞选机制的实现,是依赖于在系统中启动一个 sentinel 进程。
哨兵本身也有单点故障的问题,所以在一个一主多从的 Redis 系统中,可以使用多个哨兵进行监控,哨兵不仅会监控主数据库和从数据库,哨兵之间也会相互监控。每一个哨兵都是一个独立的进程,作为进程,它会独立运行。
哨兵在启动进程时,会读取配置文件的内容,通过如下的配置找出需要监控的主数据库:
sentinel monitor master-name ip port quorum
# master-name 是主数据库的名字
# ip 和 port 是当前主数据库地址和端口号
# quorum 表示在执行故障切换操作前,需要多少哨兵节点同意。
这里之所以只需要连接主节点,是因为通过主节点的 info 命令,获取从节点信息,从而和从节点也建立连接,同时也能通过主节点的 info 信息知道新增从节点的信息。
一个哨兵节点可以监控多个主节点,但是并不提倡这么做,因为当哨兵节点崩溃时,同时有多个集群切换会发生故障。哨兵启动后,会与主数据库建立两条连接。
_sentinel_:hello
频道以获取同样监控该数据库的哨兵节点信息info
命令,获取主数据库本身的信息。跟主数据库建立连接后会定时执行以下三个操作:
_sentinel_:hello
频道发送自己的信息。作用是将自己的监控数据和哨兵分享。每个哨兵会订阅数据库的_sentinel:hello
频道,当其他哨兵收到消息后,会判断该哨兵是不是新的哨兵,如果是则将其加入哨兵列表,并建立连接。哨兵节点发送 ping 命令时,当超过一定时间(down-after-millisecond)后,如果节点未回复,则哨兵认为主观下线。主观下线表示当前哨兵认为该节点已经下线,如果该节点为主数据库,哨兵会进一步判断是够需要对其进行故障切换,这时候就要发送命令(SENTINEL is-master-down-by-addr)询问其他哨兵节点是否认为该主节点是主观下线,当达到指定数量(quorum)时,哨兵就会认为是客观下线。
当主节点客观下线时就需要进行主从切换,主从切换的步骤为:
选出一个从数据库后,哨兵发送 slave no one
命令升级为主数据库,并发送slaveof
命令将其他从节点的主数据库设置为新的主数据库。
优点:哨兵模式是基于主从模式的,解决可主从模式中master故障不可以自动切换故障的问题。
缺点:
主从模式或哨兵模式每个节点存储的数据都是全量的数据,数据量过大时,就需要对存储的数据进行分片后存储到多个 Redis 实例上。此时就要用到 Redis Sharding 技术。
客户端分片是把分片的逻辑放在 Redis 客户端实现,(比如:jedis 已支持 Redis Sharding 功能,即 ShardedJedis),通过 Redis 客户端预先定义好的路由规则(使用一致性哈希),把对 Key 的访问转发到不同的 Redis 实例中,查询数据时把返回结果汇集。
一致性哈希算法:
是分布式系统中常用的算法。比如,一个分布式的存储系统,要将数据存储到具体的节点上,如果采用普通的 hash 方法,将数据映射到具体的节点上,如 mod(key,d),key 是数据的 key,d 是机器节点数,如果有一个机器加入或退出这个集群,则所有的数据映射都无效了。
一致性哈希算法解决了普通余数 Hash 算法伸缩性差的问题,可以保证在上线、下线服务器的情况下尽量有多的请求命中原来路由到的服务器。
一致性哈希算法实现方式:一致性 hash 算法,比如 MURMUR_HASH 散列算法、ketamahash 算法。比如 Jedis 的 Redis Sharding 实现,采用一致性哈希算法(consistent hashing),将 key 和节点 name 同时 hashing,然后进行映射匹配,采用的算法是 MURMUR_HASH。
采用一致性哈希而不是采用简单类似哈希求模映射的主要原因是当增加或减少节点时,不会产生由于重新匹配造成的 rehashing。一致性哈希只影响相邻节点 key 分配,影响量小。
客户端分片的优缺点:
优点:客户端 sharding 技术使用 hash 一致性算法分片的好处是所有的逻辑都是可控的,不依赖于第三方分布式中间件。服务端的 Redis 实例彼此独立,相互无关联,每个 Redis 实例像单服务器一样运行,非常容易线性扩展,系统的灵活性很强。开发人员清楚怎么实现分片、路由的规则,不用担心踩坑。
缺点:
客户端分片有一个最大的问题就是,服务端 Redis 实例群拓扑结构有变化时,每个客户端都需要更新调整。如果能把客户端分片模块单独拎出来,形成一个单独的模块(中间件),作为客户端 和 服务端连接的桥梁就能解决这个问题了,此时代理分片就出现了。
Redis 代理分片用得最多的就是 Twemproxy,由 Twitter 开源的 Redis 代理,其基本原理是:通过中间件的形式,Redis 客户端把请求发送到 Twemproxy,Twemproxy 根据路由规则发送到正确的 Redis 实例,最后 Twemproxy 把结果汇集返回给客户端。
Twemproxy 通过引入一个代理层,将多个 Redis 实例进行统一管理,使 Redis 客户端只需要在 Twemproxy 上进行操作,而不需要关心后面有多少个 Redis 实例,从而实现了 Redis 集群。
Redis 的哨兵模式虽然已经可以实现高可用,读写分离 ,但是存在几个方面的不足:
Redis 在 3.0 上加入了 Cluster 集群模式,实现了 Redis 的分布式存储,也就是说每台 Redis 节点上存储不同的数据。cluster 模式为了解决单机 Redis 容量有限的问题,将数据按一定的规则分配到多台机器,内存/QPS 不受限于单机,可受益于分布式集群高扩展性。Redis Cluster 是一种服务器 Sharding 技术(分片和路由都是在服务端实现),采用多主多从,每一个分区都是由一个 Redis 主机和多个从机组成,片区和片区之间是相互平行的。Redis Cluster 集群采用了 P2P 的模式,完全去中心化。
官方推荐,集群部署至少要 3 台以上的 master 节点,最好使用 3 主 3 从六个节点的模式。Redis Cluster 集群具有如下几个特点:
Redis cluster 主要是针对海量数据 + 高并发 + 高可用的场景,海量数据,如果你的数据量很大,那么建议就用 Redis cluster,数据量不是很大时,使用 sentinel 就够了。Redis cluster 的性能和高可用性均优于哨兵模式。
Redis Cluster 采用虚拟哈希槽分区而非一致性 hash 算法,预先分配一些卡槽,所有的键根据哈希函数映射到这些槽内,每一个分区内的 master 节点负责维护一部分槽以及槽所映射的键值数据。
简单说一下redis-cluster里面槽?
槽是存放数据,存放是要通过key计算槽位,选择对应的服务器来存储,获取也是同样的算法.
默认16384个槽位要均匀分布到主节点上面
为了槽里面数据安全要对主节点进行1-N从节点备份
简单说一下redis-cluster里面选举投票机制
所有主节点都参与投票,默认半数以上挂点,启动容错机制,提升从节点为主节点.