简介
Redis 是一个开源内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。
常见的redis部署方式:
通过上表比较可知:
- 需要完整的分片、复制和高可用特性,在集群节点不多且在使用sentinel这种模式会带来性能瓶颈和资源消耗的情况下,可以选择使用Redis集群;
- 如果只需要一部分特性(比如只需要分片,但不需要复制和高可用),那么可以选择Redis Sentinel。
概念注解:
1. 分区:
原来所有的数据都是在一个数据库上的,网络IO及文件IO都集中在一个数据库上的,因此CPU、内存、文件IO、网络IO都可能会成为系统瓶颈。而分区的方案就是把某一个或某几张相关的表的数据放在一个独立的数据库上,这样就可以把CPU、内存、文件IO、网络IO分解到多个机器中,从而提升系统处理能力。
2. 分表:
当数据量大到一定程度的时候,都会导致处理性能的不足,这个时候就没有办法了,只能进行分表处理。也就是把数据库当中数据根据按照分库原则分到多个数据表当中,这样,就可以把大表变成多个小表,不同的分表中数据不重复,从而提高处理效率。
3. 分库:
分表和分区都是基于同一个数据库里的数据分离技巧,对数据库性能有一定提升,对MySQL数据库的吞吐量无质的变化。当业务系统的数据容量接近或超过单台X86服务器的容量、QPS/TPS接近或超过单个MySQL数据库实例的处理极限等,则重点在于扩展MySQL数据库的吞吐量和数据处理量。此时,往往是采用垂直和水平结合的数据拆分方法,把数据服务和数据存储分布到多台MySQL数据库服务器上。 分库只是一个通俗说法,更标准名称是数据分片,采用类似分布式数据库理论指导的方法实现,对应用程序达到数据服务的全透明和数据存储的全透明
4. 分片:
分区有两种模式,一种是主从模式,用于做读写分离;另外一种模式是分片模式,也就是说把一个表中的数据分解到多个表中。一个分区只能是其中的一种模式。
Redis 部署
单实例模式
指单台redis完成所有请求任务,因此不能复用和不具备容错性;同时在单台机器上如果只启用一个redis实例会造成资源浪费 。
Redis集群
Redis 集群是一个由多个节点组成的分布式服务器群,它具有复制、高可用和分片特性。Redis集群不需要sentinel哨兵也能完成节点移除和故障转移的功能。需要将每个节点设置成集群模式,这种集群模式没有中心节点,多个节点之间存在着网络通信的消耗。
多个节点按照分片来处理不同位置的槽,接受到不属于自己的槽操作的命令时会重新发送命令给正确的节点,这中间必然有一定的资源消耗。如同redis主从配置使用sentinel作为代理来处理请求一样。
下面三点是redis官方文档(官方文档Cluster Tutorial)中提到的redis最核心的目标:
性能:
这是Redis赖以生存的看家本领,增加集群功能后当然不能对性能产生太大影响,所以Redis采取了P2P而非Proxy方式、异步复制、客户端重定向等设计,而牺牲了部分的一致性、使用性。
水平扩展:
集群的最重要能力当然是扩展,文档中称可以线性扩展到1000节点。
可用性:
在Cluster推出之前,可用性要靠Sentinel保证。有了集群之后也自动具有了Sentinel的监控和自动Failover能力。
Redis集群概念
一、分布式
Redis集群是一个由多个Redis服务器组成的分布式网络服务器群,集群中的各个服务器被称为节点(node),这些节点会相互连接并进行通信。分布式的Redis集群没有中心节点,所以用户不必担心某个节点会成为整个集群的性能瓶颈。
二、复制
Redis 集群的每个节点都有两种角色可选,一个是主节点(master node),另一个是从节点(slavenode),其中主节点用于储存数据,而从节点则是某个主节点的复制品。当用户需要处理更多读请求的时候,可以添加从节点以扩展系统的读性能。因为Redis集群重用了单机Redis复制特性的代码,所以集群的复制行为和我们之前介绍的单机复制特性的行为是完全一样的。
三、节点故障检测和自动故障转移
Redis 集群的主节点内置了类似Redis Sentinel的节点故障检测和自动故障转移功能,当集群中的某个主节点下线时,集群中的其他在线主节点会注意到这一点,并对已下线的主节点进行故障转移。集群进行故障转移的方法和Redis Sentinel进行故障转移的方法基本一样,不同的是,在集群里面,故障转移是由集群中其他在线的主节点负责进行的,所以集群不必另外使用Redis Sentinel 。
四、分片
集群使用分片来扩展数据库的容量,并将命令请求的负载交给不同的节点来分担。 集群将整个数据库分为 16384 个槽(slot),所有键都属于这 16384 个槽的其中一个,计算键 key属于哪个槽的公式为 slot_number = crc16(key) % 16384 ,其中 crc16 为 16 位的循环冗余校验和函数。集群中的每个主节点都可以处理 0 个至 16384 个槽,当 16384 个槽都有某个节点在负责处理时,集群进入上线状态,并开始处理客户端发送的数据命令请求。 例如,我们有三个主节点7000、7001 和 7002,那么我们可以: 将槽0至5460指派给节点7000负责处理; 将槽 5461至 10922 指派给节点 7001 负责处理; 将槽 10923至 16383指派给节点 7002 负责处理; 这样就可以将16384个槽平均地指派给三个节点负责处理。
五、转向
对于一个被指派了槽的主节点来说,这个主节点只会处理属于指派给自己的槽的命令请求。如果一个节点接收到了与自己处理的槽无关的命令请求,那么节点会向客户端返回一个转向错误(redirection error),告诉客户端,哪个节点负责处理这条命令,之后客户端需要根据错误中包含的地址和端口号重新向正确的节点发送命令请求。
六、Redis集群客户端
因为集群功能比起单机功能要复杂得多,所以不同语言的Redis客户端通常需要为集群添加特别的支持,或者专门开发一个集群客户端。 目前主要的 Redis 集群客户端(或者说,支持集群功能的 Redis 客户端)有以下这些:
- redis-rb-cluster:antirez 使用 Ruby 编写的 Redis 集群客户端,集群客户端的官方实现。
- predis:Redis 的 PHP 客户端,支持集群功能。
- jedis:Redis 的 JAVA 客户端,支持集群功能。
- StackExchange.Redis:Redis 的 C# 客户端,支持集群功能。 -内置的 redis-cli :在启动时给定 -c 参数即可进入集群模式,支持部分集群功能。