redis是单线程,但是一般的作为缓存使用的话,redis足够了,因为它的读写速度太快了。
官方的一个简单测试:
测试完成了50个并发执行100000个请求。
设置和获取的值是一个256字节字符串。
结果:读的速度是110000次/s,写的速度是81000次/s
在这么快的读写速度下,对于一般程序来说足够用了,但是对于访问量特别大的网站来说,还是稍有不足。那么,如何提升redis的性能呢?看标题就知道了,搭建集群。
3.0版本及以后
先来一张redis集群的架构图:
在这个图中,每一个蓝色的圈都代表着一个redis的服务器节点。它们任何两个节点之间都是相互连通的。客户端可以与任何一个节点相连接,然后就可以访问集群中的任何一个节点。对其进行存取和其他操作。
那么redis是怎么做到的呢?首先,在redis的每一个节点上,都有这么两个东西,一个是插槽(slot)可以理解为是一个可以存储两个数值的一个变量这个变量的取值范围是:0-16383。还有一个就是cluster我个人把这个cluster理解为是一个集群管理的插件。当我们的存取的key到达的时候,redis会根据crc16的算法得出一个结果,然后把结果对 16384 求余数,这样每个 key 都会对应一个编号在 0-16383 之间的哈希槽,通过这个值,去找到对应的插槽所对应的节点,然后直接自动跳转到这个对应的节点上进行存取操作。
还有就是因为如果集群的话,是有好多个redis一起工作的,那么,就需要这个集群不是那么容易挂掉,所以呢,理论上就应该给集群中的每个节点至少一个备用的redis服务。这个备用的redis称为从节点(slave)。那么这个集群是如何判断是否有某个节点挂掉了呢?
首先要说的是,每一个节点都存有这个集群所有主节点以及从节点的信息。
它们之间通过互相的ping-pong判断是否节点可以连接上。如果有一半以上的节点去ping一个节点的时候没有回应,集群就认为这个节点宕机了,然后去连接它的备用节点。如果某个节点和所有从节点全部挂掉,我们集群就进入faill状态。还有就是如果有一半以上的主节点宕机,那么我们集群同样进入发力了状态。这就是我们的redis的投票机制,具体原理如下图所示:
(1)投票过程是集群中所有master参与,如果半数以上master节点与master节点通信超时(cluster-node-timeout),认为当前master节点挂掉.
(2)什么时候整个集群不可用(cluster_state:fail)?
a:如果集群任意master挂掉,且当前master没有slave.集群进入fail状态,也可以理解成集群的slot映射[0-16383]不完整时进入fail状态. ps : redis-3.0.0.rc1加入cluster-require-full-coverage参数,默认关闭,打开集群兼容部分失败.
b:如果集群超过半数以上master挂掉,无论是否有slave,集群进入fail状态.
redis cluster是redisr推出的集群版,对应版本是 redis 3.0版本。redis cluster后面一系列源码学习都是针对该版本的。
Redis cluster(集群)是分布式(distributed)的 Redis 实现,具有一定的容错性(fault-tolerant)和线性可扩展性(linear scalability)。
主要功能:
(1) 可线性扩展到16384个节点(cluster使用哈希方式将数据分布到16384个槽,redis节点以槽为单位负责存储数据) ;
(2) 通过cluster 客户端可使数据自动路由到所负责节点 ;
(3) 实现了多个节点间的数据共享(主从节点数据共享;所有节点共享配置数据);
(4) 可支持动态增加或删除节点;
(5)可保证某些节点无法提供服务时不影响整个集群的操作;
(6) 不保证数据的强一致性,但在不出现主从切换的情况下,从用户角度是可以保证数据强一致性
(7)可支持动态调整数据分布,从而实现负载匀衡
(8)可支持人工动态调整主从关系
命令:
1. 支持Redis所有处理单个数据库键的命令;
2. 不支持对多个数据库键的操作,比如MSET、SUNION;
3. 不能使用 SELECT 命令,集群只使用默认的0号数据库;
4. 增加cluster相关命令,用于配置和运维redis cluster。
Slot 槽:Redis Cluster中,一共分成16384个槽
Node节点:每个node(节点)负责分摊这16384个slot中的一部分。官方推荐的方案是将node配置成主从结构,即一个master主节点,挂n个slave从节点。
三个小集群 特点 每一组集群数据是独立的。
每一组数据占据上层Java应用服务(分布式集群)数据1/3
主从服务之间会有 主从的syn同步命令
导致Master内部的线程执行数据保存的工作 rdb aop 方式存储数据 在复制一份给从服务器S
Java应用服务(分布式集群)
加集群节点 ,在企业中非常常见。但是槽点的数量是不会增加:16384
旧槽点怎么迁移到新槽点上
1. 随机分配
2. 均匀分配一定数量
Redis集群以下几点要改:
1. 环路IP
bind
2. 端口
port:1000
3. 后台启动
daemonize yes
4. 进程文件(用于存储进程)
pidfile /var/run/redis.pid
5. 持久化(集群必须开启AOF)
appendonly yes