1.Redis安装(redis-5.0.5)
第一步,安装C语言需要的GCC环境
yum install -y gcc-c++
yum install -y wget
第二步,下载并解压缩redis源码安装包
wget http://download.redis.io/releases/redis-5.0.5.tar.gz
tar -zxf redis-5.0.5.tar.gz
也可以从官网下载安装包,中文官网地址:http://www.redis.cn/
第三步:编译 Redis 源码,进入 redis-5.0.5 目录,执行编译命令
cd redis-5.0.5/src
make
第四步:安装 Redis ,需要通过 PREFIX 指定安装路径
mkdir /usr/redis -p
make install PREFIX=/usr/redis
Redis启动
启动命令:/redis-server,在安装目录的bin目录下,这种方式是前台启动,如果需要后台启动,需要拷贝redis.conf到bin目录中,修改redis.conf配置文件,并在启动时指定使用redis.conf配置文件
cp redis.conf /usr/redis/bin/
vim redis.conf
将`daemonize`由`no`改为`yes`,后台启动
daemonize yes
默认绑定的是回环地址,默认不能被其他机器访问
bind 127.0.0.1
是否开启保护模式,由yes该为no
protected-mode no
启动服务,使用指定配置文件
/redis-server redis.conf
2. 主从复制
主从复制的好处:
一主多从,读写分离,主负责写,从负责读,可以提升redis性能和吞吐量
主从复制存在的问题:从机是主机的备份,主机宕机从机可读不可写,默认情况下从机不能自动切换为主机(可以使用哨兵模式实现主备切换),以及主从数据一致性问题。
以一主一从为例,在一台虚拟机上安装两个redis,端口为6379,和6380,6379端口作为主机,主机不用做任何配置,在从机6380的redis.conf文件中增加:
slaveof <masterip> <masterport>
表示当前【从服务器】对应的【主服务器】的IP,端口是6379。
replicaof 127.0.0.1 6379
分别启动两个redis
使用redis-cli连接6379,并执行set命令
./redis-cli
连接6380,并执行命令,可以看到从机中可以读取name=张飞,但是不可以写入name
./redis-cli -p 6380
主从同步原理:
redis同步功能的实现分为数据同步和命令传播
首先,从机与主机之间建立socket连接,从机相当于主机的一个client,建立连接后:
1.从机向主机发送PSYNC请求同步数据
2.主机创建快照,并将快照生成期间接受到的写命令放入命令缓冲区
3.主机将快照文件发送给从机
4.从机清空之前数据,并执行快照文件
5.快照文件同步完成后,主机向从机发送快照同步期间的写命令
6.数据同步完成后数据同步使用命令传播方式,机主机将接受的写命令同步传播给从机
3. 哨兵模式
sentinel哨兵模式,是redis高可用的解决方案,由一个或多个sentinel实例组成的sentinel集群来监控一个或多主从服务器,当主机下线后,在该主机的从服务中选出一个从机作为主机,继续对外提供服务,来保证redis的高可用
sentinel搭建:
还是采用在一台虚拟机搭建伪集群的方式
端口 | 角色 |
---|---|
6379 | master |
6380 | slaver1 |
6381 | slaver2 |
26379 | sentinel1 |
26380 | sentinel2 |
26381 | sentinel3 |
1.创建目录 |
[root@localhost bin]# mkdir -p /var/redis-sentinel
[root@localhost bin]# cd /var/redis-sentinel/
[root@localhost redis-sentinel]# mkdir master slaver1 slaver2 sentinel1 sentinel2 sentinel3
[root@localhost redis-sentinel]# ls
2.安装redis主机6379,并拷贝redis.conf完成主机配置
make install PREFIX=/var/redis-sentinel/master/
cp redis.conf /var/redis-sentinel/master/bin/
vim redis.conf
将`daemonize`由`no`改为`yes`
daemonize yes
默认绑定的是回环地址,默认不能被其他机器访问
#bind 127.0.0.1
#是否开启保护模式,由yes该为no
protected-mode no
3.安装从机6380和6381
#将master拷贝
[root@localhost master]# cp -r /var/redis-sentinel/master/* /var/redis-sentinel/slaver1
[root@localhost master]# cp -r /var/redis-sentinel/master/* /var/redis-sentinel/slaver2
#安装redis-slaver1
#修改配置文件
vim /var/redis-sentinel/slaver1/bin/redis.conf
port 6380
replicaof 127.0.0.1 6379
#安装redis-slaver2
#修改配置文件
vim /var/redis-sentinel/slaver2/bin/redis.conf
port 6381
replicaof 127.0.0.1 6379
4.安装sentinel
#拷贝到sentinel
[root@localhost master]# cp -r /var/redis-sentinel/master/* /var/redis-sentinel/sentinel1/
[root@localhost master]# cp -r /var/redis-sentinel/master/* /var/redis-sentinel/sentinel2/
[root@localhost master]# cp -r /var/redis-sentinel/master/* /var/redis-sentinel/sentinel3/
#拷贝配置文件,注意这里拷贝的是sentinel.conf,不是redis.conf
[root@localhost master]# cp /usr/redis-install/redis-5.0.5/sentinel.conf /var/redis-sentinel/sentinel1/bin
[root@localhost master]# cp /usr/redis-install/redis-5.0.5/sentinel.conf /var/redis-sentinel/sentinel2/bin
[root@localhost master]# cp /usr/redis-install/redis-5.0.5/sentinel.conf /var/redis-sentinel/sentinel3/bin
配置sentinel1 26379
# 哨兵sentinel实例运行的端口 默认26379
port 26379
# 将`daemonize`由`no`改为`yes`
daemonize yes
# 哨兵sentinel监控的redis主节点的 ip port
# master-name 可以自己命名的主节点名字 只能由字母A-z、数字0-9 、这三个字符".-_"组成。
# quorum 当这些quorum个数sentinel哨兵认为master主节点失联 那么这时 客观上认为主节点失联了
# sentinel monitor <master-name> <ip> <redis-port> <quorum>
sentinel monitor mymaster 127.0.0.1 6379 2
# 当在Redis实例中开启了requirepass foobared 授权密码 这样所有连接Redis实例的客户端都要提
供密码
# 设置哨兵sentinel 连接主从的密码 注意必须为主从设置一样的验证密码
# sentinel auth-pass <master-name> <password>
sentinel auth-pass mymaster MySUPER--secret-0123passw0rd
# 指定多少毫秒之后 主节点没有应答哨兵sentinel 此时 哨兵主观上认为主节点下线 默认30秒,改成3
秒
# sentinel down-after-milliseconds <master-name> <milliseconds>
sentinel down-after-milliseconds mymaster 3000
# 这个配置项指定了在发生failover主备切换时最多可以有多少个slave同时对新的master进行 同步,
这个数字越小,完成failover所需的时间就越长,
但是如果这个数字越大,就意味着越 多的slave因为replication而不可用。
可以通过将这个值设为 1 来保证每次只有一个slave 处于不能处理命令请求的状态。
# sentinel parallel-syncs <master-name> <numslaves>
sentinel parallel-syncs mymaster 1
# 故障转移的超时时间 failover-timeout 可以用在以下这些方面:
#1. 同一个sentinel对同一个master两次failover之间的间隔时间。
#2. 当一个slave从一个错误的master那里同步数据开始计算时间。直到slave被纠正为向正确的
master那里同步数据时。
#3.当想要取消一个正在进行的failover所需要的时间。
#4.当进行failover时,配置所有slaves指向新的master所需的最大时间。不过,即使过了这个超时,
slaves依然会被正确配置为指向master,但是就不按parallel-syncs所配置的规则来了
# 默认三分钟
# sentinel failover-timeout <master-name> <milliseconds>
sentinel failover-timeout mymaster 180000
另外两台sentinel也按此配置,修改端口为26380,26381
配置好后依次启动master,slaver1,slaver2,sentinel1,sentinel2,sentinel3
[root@localhost bin]# ./redis-server redis.conf
[root@localhost bin]# cd ../../slaver1/bin/
[root@localhost bin]# ./redis-server redis.conf
[root@localhost bin]# cd ../../slaver2/bin/
[root@localhost bin]# ./redis-server redis.conf
[root@localhost bin]# cd ../../sentinel1/bin/
[root@localhost bin]# ./redis-sentinel sentinel.conf
[root@localhost bin]# cd ../../sentinel2/bin/
[root@localhost bin]# ./redis-sentinel sentinel.conf
[root@localhost bin]# cd ../../sentinel3/bin/
[root@localhost bin]# ./redis-sentinel sentinel.conf
使用redis-cli工具连接3台主机进行操作,主机可写,2台从机只读
现在kill掉6379进程模拟主机下线
使用cli工具连接6381,发现6381变成可写,6380还是只读,所以主机6379下线后,sentinel将6381切换成主机,此时若再次启动6379,它只能作为从机只读,不会再升为主机
sentinel原理:
sentinel是特殊的redis服务器,不会持久化,每个sentinel启动后会向主机创建2个连接
命令连接:用于像主机发送命令并接受响应
订阅连接:用户订阅主机的sentinel-hello频道
1.获取主机信息
sentinel每隔10s会向主机发送一次info命令,来了获取主机以及其下属从机,当发现有新的从机出现时,sentinel会对新的从机建立命令连接和订阅连接。
127.0.0.1:6379> info
# Server
redis_version:5.0.5
os:Linux 3.10.0-229.el7.x86_64 x86_64
run_id:a4e06ab61b4116660aa37b85079ed482b0b695b1
# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=6380,state=online,offset=1571684,lag=1
slave1:ip=127.0.0.1,port=6381,state=online,offset=1571551,lag=1
master_replid:366322125dd7dc9bc95ed3467cfec841c112e207
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:1571684
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:523109
repl_backlog_histlen:1048576
sentinel也会每隔10s想从机发送info命令。
2.sentinel默认每2s会向主机和从机所订阅的sentinel:hello频道发送消息,消息中携带自身信息和主机信息
PUBLISH _sentinel_:hello "< s_ip > < s_port >< s_runid >< s_epoch > < m_name > <
m_ip >< m_port ><m_epoch>"
3.sentinel之间只创建命令连接,不创建订阅连接,因为sentinel会通过对主从服务的订阅中感知新的sentinel加入
4.故障转移:
sentinel每秒像与它建立连接的服务器(主机,从机,其他sentinel)发送ping命令,如果没有收到有效回复,则会认为该服务处于主观下线状态,然后sentinel会向其他sentinel服务器发送查询命令,询问该主机是否下线,如果收到配置中quorum数量的sentinel实例都反馈该主机下线,那么该主机会被判定为客观下线
当一个主机被判断为客观下线后,sentinel会通过raft选举法选举出一个leader sentinel去执行故障转移:
1. 它会将失效 Master 的其中一个 Slave 升级为新的 Master , 并让失效 Master 的其他 Slave 改为复
制新的 Master ;
2. 当客户端试图连接失效的 Master 时,集群也会向客户端返回新 Master 的地址,使得集群可以使
用现在的 Master 替换失效 Master 。
3. Master 和 Slave 服务器切换后, Master 的 redis.conf 、 Slave 的 redis.conf 和
sentinel.conf 的配置文件的内容都会发生相应的改变,即, Master 主服务器的 redis.conf
配置文件中会多一行 replicaof 的配置, sentinel.conf 的监控目标会随之调换
哨兵leader根据以下规则从客观下线的主服务器的从服务器中选择出新的主服务器:
1. 过滤掉主观下线的节点
2. 选择slave-priority最高的节点,如果由则返回没有就继续选择
3. 选择出复制偏移量最大的系节点,因为复制偏移量越大则数据复制的越完整,如果由就返回了,没
有就继续
4. 选择run_id最小的节点,因为run_id越小说明重启次数越少
4. 集群分区
分区的意义:性能的提升和存储能力的横向扩展
一般有client端分区和proxy端分区,这里使用官方cluster分区,redis5.0之后就可以使用cli进行集群的创建和管理,方案采用去中心化的方式,包括:sharding(分区)、replication(复制)、failover(故障转移)。称为RedisCluster。
集群搭建,搭建三主三从集群,master1,master2,master3,以及各自的从机slaver1,slaver2,slaver3
端口 | 角色 |
---|---|
7001 | master1 |
7002 | master2 |
7003 | master3 |
7004 | slaver1 |
7005 | slaver2 |
7006 | slaver3 |
一,首先创建目录
[root@localhost var]# mkdir -p /var/redis-cluster/master1
[root@localhost var]# mkdir -p /var/redis-cluster/master2
[root@localhost var]# mkdir -p /var/redis-cluster/master3
[root@localhost var]# mkdir -p /var/redis-cluster/slaver1
[root@localhost var]# mkdir -p /var/redis-cluster/slaver2
[root@localhost var]# mkdir -p /var/redis-cluster/slaver3
二,按照上面安装步骤创建7001实例
make install PREFIX=/var/redis-cluster/master1/
cp redis.conf /var/redis-cluster/master1/bin/
编辑redis.conf文件,把端口号改成7001,并开启集群设置
port 7001
cluster-enable yes
三,将master1拷贝到其余5个目录中,并修改端口为7002-7006
[root@localhost bin]# cp -r /var/redis-cluster/master1/* /var/redis-cluster/master2/
[root@localhost bin]# cp -r /var/redis-cluster/master1/* /var/redis-cluster/master3/
[root@localhost bin]# cp -r /var/redis-cluster/master1/* /var/redis-cluster/slaver1/
[root@localhost bin]# cp -r /var/redis-cluster/master1/* /var/redis-cluster/slaver2/
[root@localhost bin]# cp -r /var/redis-cluster/master1/* /var/redis-cluster/slaver3/
四,分别启动各个redis实例
为了方便在/var/redis-cluster目录下创建一个启动脚本start.sh
cd master1/bin
./redis-server redis.conf
cd ..
cd ..
cd master2/bin
./redis-server redis.conf
cd ..
cd ..
cd master3/bin
./redis-server redis.conf
cd ..
cd ..
cd slaver1/bin
./redis-server redis.conf
cd ..
cd ..
cd slaver2/bin
./redis-server redis.conf
cd ..
cd ..
cd slaver3/bin
./redis-server redis.conf
cd ..
cd ..
#权限
chmod u+x start.sh
#启动
./start.sh
五,创建集群
注意:集群创建要保证各个实例中都是空的,没有数据。
#1主机1从机 前三个为主 后三个为各自的从机
./redis-cli --cluster create 192.168.8.186:7001 192.168.8.186:7002 192.168.8.186:7003 192.168.8.186:7004 192.168.8.186:7005 192.168.8.186:7006 --cluster-replicas 1
控制台会打印出主从的信息,slot部分情况等,输入yes继续
看到这个信息表明集群创建成功,16384个slot全部分配完毕