redis复制:
通过使用 slaveof host port 命令来让一个服务器成为另一个服务器的从服务器。
一个从服务器只能有一个主服务器,并且不支持主主复制。
redis的主从连接过程:
(1)主服务器创建快照文件,即 RDB 文件,发送给从服务器,并在发送期间使用缓冲区记录执行的写命令。
(2)快照文件发送完毕之后,开始像从服务器发送存储在缓冲区的写命令。
(3)从服务器丢弃所有旧数据,载入主服务器发来的快照文件,之后从服务器开始接受主服务器发来的写命令。
(4)主服务器每执行一次写命令,就向从服务器发送相同的写命令。
redis主从复制搭建。
定义为从服务器有两种方式。
第一种:slaveof host port 通过slaveof命令指明主服务器的ip。显然他就是从服务器
第二种:修改配置文件
[root@Centos6 ~]# vim /etc/redis.conf
# slaveof <masterip> <masterport>
主从复制基于配置文件。
[root@Centos6 ~]# mkdir -pv /redis/conf 创建一个存放配置文件的目录
[root@Centos6 ~]# cp -a /etc/redis.conf /redis/conf/redis.conf.2 将配置文件复制一份,改名字为.2
[root@Centos6 ~]# vim /etc/redis.conf 第一个redis服务配置文件默认配置。
[root@Centos6 ~]# vim /redis/conf/redis.conf.2
bind 127.0.0.1 地址默认还是监听本机
port 6380 端口修改为6380
[root@Centos6 ~]# redis-server /redis/conf/redis.conf.2
[root@Centos6 ~]# service redis start
[root@Centos6 ~]# redis-cli -h 127.0.0.1 -p 6380 连入6380redis服务2
127.0.0.1:6380> SLAVEOF 127.0.0.1 6379 指明主redisip和端口,标明自己为从服务器。
OK
127.0.0.1:6380>
127.0.0.1:6380> info replication 查看info里面相关的复制信息。
# Replication
role:slave 指明从服务
master_host:127.0.0.1
master_port:6379
master_link_status:up
master_last_io_seconds_ago:6
master_sync_in_progress:0
slave_repl_offset:8789
slave_priority:100
slave_read_only:1
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
127.0.0.1:6380>
验证主从复制:
[root@Centos6 ~]# redis-cli -h 127.0.0.1 -p 6379 连入主库
127.0.0.1:6379> key *
(error) ERR unknown command 'key'
127.0.0.1:6379> set name yan
OK
127.0.0.1:6379> set ip 123
OK
127.0.0.1:6379>
127.0.0.1:6380> get ip
"123"
127.0.0.1:6380> get name
"yan"
127.0.0.1:6380>
哨兵(sentinel)机制:
(1)主从复制很容易,但是也会面临许多问题,例如:主库突然down,那我们该如何处置。
在MYSQL数据库中,我们有MHA机制(数据库高可用)基于主从复制架构之上,监控主节点,当主机点下线时,选出一个从节点担任主节点。
(2)而redis中提供了哨兵(sentinel)机制。
哨兵概念:
Sentinel(哨兵)可以监听集群中的服务器,并在主服务器进入下线状态时,自动从从服务器中选举处新的主服务器分片
用于管理多个redis服务实现HA
监控
通知
自动故障转移
语言协议,投票协议
哨兵可以有多个,通过协商决定,判断某节点是否下线。
sentinel的配置文件。
[root@Centos6 ~]# vim /etc/redis-sentinel.conf
(1)#sentinel monitor <master-name> <ip> <redis-port> <quorum>
sentinel monitor mymaster 172.0.0.1 6379
(2)sentinel down-after-milliseconds <master-name> <milliseconds>
sentinel down-after-milliseconds mymaster 30000 这表在多长时间内找不到主服务器就表明离线,默认是30s
(3)sentinel parallel-syncs <master-name> <numslaves> 开启这项表示当一个新的从服务器作为主服务器时,允许多少从服务链接。
sentinel parallel-syncs mymaster 1
(4)sentinel failover-timeout <master-name> <milliseconds>:这项表示故障转移时间,默认在180s内没有从服务提升为主,说明故障转移失败。
sentinel failover-timeout mymaster 180000
开启sentinel机制有两种:
redis-sentinel /path/to/file.conf
redis-server /path/to/file.conf --sentinel
(1)服务器自身初始化,运行redis-server中专用于sentinel功能的代码
(2)初始化sentinel状态,根据给定的配置文件,初始化监控的master服务器列表
(3)创建连向master的链接。
关于哨兵机制的专用命令:
sentinel masters :列出所有监控的主服务器所有详细信息。
sentinel slaves <master name>获取指定主服务器的从节点。
sentinel get-master-ddr-by-name <master name>:根据master名字获取地址
sentinel reset :重置操作,清楚服务器所有操作。
sentinel failover <master name>手动故障转移,强制转移。
如何使用哨兵监控主机点。例如下面简单实列:
基于配置文件构建两个从服务器。
[root@Centos6 ~]# mkdir -pv /redis/conf/
[root@Centos6 ~]# mkdir -pv /redis/lib/
[root@Centos6 ~]# cp /etc/redis.conf /redis/conf/redis.conf.2
[root@Centos6 ~]# cp /etc/redis.conf /redis/conf/redis.conf.3
[root@Centos6 ~]# touch /redis/lib/{db1,db2}
[root@Centos6 ~]# vim /redis/conf/redis.conf.2
daemo-size:表示在后台运行
bind 127.0.0.1
port 6380
pidfile /var/run/redis_6380.pid
dir /redis/lib
[root@Centos6 ~]# vim /redis/conf/redis.conf.3
bind 127.0.0.1
port 6381
pidfile /var/run/redis_6381.pid
dir /redis/lib
[root@Centos6 lib]# redis-server /redis/conf/redis.conf.2
[root@Centos6 lib]# redis-server /redis/conf/redis.conf.3
[root@Centos6 ~]# service redis restart
[root@Centos6 ~]# ss -tnl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 127.0.0.1:6379 *:*
LISTEN 0 128 127.0.0.1:6380 *:*
LISTEN 0 128 127.0.0.1:6381 *:*
[root@Centos6 ~]# redis-cli -h 127.0.0.1 -p 6381
127.0.0.1:6381> SLAVEOF 127.0.0.1 6379
OK
127.0.0.1:6381> exit
[root@Centos6 ~]# redis-cli -h 127.0.0.1 -p 6380
127.0.0.1:6381> SLAVEOF 127.0.0.1 6379
OK
127.0.0.1:6381> exit
[root@Centos6 ~]# redis-sentinel /etc/redis-sentinel.conf 启动哨兵机制服务。
[root@Centos6 ~]# ss -tnl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 *:26379 *:*
LISTEN 0 128 :::26379 :::*
LISTEN 0 128 127.0.0.1:6379 *:*
LISTEN 0 128 127.0.0.1:6380 *:*
LISTEN 0 128 127.0.0.1:6381 *:*
[root@Centos6 ~]# redis-cli -h 127.0.0.1 -p 26379
127.0.0.1:26379>
127.0.0.1:26379>
127.0.0.1:26379> sentinel masters 列出所有监控的主服务器所有详细信息。
1) 1) "name"
2) "mymaster"
3) "ip"
4) "127.0.0.1"
5) "port"
6) "6379"
7) "runid"
8) "3ea84e44cb23d5c188f92bb319333a2af5363543"
9) "flags"
10) "master"
127.0.0.1:26379> sentinel slaves mymaster 获取指定主服务器的从节点。
1) 1) "name"
2) "127.0.0.1:6380"
3) "ip"
4) "127.0.0.1"
5) "port"
6) "6380"
7) "runid"
8) "cc4911783d67ec70946f93b41d9cb6ac12df2f94"
9) "flags"
10) "slave"
11) "link-pending-commands"
12) "0"
13) "link-refcount"
14) "1"
15) "last-ping-sent"
16) "0"
17) "last-ok-ping-reply"
18) "26"
19) "last-ping-reply"
20) "26"
21) "down-after-milliseconds"
22) "30"
23) "info-refresh"
24) "4920"
25) "role-reported"
26) "slave"
27) "role-reported-time"
28) "15003"
29) "master-link-down-time"
30) "0"
31) "master-link-status"
32) "ok"
33) "master-host"
34) "127.0.0.1"
35) "master-port"
36) "6379"
37) "slave-priority"
38) "100"
39) "slave-repl-offset"
40) "309"
2) 1) "name"
2) "127.0.0.1:6381"
3) "ip"
4) "127.0.0.1"
5) "port"
6) "6381"
7) "runid"
8) "78c6a1790fa77547df38defcb098c535b7375876"
9) "flags"
10) "slave"
11) "link-pending-commands"
12) "0"
13) "link-refcount"
14) "1"
15) "last-ping-sent"
16) "0"
17) "last-ok-ping-reply"
18) "26"
19) "last-ping-reply"
20) "26"
21) "down-after-milliseconds"
22) "30"
23) "info-refresh"
24) "4921"
25) "role-reported"
26) "slave"
27) "role-reported-time"
28) "225956"
29) "master-link-down-time"
30) "0"
31) "master-link-status"
32) "ok"
33) "master-host"
34) "127.0.0.1"
35) "master-port"
36) "6379"
37) "slave-priority"
38) "100"
39) "slave-repl-offset"
40) "309"
我们可以模拟主节点下线。关闭主节点服务。
我默认修改的sentinel down-after-milliseconds mymaster 30 的为30s,检测30秒找不到主的就说明离线了。
分片:
简单说明一下数据库分片:
分片是将数据划分为多个部分的方法,可以将数据存储到多台机器里面,这种方法在解决某些问题时可以获得线性级别的性能提升。
假设有 4 个 Redis 实例 R0, R1, R2, R3, 还有很多表示用户的键 user:1, user:2, … , 有不同的方式来选择一个指定的键存储在哪个实例中。
最简单的是范围分片,例如用户 id 从 0 ~ 1000 的存储到实例 R0 中,用户 id 从 1001 ~ 2000 的存储到实例 R1中,等等。但是这样需要维护一张映射范围表,维护操作代价高。
还有一种是哈希分片。使用 CRC32 哈希函数将键转换为一个数字,再对实例数量求模就能知道存储的实例。
根据执行分片的位置,可以分为三种分片方式:
客户端分片:客户端使用一致性哈希等算法决定应当分布到哪个节点。
代理分片:将客户端的请求发送到代理上,由代理转发到正确的节点上。
服务器分片:Redis Cluster。