分片是将数据划分为多个部分的方法,可以将数据存储到多台服务器里面,这种方法在解决某些问题时可以获得线性提升。
例如将用户id 0-10000 存到redis 1 中,10001-20000 存到 redis2中。但是这样需要维护一张映射范围表,维护操作代价很高。
使用CRC32哈希函数将键转换为一个数字,在对redis实例数量求模就能直到存储的redis实例。
客户端发送查询到一个随机实例,这个实例会保证转发你的查询到正确节点,Redis集群在客户端的帮助下,实现了查询路由的一种混合形式(请求不是直接从redis实例转发到另一个,而是客户端收到重定向以后的节点,再次发送请求到正确的redis实例)
redis作为缓存,增加和删除节点是一件很棘手的事,使用固定的键和实例映射要简单的多。
数据的需求一直在变化,因此我们需要预留足够多的节点供以后扩容使用。
redis只有相当少的内存占用,而且是轻量级(一个空闲实例只用1mb内存) ,一个简单的解决方案就是开启很多实例(32/64),即时只有一台服务器,使用分片来运行多个reids实例在一台服务器上。 当存储出现增长时,需要更更多服务器时,只需要将一半redis实例搬到新的服务器上。
使用redis复制(主动),就可以在很小或者根本不用停机时间内完成移动数据。
redis cluster 提供一种运行redis的方式,数据被自动分片到多个reids节点。
集群不支持处理多个键的命令,因为这需要在redis节点间移动数据,使得redis集群不能提供像单点redis那样的性能,高负载的表现不可知。
每个redis节点需要两个tcp连接打开,正常的tcp端口用来服务客户端,正常端口号+10000的端口用作集群总线端口。
数据端口用于集群总线。集群总线被节点用于错误检测,配置更新,故障转移授权等。客户不能连接集群总线端口。但是要确保在防火墙中打开了这两个端口,否则redis集群节点不能通信。
命令端口和集群总线端口的偏移量总是10000
为了使Redis集群工作正常,对每个节点:
redis集群没有使用一致性hash。而是使用另一种分片方式,每个键概念上被我们称为hash槽(hash slot)的一部分(键属于hash slot)。
我们使用键的CRC16编码对16384取模来计算一个指定键所属的hash槽。
redis集群有16384个哈希槽 ,如有一个三节点的集群:
为了当部分节点失效时,或者无法与大多数节点通信时仍能保持可用。redis集群采用每个节点拥有1-N个副本(一个主服务器,n-1个从服务器) 。
redis集群(AOF也仅能做到秒级一致)不保证强一致性。意味着redis可能会丢掉一些写入请求命令。
发生网络分割时,客户端与至少包含一个主服务器的少数实例被孤立起来了。
举个例子,我们的集群由 A,B,C,A1,B1,C1 共 6 个节点组成,3 个主服务器,3 个从服务器。还有一个客户端,我们称为 Z1。
分割发生以后,有可能分割的一侧是 A,C,A1,B1,C1,分割的另一侧是 B 和 Z1。
Z1 仍然可以写入到可接受写请求的 B。如果分割在很短的时间内恢复,集群会正常的继续。但是,如果分割持续了足够的时间,B1 在分割的大多数这一侧被提升为主服务器,Z1 发送给 B 的写请求会丢失。
这个时间量是 Redis 集群一个非常重要的配置指令,称为节点超时(node timeout)。
节点超时时间过后,主服务器节点被认为失效,可以用其一个副本来取代。同样地,节点超时时间过后,主服务器节点还不能感知其它主服务器节点的大多数,则进入错误状态,并停止接受写请求。
port 7000
cluster-enabled yes //开启集群指令
cluster-config-file nodes.conf //每个实例包含保存这个节点配置的文件的路径
cluster-node-timeout 5000 //节点超时时间(用于网络分割后,对主服务器停止)
appendonly yes //开启AOF持久化(redis中其时默认关闭的)
支持在节点数量改变的情况下,旧结点数据可以恢复到新的hash节点。
redis cluster 3.0自带的集群,特点在于其分布式算法不是一致性hash,而是hash槽概念,以及支持节点设置从节点。
redis实例占用内存不到1mb。在代码层面起几个毫无关联的redis实例,在代码层对key进行hash计算,然后去对应redis实例操作数据。这种方式对hash层代码要求高,需要考虑节点失效后的替代算法,数据震荡后的自动脚本恢复,实例的监控等。
在a,b,c三个节点的集群,在没有复制模型的情况下,如果节点b失败了,那么整个集群就会以为缺少55001-10000这个范围的hash槽而变得不可用。
redis集群无法做出数据库选择,默认在0数据库。
一般的缓存系统,都是按照key去缓存查询,如果不存在对应的value,就去后端如数据库去查询。一些恶意的请求会故意查询不存在的key,请求量很大就会对后端系统造成压力。
当缓存服务器重启或者大量缓存数据在某一时间端失效。这样在失效的时侯就会给后端系统带来很多大压力。造成系统崩溃。
reids集群