跳转至

Redis主从

1. 介绍

       REmote DIctionary Server(Redis) 是一个由Salvatore Sanfilippo写的key-value存储系统。

       Redis是一个开源的使用ANSI C语言编写、遵守BSD协议、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。

       它通常被称为数据结构服务器,因为值(value)可以是 字符串(String), 哈希(Hash), 列表(list), 集合(sets) 和 有序集合(sorted sets)等类型。

2. 部署

2.1 Redis 主从

Redis支持主从同步。数据可以从主服务器向任意数量的从服务器上同步,同步使用的是发布/订阅机制。

2.2 配置

Mater Slave的模式,从Slave向Master发起SYNC命令。

Master 多Slave,可以分层,Slave下可以再接Slave,可扩展成树状结构。

配置非常简单,只需在slave的设定文件中指定master的ip和port

root@leco:/usr/local/redis# mkdir redis1/{etc,var,log} -p
root@leco:/usr/local/redis# tree .
.
└── redis1
    ├── etc
    ├── log
    └── var

4 directories, 0 files
root@leco:/usr/local/redis# cp -aR redis1/ redis2
root@leco:/usr/local/redis# vim redis1/etc/redis.conf
root@leco:/usr/local/redis# cat redis1/etc/redis.conf

2.3 master配置

root@leco:/usr/local/redis# cat redis1/etc/redis.conf
daemonize yes
pidfile "/usr/local/redis/redis1/log/redis.pid"
port 8379
timeout 300
loglevel debug
logfile "/usr/local/redis/redis1/log/redis.log"
databases 16
save 900 1
save 300 10
save 60 10000
rdbcompression yes
dbfilename "dump.rdb"
dir "/usr/local/redis/redis1/var"
appendonly no
appendfsync always
bind 0.0.0.0

2.4 slave配置

root@leco:/usr/local/redis# cat redis2/etc/redis.conf
daemonize yes
pidfile "/usr/local/redis/redis1/log/redis.pid"
port 8380
timeout 300
loglevel debug
logfile "/usr/local/redis/redis1/log/redis.log"
databases 16
save 900 1
save 300 10
save 60 10000
rdbcompression yes
dbfilename "dump.rdb"
dir "/usr/local/redis/redis1/var"
appendonly no
appendfsync always
bind 0.0.0.0
slaveof 172.17.0.2 8379 

手动配置主

在从上配置要同步的主
127.0.0.1:8380> slaveof localhost 6380
只读模式
slave-read-only yes                设置slave为只读模式

2.5 启动

root@leco:/usr/local/redis# redis-server /usr/local/redis/redis1/etc/redis.conf
root@leco:/usr/local/redis# redis-server /usr/local/redis/redis2/etc/redis.conf
root@leco:/usr/local/redis# ps axf|egrep '8379|8380' | grep -v grep
 5796 ?        Ssl    0:00 redis-server 0.0.0.0:8379
 6663 ?        Ssl    0:00 redis-server 0.0.0.0:8380

2.6 检查主从

root@leco:/usr/local/redis# redis-cli -p 8379
127.0.0.1:8379> keys *
(empty list or set)
127.0.0.1:8379> set name 'cmz'
OK
127.0.0.1:8379> quit
root@leco:/usr/local/redis# redis-cli -p 8380
127.0.0.1:8380> keys*
(error) ERR unknown command 'keys*'
127.0.0.1:8380> keys *
1) "name"
127.0.0.1:8380> get name
"cmz"

root@leco:/usr/local/redis# redis-cli -p 8379
127.0.0.1:8379> info
# Server
redis_version:3.0.6
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:28b6715d3583bf8e
redis_mode:standalone
os:Linux 4.15.0-45-generic x86_64
arch_bits:64
multiplexing_api:epoll
gcc_version:5.4.0
process_id:5796
run_id:32ac4a621301f8c8398439b074ff3cf7b7e0d0f9
tcp_port:8379
uptime_in_seconds:557
uptime_in_days:0
hz:10
lru_clock:7649260
config_file:/usr/local/redis/redis1/etc/redis.conf

