redis主从

redis是一款功能强大的缓存工具,支持丰富的数据结构,等等一些牛逼的特性暂且不表,今天重点说下主从,并通过指令,实践操作一下。

源码安装一下redis (版本3.2.8,官网下载)

将下载的文件,解压进行安装,安装很简单.

[root@localhost redis-3.2.8]# ll
总用量 256
-rw-rw-r--.  1 root root 85775 2月  12 23:14 00-RELEASENOTES
-rw-rw-r--.  1 root root    53 2月  12 23:14 BUGS
-rw-rw-r--.  1 root root  1805 2月  12 23:14 CONTRIBUTING
-rw-rw-r--.  1 root root  1487 2月  12 23:14 COPYING
drwxrwxr-x.  7 root root  4096 3月   1 10:28 deps
-rw-rw-r--.  1 root root    11 2月  12 23:14 INSTALL
-rw-rw-r--.  1 root root   151 2月  12 23:14 Makefile
-rw-rw-r--.  1 root root  4223 2月  12 23:14 MANIFESTO
-rw-rw-r--.  1 root root  6834 2月  12 23:14 README.md
-rw-rw-r--.  1 root root 46696 3月   1 10:52 redis.conf
-rw-r--r--.  1 root root 46695 3月   1 10:52 redis.conf-bk
-rwxrwxr-x.  1 root root   271 2月  12 23:14 runtest
-rwxrwxr-x.  1 root root   280 2月  12 23:14 runtest-cluster
-rwxrwxr-x.  1 root root   281 2月  12 23:14 runtest-sentinel
-rw-rw-r--.  1 root root  7606 2月  12 23:14 sentinel.conf
drwxrwxr-x.  2 root root  4096 3月   1 10:36 src
drwxrwxr-x. 10 root root  4096 2月  12 23:14 tests
drwxrwxr-x.  7 root root  4096 2月  12 23:14 utils
[root@localhost redis-3.2.8]# make

先执行make,然后再执行make install即可,安装后的指令在/usr/local/bin/下面。

[root@localhost redis-3.2.8]# whereis redis-server
redis-server: /usr/local/bin/redis-server

将源文件中的redis.conf文件拷贝到/etc/redis/目录下,若没有/etc/redis目录,可以自行创建之。并改名为6379.conf,可以是任意文件名,为了验证主从操作,将主服务器的端口设置为6379.

考虑到安全性,给配置文件中设置密码信息requirepass:

然后启动redis-server,用/etc/redis/6379.conf配置文件。

[root@localhost ~]# redis-server /etc/redis/6379.conf 
[root@localhost ~]# 

检查下,密码安全是否生效:

[root@localhost ~]# 
[root@localhost ~]# redis-cli
127.0.0.1:6379> 
127.0.0.1:6379> keys *
(error) NOAUTH Authentication required.
127.0.0.1:6379> 

通过keys *命令查看是是否有数据,被告知没有授权,说明requirepass指令生效。那么我们输入密码,能否进去呢?

127.0.0.1:6379> auth redis6379
OK
127.0.0.1:6379> keys *
1) "hello"
127.0.0.1:6379> 

说明安全问题,requirepass的设置已经是在正常工作了。

好了,单实例的redis服务器已经没有问题了,可以工作了。就开始本博文要讲的重点了,如何实现主从呢?按照redis的官方文档来说,其实也非常的简单,就是一个指令的事情slaveof host port。

那就再配置一个slave的服务器吧,配置文件命名为6380.conf,在6379.conf的基础上,主要修改一下port,以及requirepass,其他暂且都不变。在一个机器上运行两个redis服务器,仅仅是端口不同。

。。。。。。。。。
# Protected mode is a layer of security protection, in order to avoid that
# Redis instances left open on the internet are accessed and exploited.
#
# When protected mode is on and if:
#
# 1) The server is not binding explicitly to a set of addresses using the
#    "bind" directive.
# 2) No password is configured.
#
# The server only accepts connections from clients connecting from the
# IPv4 and IPv6 loopback addresses 127.0.0.1 and ::1, and from Unix domain
# sockets.
#
# By default protected mode is enabled. You should disable it only if
# you are sure you want clients from other hosts to connect to Redis
# even if no authentication is configured, nor a specific set of interfaces
# are explicitly listed using the "bind" directive.
protected-mode yes

# Accept connections on the specified port, default is 6379 (IANA #815344).
# If port 0 is specified Redis will not listen on a TCP socket.
port 6380
。。。。。。。。
################################## SECURITY ###################################

