主从架构可以本机多实例数据库之间实现,也可以异机多实例之间实现。
主可读可写,备只读,这样就可以实现读写分离的架构。
redis主从复制的特点:
1.一台master可以拥有多个slave(1对多的关系)
2.多个slave可以连接同一个master外,还可以连接到其他slave
这样做的原因是,如果master 挂掉之后,其中的一台slave立马可以充当master 的角色
整个服务流程可以不受影响
3.复制过程不会阻塞master,在同步数据的同时,master可以继续处理client请求。
4.提高系统的伸缩性
redis 主从复制的过程:
1.slave 与 master建立连接,发送sync同步命令。
2.master会启动一个后台进程,将数据库快照保存到文件中,同时master主进程会开始收集新的写命令并缓存
3.后台完成保存后,将文件发送给slave
4.slave将文件保存到硬盘上
redis 主从复制配置和使用都非常简单。
通过主从复制可以允许多个slave server拥有和master server相同的数据库副本。
下面是关于redis 主从复制的一些特点:
1.master 可以有多个slave
2.除了多个slave连到相同的master外,slave也可以连接其他slave形成图状结构
3.主从复制不会阻塞master。也就是说当一个或多个slave与master进行初次同步数据时,master可以继续处理client发来的请求。
相反slave在初次同步数据时,则会阻塞不能处理client的请求。
4.主从复制可以用来提高系统的可伸缩性,我们可以用多个slave专门用于client的读请求,
比如sort操作可以使用slave来处理。也可以用来做简单的数据冗余。
5.可以在master禁用数据持久化,只需要注释掉master配置文件中的所有save配置,然后只在slave上配置数据持久化。
配置过程:
这里使用同一台服务器上两个不同实例做主备实验。
主:6378
备:6379
1.启动主redis实例
[[email protected] ~]# /etc/init.d/redis_6378 restart Stopping ... Redis stopped Starting Redis server...
2.添加备实例参数
[[email protected] ~]# vi /etc/redis/6379.conf 添加如下内容 slaveof 127.0.0.1 6378 #表示主节点是127.0.0.1的6378端口
3.启动备实例
[[email protected] ~]# /etc/init.d/redis_6379 restart Stopping ... Redis stopped Starting Redis server...
4.查看角色状态
[[email protected] ~]# redis-cli -p 6378 info .... # Replication role:master #角色是master connected_slaves:1 #当前连接的slaves有1个 slave0:ip=127.0.0.1,port=6379,state=online,offset=85,lag=1 #slave0 是 127.0.0.1的6379端口,状态为online master_repl_offset:85 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:2 repl_backlog_histlen:84 .... [[email protected] ~]# redis-cli -p 6379 info .... # Replication role:slave #角色状态是slave master_host:127.0.0.1 #master的地址是127.0.0.1 master_port:6378 #master端口号是6378 master_link_status:up #跟master连接的状态是up的 master_last_io_seconds_ago:0 master_sync_in_progress:0 slave_repl_offset:323 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 .... 这里说明主从就已经配置好了,很简单吧。
5.验证同步
[[email protected] ~]# redis-cli -p 6378 127.0.0.1:6378> set s1 abc #在master创建两个值,s1 s2 OK 127.0.0.1:6378> set s2 bcd OK 127.0.0.1:6378> mget s1 s2 1) "abc" 2) "bcd" 127.0.0.1:6378> quit [[email protected] ~]# redis-cli -p 6379 127.0.0.1:6379> get s1 #在slave中也能读取刚才的s1 s2两个值 "abc" 127.0.0.1:6379> get s2 "bcd" 127.0.0.1:6379> set s1 aaa #这里slave无法写,只能读 (error) READONLY You can‘t write against a read only slave.
6.进一步实验,slave-slave
初始化一个6380的实例 [[email protected] ~]# cd /root/redis-2.8.13/utils/ [[email protected] utils]# ./install_server.sh Welcome to the redis service installer This script will help you easily set up a running redis server Please select the redis port for this instance: [6379] 6380 Please select the redis config file name [/etc/redis/6380.conf] Selected default - /etc/redis/6380.conf Please select the redis log file name [/var/log/redis_6380.log] Selected default - /var/log/redis_6380.log Please select the data directory for this instance [/var/lib/redis/6380] Selected default - /var/lib/redis/6380 Please select the redis executable path [/usr/local/bin/redis-server] Selected config: Port : 6380 Config file : /etc/redis/6380.conf Log file : /var/log/redis_6380.log Data dir : /var/lib/redis/6380 Executable : /usr/local/bin/redis-server Cli Executable : /usr/local/bin/redis-cli Is this ok? Then press ENTER to go on or Ctrl-C to abort. Copied /tmp/6380.conf => /etc/init.d/redis_6380 Installing service... Successfully added to chkconfig! Successfully added to runlevels 345! Starting Redis server... Installation successful! 同样修改配置文件 [[email protected] utils]# vi /etc/redis/6380.conf 添加如下内容 slaveof 127.0.0.1 6379 [[email protected] utils]# /etc/init.d/redis_6380 restart Stopping ... Redis stopped Starting Redis server... [[email protected] utils]# redis-cli -p 6380 info ... # Replication role:slave master_host:127.0.0.1 master_port:6379 master_link_status:up master_last_io_seconds_ago:8 master_sync_in_progress:0 slave_repl_offset:29 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 ... [[email protected] utils]# redis-cli -p 6379 info ... # Replication role:slave master_host:127.0.0.1 master_port:6378 master_link_status:up master_last_io_seconds_ago:1 master_sync_in_progress:0 slave_repl_offset:1092 slave_priority:100 slave_read_only:1 connected_slaves:1 slave0:ip=127.0.0.1,port=6380,state=online,offset=85,lag=1 #在备状态下,又连接了一个备 master_repl_offset:85 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:2 repl_backlog_histlen:84 ....
7.验证同步
[[email protected] utils]# redis-cli -p 6380 mget s1 s2 1) "abc" 2) "bcd" [[email protected] utils]# redis-cli -p 6378 shutdown [[email protected] utils]# redis-cli -p 6379 info ... # Replication role:slave master_host:127.0.0.1 master_port:6378 master_link_status:down #跟master的连接已经挂掉了 master_last_io_seconds_ago:-1 master_sync_in_progress:0 slave_repl_offset:1470 master_link_down_since_seconds:7 slave_priority:100 slave_read_only:1 connected_slaves:0 master_repl_offset:477 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:2 repl_backlog_histlen:476 ... [[email protected] utils]# redis-cli -p 6380 info ... # Replication role:slave master_host:127.0.0.1 master_port:6379 master_link_status:down #表示跟6379的连接也挂掉了 master_last_io_seconds_ago:-1 master_sync_in_progress:0 slave_repl_offset:1 master_link_down_since_seconds:65 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 ... 发现主挂掉之后,从库仍然是可以读的 [[email protected] utils]# redis-cli -p 6380 get s1 "abc"
8.添加认证
如果其他人知道我的IP和端口号就可以直接用来跟redis做主从同步了。不安全,下面来看一下如何设置密码
[[email protected] utils]# vi /etc/redis/6378.conf 添加一行 requirepass redis #这里表示密码就是redis [[email protected] utils]# /etc/init.d/redis_6378 start Starting Redis server... [[email protected] utils]# redis-cli -p 6378 127.0.0.1:6378> get s1 #下次登录直接使用get命令就无法获得值了 (error) NOAUTH Authentication required. 127.0.0.1:6378> auth redis #输入密码后,可以使用刚才的get命令了。 OK 127.0.0.1:6378> get s1 "abc"
9.从库配置认证
[[email protected] utils]# redis-cli -p 6379 info # Replication role:slave master_host:127.0.0.1 master_port:6378 master_link_status:down #从这个地方看出跟主的连接还是down的 master_last_io_seconds_ago:-1 master_sync_in_progress:0 slave_repl_offset:1 master_link_down_since_seconds:1076 slave_priority:100 slave_read_only:1 connected_slaves:0 master_repl_offset:1961 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:2 repl_backlog_histlen:1960 .... 打开配置文件添加认证信息 [[email protected] utils]# vi /etc/redis/6379.conf 添加下面的信息 masterauth redis 重启一下备库,这里一定要重新启动一下备库 [[email protected] utils]# /etc/init.d/redis_6379 restart Stopping ... Redis stopped Starting Redis server... 状态就变成up了 [[email protected] utils]# redis-cli -p 6379 info | grep master master_host:127.0.0.1 master_port:6378 master_link_status:up master_last_io_seconds_ago:9 master_sync_in_progress:0 master_repl_offset:1
10.同步验证
[[email protected] utils]# redis-cli -p 6378 127.0.0.1:6378> auth redis OK 127.0.0.1:6378> set s3 abcd123 OK 127.0.0.1:6378> [[email protected] utils]# redis-cli -p 6379 127.0.0.1:6379> get s3 "abcd123"
介绍下面几个参数
slave-read-only yes #表示从库只读
repl-ping-slave-period 10 #从库会发送ping确认跟主库是否还可以互通