# Clients
connected_clients:1
client_longest_output_list:0
client_biggest_input_buf:0
blocked_clients:0

# Memory
used_memory:1884808
used_memory_human:1.80M
used_memory_rss:3731456
used_memory_peak:1884808
used_memory_peak_human:1.80M
used_memory_lua:36864
mem_fragmentation_ratio:1.98
mem_allocator:jemalloc-3.6.0

# Persistence
loading:0
rdb_changes_since_last_save:1
rdb_bgsave_in_progress:0
rdb_last_save_time:1551152980
rdb_last_bgsave_status:ok
rdb_last_bgsave_time_sec:0
rdb_current_bgsave_time_sec:-1
aof_enabled:0
aof_rewrite_in_progress:0
aof_rewrite_scheduled:0
aof_last_rewrite_time_sec:-1
aof_current_rewrite_time_sec:-1
aof_last_bgrewrite_status:ok
aof_last_write_status:ok

# Stats
total_connections_received:4
total_commands_processed:158
instantaneous_ops_per_sec:0
total_net_input_bytes:5511
total_net_output_bytes:318
instantaneous_input_kbps:0.02
instantaneous_output_kbps:0.00
rejected_connections:0
sync_full:1
sync_partial_ok:0
sync_partial_err:0
expired_keys:0
evicted_keys:0
keyspace_hits:0
keyspace_misses:0
pubsub_channels:0
pubsub_patterns:0
latest_fork_usec:154
migrate_cached_sockets:0

# Replication
role:master
connected_slaves:1
slave0:ip=127.0.0.1,port=8380,state=online,offset=266,lag=1
master_repl_offset:266
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:265

# CPU
used_cpu_sys:0.40
used_cpu_user:0.11
used_cpu_sys_children:0.00
used_cpu_user_children:0.00

# Cluster
cluster_enabled:0

# Keyspace
db0:keys=1,expires=0,avg_ttl=0

2.7 查看slave

       在主上执行 info repliaction

127.0.0.1:8379>  INFO replication
# Replication
role:master
connected_slaves:1
slave0:ip=127.0.0.1,port=8380,state=online,offset=308,lag=0
master_repl_offset:308
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:307

2.8 手动切换身份

       Master不可用的情况下,停止Master,将Slave的设定无效化后,Slave升级为Master

root@leco:/usr/local/redis# redis-cli -p 8380
127.0.0.1:8380> info
# Server
redis_version:3.0.6
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:28b6715d3583bf8e
redis_mode:standalone
os:Linux 4.15.0-45-generic x86_64
arch_bits:64
multiplexing_api:epoll
gcc_version:5.4.0
process_id:7666
run_id:5e077def1cd19dee9f3a379cc889b363f20b8305
tcp_port:8380
uptime_in_seconds:64
uptime_in_days:0
hz:10
lru_clock:7649736
config_file:/usr/local/redis/redis2/etc/redis.conf

# Clients
connected_clients:2
client_longest_output_list:0
client_biggest_input_buf:0
blocked_clients:0

# Memory
used_memory:837232
used_memory_human:817.61K
used_memory_rss:3686400
used_memory_peak:837232
used_memory_peak_human:817.61K
used_memory_lua:36864
mem_fragmentation_ratio:4.40
mem_allocator:jemalloc-3.6.0

# Persistence
loading:0
rdb_changes_since_last_save:0
rdb_bgsave_in_progress:0
rdb_last_save_time:1551153544
rdb_last_bgsave_status:ok
rdb_last_bgsave_time_sec:-1
rdb_current_bgsave_time_sec:-1
aof_enabled:0
aof_rewrite_in_progress:0
aof_rewrite_scheduled:0
aof_last_rewrite_time_sec:-1
aof_current_rewrite_time_sec:-1
aof_last_bgrewrite_status:ok
aof_last_write_status:ok

# Stats
total_connections_received:3
total_commands_processed:4
instantaneous_ops_per_sec:0
total_net_input_bytes:130
total_net_output_bytes:1540
instantaneous_input_kbps:0.00
instantaneous_output_kbps:0.04
rejected_connections:0
sync_full:0
sync_partial_ok:0
sync_partial_err:0
expired_keys:0
evicted_keys:0
keyspace_hits:0
keyspace_misses:0
pubsub_channels:0
pubsub_patterns:0
latest_fork_usec:0
migrate_cached_sockets:0

