【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结构。

系统配置的更改如下图所示。

20210916_1.png

环境

    • 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主从配置,并不需要非常复杂的设置,我们已经能够实施。不仅可以进行复制,还可以进行集群等操作,如果有机会的话,我想学习一下。

bannerAds