【Laravel】Redis主从复制
首先
关于由Laravel开发的应用程序,我为了负载均衡的目的,将原本的单台Web服务器改为了两台Web服务器,并引入了负载均衡器。
最初我们在Web服务器的缓存客户端中引入了Redis,但是随着增加Web服务器设备,我们需要在新增的Web服务器上也引入Redis。
此外,为了避免缓存数据在每个Web服务器上产生差异,Redis中存储的缓存数据需要在每个Web服务器的Redis之间进行同步。
我将介绍一种方法,即将原本存在的Web服务器上的Redis复制到新添加的Web服务器上的Redis。
我们将原始的Web服务器称为Web1号机,将添加的Web服务器称为Web2号机。另外,关于Redis的复制,我们将Web1号机设为Master,将Web2号机设为Slave,形成了Master-Slave结构。
系统配置的更改如下图所示。

环境
-
- Laravel 6.5
- Redis 6.2.3
验证主从通信
如果保持Redis的默认设置,连接配置只能是127.0.0.1(localhost)。
(Master側で)
$ redis-cli -h 192.168.1.y
Could not connect to Redis at 192.168.1.y:6379: Connection refused
not connected>
设置从Slave到Master的连接配置。
无论是主节点还是从节点,都需要修改/etc/redis/redis.conf中的连接设置部分。
bind 127.0.0.1 → bind 0.0.0.0
执行Redis的重启操作。
$ systemctl restart redis.service
确认沟通是否畅通
在主从设备之间进行通信确认。
(Master側で)
$ redis-cli -h 192.168.1.y
192.168.1.y:6379>
(Slave側で)
$ redis-cli -h 192.168.1.x
192.168.1.x:6379>
确认服务器之间的联通。
复制配置
我将修改Slave节点上的redis.conf文件。
slaveof <masterのIP> <masterのredisのport番号>
通过这样做,可以设置Master和Slave之间的对应关系。
slaveof 192.168.1.y 6379
对每个Redis进行重新启动。
$ systemctl restart redis.service
确认复制
确认设置
我将检查Slave是否已经复制了Master。
(Slave側で)
$ redis-cli
127.0.0.1:6379> INFO
// 割愛
# Replication
role:slave
master_host:192.168.1.x
master_port:6379
只要在”Replication”栏的”master_host”中填写了设置的主服务器IP地址,那么就可以进行复制设置。
师父也会检查设定。
$ redis-cli
127.0.0.1:6379> INFO
# Replication
role:master
connected_slaves:1
slave0:ip=192.168.1.y,port=6379,state=online,offset=110155,lag=1
如果在Replication栏的slave0中填写了设置的Slave的IP地址,那就可以了。
虽然我们这次没有实施,但也可以将多个Slave与Master关联起来。
确认数据同步。
我在Master端确认设置的数据是否已被复制到Slave端。
(Master側で)
127.0.0.1:6379> set key1 value1
OK
127.0.0.1:6379> keys *
1) "key1"
(上記実行後、Slave側で)
127.0.0.1:6379> keys *
1) "key1"
数据删除的过程同样会被复制到从库。
(Master側で)
127.0.0.1:6379> keys *
1) "key1"
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> keys *
(empty list or set)
(上記実行後、Slave側で)
127.0.0.1:6379> keys *
(empty list or set)
另外,由于Slave仅允许进行查找操作,因此如果尝试在Slave上进行数据添加或删除操作,将会出现错误。
(上記実行後、Slave側で)
127.0.0.1:6379> set key1 value1
(error) READONLY You can't write against a read only slave.
在程序中,需要控制缓存的引用分别指向每个Redis(即localhost),对于添加、更新和删除操作,需要参考主节点(Master)。
改变Laravel Redis的配置内容
关于应用程序内缓存的设置,请参考config/cache.php中的说明。
以下是存储Redis配置内容的stores键。
'stores' => [
// 割愛
'redis' => [
'driver' => 'redis',
'connection' => 'cache',
],
// 割愛
],
默认情况下,redis只有一个配置(本地主机)可用。但是这次需要两个配置内容来进行读取/写入操作,所以将配置内容更改如下。
'stores' => [
// 割愛
'redis_read' => [
'driver' => 'redis',
'connection' => 'read_cache',
],
'redis_write' => [
'driver' => 'redis',
'connection' => 'write_cache',
],
// 割愛
],
在上述的连接选项中,指定的内容是缓存客户端的连接目标,它记录了在config/database.php文件中的驱动项(即redis)中使用的值是什么。
默认的config/database.php文件如下所示。
'redis' => [
'client' => env('REDIS_CLIENT', 'phpredis'),
'default' => [
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => env('REDIS_DB', 0),
],
'cache' => [
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => env('REDIS_CACHE_DB', 1),
],
],
由于需要分别描述读取和写入的连接信息,下面的修改将被进行。
'redis' => [
'client' => env('REDIS_CLIENT', 'phpredis'),
'default' => [
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => env('REDIS_DB', 0),
],
'read_cache' => [
'url' => env('REDIS_URL'),
'host' => env('REDIS_HOST', '127.0.0.1'),
'host' => env('REDIS_HOST_READ', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => env('REDIS_CACHE_DB', 1),
],
'write_cache' => [
'url' => env('REDIS_URL'),
'host' => env('REDIS_HOST_WRITE', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => env('REDIS_CACHE_DB', 1),
],
],
另外,需要在.env文件中记录read_cache和write_cache的主机(IP地址)。
REDIS_HOST_READ=127.0.0.1
REDIS_HOST_WRITE=192.168.1.x
为了读取Redis,将IP地址设置为127.0.0.1(本地主机)。也就是说,引用的Redis是指在自己的Web服务器内的Redis。
为了写入Redis,将IP地址设置为Master的IP地址。这样可以使Web1号机和Web2号机都能够将数据写入到Master的Redis中。
最後
只需要两台Web服务器的Redis主从配置,并不需要非常复杂的设置,我们已经能够实施。不仅可以进行复制,还可以进行集群等操作,如果有机会的话,我想学习一下。