# Require clients to issue AUTH <PASSWORD> before processing any other
# commands.  This might be useful in environments in which you do not trust
# others with access to the host running redis-server.
#
# This should stay commented out for backward compatibility and because most
# people do not need auth (e.g. they run their own servers).
#
# Warning: since Redis is pretty fast an outside user can try up to
# 150k passwords per second against a good box. This means that you should
# use a very strong password otherwise it will be very easy to break.
#
requirepass redis6380
。。。。。。。。。

接下来,我们再启动这个6380的服务器:

[root@localhost redis]# redis-server /etc/redis/6380.conf
[root@localhost redis]#
[root@localhost redis]# redis-cli -h 127.0.0.1 -p 6380 -a redis6380
127.0.0.1:6380> keys *
(empty list or set)
127.0.0.1:6380>

从上面的操作日志中,可以看出,6380端口对应的服务已经启动,而且可以正常的连接上。redis-cli指定登录到那个host的那个port上,带上auth信息,本地是登录127.0.0.1机器的6380端口,密码信息为redis6380.

好了,我们开始给6379这个服务器设置slave,将6380的redis设置成从服务器。设置从服务器,需要在从服务器上指定主服务器的IP以及端口。slaveof <masterip> <masterport>

127.0.0.1:6380> slaveof 127.0.0.1 6379
OK
127.0.0.1:6380>

slaveof指令执行结束后,显示OK,应该是设置成功了吧。那我们检查一下是不是真的成功了,在6379这个服务器上用info指令或者info Replication查看一下主从复制信息:

127.0.0.1:6379> 
127.0.0.1:6379> info Replication
# Replication
role:master
connected_slaves:0
master_repl_offset:533
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:532
127.0.0.1:6379> 

怎么回事?connected_slaves:0,在6380上slaveof分明显示的是OK啊。那我在6379上再执行一下存储一个数据吧,看看6380从服务器上,是否将这个数据同步过来。

127.0.0.1:6379> set test "Hello world"
OK
127.0.0.1:6379> get test
"Hello world"
127.0.0.1:6379> 
127.0.0.1:6380> get test
(nil)
127.0.0.1:6380> 

从上面的数据来看,test的值只是在6379上有,在6380上没有,再一次证明slaveof执行后的OK不能说明6380真的成为了6379的slave。分析一下,我们这里,master是有密码要求的,是不是slaveof操作,master没有给予授权?查看下6380.conf的配置文件,找了下是否有这么一个配置从服务器授权的信息,还真找到了一个masterauth的字段。

# If the master is password protected (using the "requirepass" configuration
# directive below) it is possible to tell the slave to authenticate before
# starting the replication synchronization process, otherwise the master will
# refuse the slave request.
#
# masterauth <master-password>

于是乎,将这个masterauth字段配置上6379的密码redis6379. 再次启动6380的服务器,重复上面的验证操作,主要是slaveof的再次执行。

127.0.0.1:6379> info Replication
# Replication
role:master
connected_slaves:1
slave0:ip=127.0.0.1,port=6380,state=online,offset=1395,lag=0
master_repl_offset:1395
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:1394
127.0.0.1:6379> 

这次,6379上的info指令对应的信息,就是符合需求的,到此,说明主从的基本配置完成,再看看从服务是否将之前的数据同步过来呢?

127.0.0.1:6380> get test
"Hello world"
127.0.0.1:6380> 

这么看,数据也被同步到了从服务器6380上了。到此,基本的主从配置,就算结束了。

看看从服务器上,是否有什么特殊信息,关于主从配置的:

127.0.0.1:6380> info Replication
# 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:1717
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

那解除6380作为6379的slave关系,如何做呢?也很简单,执行一个命令slaveof no one

127.0.0.1:6380> slaveof no one
OK
127.0.0.1:6380> 
127.0.0.1:6380> info Replication
# Replication
role:master
connected_slaves:0
master_repl_offset:71
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

相应的,6379上,也就没有了这个slave

127.0.0.1:6379> 
127.0.0.1:6379> info Replication
# Replication
role:master
connected_slaves:0
master_repl_offset:211
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:210

当要做主从切换的时候,其实,通过收到操作,还是有点麻烦的。例如,假设6379 shutdown了,为了保证服务能正常运行,必须立即将6380的salve这个role解除,就要执行slave no one指令,然后,让应用连接到6380上。这个过程,其实还是蛮费事的。因为,当6379好了后,要重新作为master,那在6380上运行的时间里产生的数据,需要重新同步到6379上,可以通过手动拷贝已经持久化后的数据去覆盖6379的文件,可以解决问题,但是毕竟容易出错,时间周期长。

此问题,可以通过keepalived软件,将两个redis配置成互为backup的主从关系(redis的配置文件中slave-read-only这个字段,必须是no),可以保证应用系统的高可用性,关于keepalived的相关工作原理,不描述,自己去Google吧。

原文地址:https://www.cnblogs.com/shihuc/p/6483840.html