# Replication
role:slave                # 是从
master_host:127.0.0.1
master_port:8379
master_link_status:up
master_last_io_seconds_ago:6
master_sync_in_progress:0
slave_repl_offset:43
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

# CPU
used_cpu_sys:0.06
used_cpu_user:0.01
used_cpu_sys_children:0.00
used_cpu_user_children:0.00

# Cluster
cluster_enabled:0

# Keyspace
db0:keys=1,expires=0,avg_ttl=0


127.0.0.1:8380> SLAVEOF no one  配置没有主
OK


127.0.0.1:8380> info
# Server
redis_version:3.0.6
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:28b6715d3583bf8e
redis_mode:standalone
os:Linux 4.15.0-45-generic x86_64
arch_bits:64
multiplexing_api:epoll
gcc_version:5.4.0
process_id:7666
run_id:5e077def1cd19dee9f3a379cc889b363f20b8305
tcp_port:8380
uptime_in_seconds:103
uptime_in_days:0
hz:10
lru_clock:7649775
config_file:/usr/local/redis/redis2/etc/redis.conf

# Clients
connected_clients:1
client_longest_output_list:0
client_biggest_input_buf:0
blocked_clients:0

# Memory
used_memory:816360
used_memory_human:797.23K
used_memory_rss:3686400
used_memory_peak:837232
used_memory_peak_human:817.61K
used_memory_lua:36864
mem_fragmentation_ratio:4.52
mem_allocator:jemalloc-3.6.0

# Persistence
loading:0
rdb_changes_since_last_save:0
rdb_bgsave_in_progress:0
rdb_last_save_time:1551153544
rdb_last_bgsave_status:ok
rdb_last_bgsave_time_sec:-1
rdb_current_bgsave_time_sec:-1
aof_enabled:0
aof_rewrite_in_progress:0
aof_rewrite_scheduled:0
aof_last_rewrite_time_sec:-1
aof_current_rewrite_time_sec:-1
aof_last_bgrewrite_status:ok
aof_last_write_status:ok

# Stats
total_connections_received:3
total_commands_processed:11
instantaneous_ops_per_sec:0
total_net_input_bytes:268
total_net_output_bytes:4961
instantaneous_input_kbps:0.00
instantaneous_output_kbps:0.00
rejected_connections:0
sync_full:0
sync_partial_ok:0
sync_partial_err:0
expired_keys:0
evicted_keys:0
keyspace_hits:0
keyspace_misses:0
pubsub_channels:0
pubsub_patterns:0
latest_fork_usec:0
migrate_cached_sockets:0

# Replication
role:master                # 变成了master了
connected_slaves:0
master_repl_offset:99
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

# CPU
used_cpu_sys:0.09
used_cpu_user:0.02
used_cpu_sys_children:0.00
used_cpu_user_children:0.00

# Cluster
cluster_enabled:0

# Keyspace
db0:keys=1,expires=0,avg_ttl=0
127.0.0.1:8380>

2.9 健康检查

        Slave按照repl-ping-slave-period的间隔(默认10秒),向Master发送ping。

       如果主从间的链接中断后,再次连接的时候,2.8以前按照full sync再同期。2.8以后,因为有backlog的设定,backlog存在master的内存里,重新连接之前,如果redis没有重启,并且offset在backlog保存的范围内,可以实现从断开地方同期,不符合这个条件,还是full sync

        用monitor命令,可以看到slave在发送ping

127.0.0.1:8380> slaveof localhost 8379
OK
127.0.0.1:8380> MONITOR
OK
1551153843.193225 [0 127.0.0.1:8379] "PING"

        用ping命令,可以看到slave在发送ping

root@leco:/usr/local/redis# redis-cli -p 8380
127.0.0.1:8380> ping
PONG

注意

以上配置master主从是单个机器上启动的多少实例,多机主从,类似,配置文件稍微修改。