Redis cluster部署及在Laravel中的配置

环境说明

  • CentOS7(ip: 192.168.8.11)
  • Redis5.0.2(可执行命令已复制到/usr/local/bin/,可在任意目录执行)
  • Laravel5.5
  • predis1.1
  • ruby执行环境(可用命令yum -y install ruby ruby-devel rubygems rpm-build一键安装)
  • ruby redis客户端(安装命令gem install redis --version 3.0.0

cluster部署

用来生成cluster节点配置文件的脚本:

#!/bin/sh
#create redis cluster conf
#/data/sh/new-cluster-conf.sh
#接收两个参数,一是起始端口,二是结尾端口,代表生成这区间内每个端口的配置文件

p1=$1
p2=$2

for((p=p1;p<=p2;p++))
do
conf="/usr/local/etc/cluster-${p}.conf"
echo "port ${p}" > ${conf}
echo "daemonize yes" >> ${conf}
echo "dir /data/redis/" >> ${conf}
echo "dbfilename dump-${p}.rdb" >> ${conf}
echo "logfile /data/redis/cluster-${p}.log" >> ${conf}
echo "cluster-config-file /usr/local/etc/nodes-${p}.conf" >> ${conf}
echo "bind 0.0.0.0" >> ${conf}
echo "cluster-enabled yes" >> ${conf}
echo "cluster-node-timeout 15000" >> ${conf}
echo "cluster-require-full-coverage no" >> ${conf}
done

用来启动cluster节点的脚本:

#!/bin/sh
#/data/sh/start-cluster.sh
#接收若干个参数,每个参数是要开启的节点端口号

for p in "$@" ; do
redis-server    /usr/local/etc/cluster-${p}.conf
done

执行命令

#新建各个节点的配置文件
sh /data/sh/new-cluster-conf.sh 6411 6416
#开启准备节点
sh /data/sh/start-cluster.sh 6411 6412 6413 6414 6415 6416
#运行自动配置工具完成后续操作,命令设置了每个主节点分配一个从节点,前面的节点是主,后面那几个是从
redis-cli --cluster create 127.0.0.1:6411 127.0.0.1:6412 127.0.0.1:6413 127.0.0.1:6414 127.0.0.1:6415 127.0.0.1:6416 --cluster-replicas 1

cluster的搭建可分为四步:

  1. 是开启准备节点;
  2. 是节点间meet握手,让彼此知道对方的存在;
  3. 分配主从节点;
  4. 分配槽。

Redis5中使用redis-cli --cluster(单独执行redis-cli --cluster help可获得该命令的帮助信息)代替了redis-trib.rb集群自动操作工具的全部功能,使用自动工具可以一条命令执行完第2步到第4步的操作,可靠且高效。
上面3条命令执行完成后,cluster就算部署好了。然后可用下图命令查看集群节点情况(rdc是我自定义的redis-cli命令别名),端口6411、6412和6413是主节点,其余是从节点,每个主节点配有一个从节点。cennected后面接的是被分配的槽的范围。
在这里插入图片描述

集群扩容

假设业务需要扩展集群容量,新增端口6417的节点为主节点,6418为从节点,那需要执行3步操作,1开启前面提到的两个节点;2执行自动命令添加节点到已有的集群和分配主从;3分配槽。
已开启准备节点后再执行下面命令

#6417节点加入集群,默认成为主节点,6411节点是已存在集群内的节点,指示目标集群
redis-cli --cluster add-node 192.168.8.11:6417 192.168.8.11:6411
#6418节点加入集群,`--cluster-slave --cluster-master-id`后接的是其对应的主节点id
redis-cli --cluster add-node 192.168.8.11:6418 192.168.8.11:6411 --cluster-slave --cluster-master-id fb7bbf981b7339221f6deac111d8a68e91657a07
#给目标集群调整槽的分配,如下图示,分别输入要分配的槽大小(4096)、目标节点(6417)的id和槽的来源节点
redis-cli --cluster reshard 192.168.8.11:6411

在这里插入图片描述
分配完后可看到6417节点的槽分配:
在这里插入图片描述

Laravel配置

下面配置中仅prifix项是可有可无的,其它的都必须要有,default组下的每个元素都是配置一个节点的信息,要将集群里无论主从节点都加入其中。

    'redis' => [
        'options' => [
            'prefix' => 'test::',
            'cluster' => 'redis', //使用原生集群
        ],
        
        'client' => 'predis',

        'clusters' => [
            'default' => [
                [
                    'host' => '192.168.8.11',
                    'password' => null,
                    'port' => 6411,
                    'database' => 0,
                ],
                [
                    'host' => '192.168.8.11',
                    'password' => null,
                    'port' => 6412,
                    'database' => 0,
                ],
                [
                    'host' => '192.168.8.11',
                    'password' => null,
                    'port' => 6414,				//端口6411的从节点
                    'database' => 0,
                ],
                [
                    'host' => '192.168.8.11',
                    'password' => null,
                    'port' => 6415,				//端口6412的从节点
                    'database' => 0,
                ],
                ·
                ·
                ·
                //为了简明表达,这里略去了若干个节点,实际操作中一定要全部加上
            ],
        ],
    ],

end

已标记关键词 清除标记
<div class="post-text" itemprop="text"> <p>I got a Redis Cluster server which I created by following this <a href="https://redis.io/topics/cluster-tutorial#creating-the-cluster" rel="nofollow noreferrer">tutorial</a>. </p> <p>This is what my database/config.php setup looks like (see details <a href="https://stackoverflow.com/questions/56497809/how-to-make-laravel-work-with-redis-cluster-on-aws">here</a>):</p> <pre><code>'redis' => [ 'client' => 'predis', 'cluster' => true, 'options' => [ 'cluster' => 'redis', 'parameters' => [ 'host' => env('REDIS_DEFAULT_HOST', '127.0.01'), 'password' => env('REDIS_PASSWORD', null), 'port' => env('REDIS_DEFAULT_PORT', 6379), 'database' => 0, ], ], 'clusters' => [ 'default' => [ 'host' => env('REDIS_DEFAULT_HOST', '127.0.01'), 'password' => env('REDIS_PASSWORD', null), 'port' => env('REDIS_DEFAULT_PORT', 6379), 'database' => 0, ], 'jobs' => [ 'host' => env('REDIS_JOBS_HOST', '127.0.01'), 'password' => env('REDIS_PASSWORD', null), 'port' => env('REDIS_JOBS_PORT', 6379), 'database' => 0, ], 'content' => [ 'host' => env('REDIS_CONTENT_HOST', '127.0.01'), 'password' => env('REDIS_PASSWORD', null), 'port' => env('REDIS_CONTENT_PORT', 6379), 'database' => 0, ], 'options' => [ 'cluster' => 'redis' ], ] ] </code></pre> <p>and what my config/broadcasting.php looks like:</p> <pre><code><?php return [ /* |-------------------------------------------------------------------------- | Default Broadcaster |-------------------------------------------------------------------------- | | This option controls the default broadcaster that will be used by the | framework when an event needs to be broadcast. You may set this to | any of the connections defined in the "connections" array below. | */ 'default' => env('BROADCAST_DRIVER', 'redis'), /* |-------------------------------------------------------------------------- | Broadcast Connections |-------------------------------------------------------------------------- | | Here you may define all of the broadcast connections that will be used | to broadcast events to other systems or over websockets. Samples of | each available type of connection are provided inside this array. | */ 'connections' => [ 'pusher' => [ 'driver' => 'pusher', 'key' => env('PUSHER_KEY'), 'secret' => env('PUSHER_SECRET'), 'app_id' => env('PUSHER_APP_ID'), ], 'redis' => [ 'driver' => 'redis', 'connection' => 'default', ], 'log' => [ 'driver' => 'log', ], ], ]; </code></pre> <p>when i reach this part in my code when i want to publish an event in redis:</p> <pre><code> // Dispatch an event indicates order status has been changed. event(new OrderStatusChanged($order->id, OrderActionsConstants::INCOMPLETE_CART)); </code></pre> <p>I get this error:</p> <pre><code>Cannot use 'PUBLISH' with redis-cluster. </code></pre> <p>with this stack trace</p> <pre><code>[2019-06-10 17:05:06] local.ERROR: 0 /Users/Shared/dev/php/toters-api/vendor/predis/predis/src/Connection/Aggregate/RedisCluster.php(550): Predis\Connection\Aggregate\RedisCluster->getConnection(Object(Predis\Command\PubSubPublish)) 1 /Users/Shared/dev/php/toters-api/vendor/predis/predis/src/Connection/Aggregate/RedisCluster.php(593): Predis\Connection\Aggregate\RedisCluster->retryCommandOnFailure(Object(Predis\Command\PubSubPublish), 'executeCommand') 2 /Users/Shared$dev/php/toters-api/vendor/predis/predis/src/Client.php(331): Predis\Connection\Aggregate\RedisCluster->executeCommand(Object(Predis\Command\PubSubPublish)) 3 /Users/Shared/dev/php/toters-api/vendor/predis/predis/src/Client.php(314): Pre$is\Client->executeCommand(Object(Predis\Command\PubSubPublish)) 4 /Users/Shared/dev/php/toters-api/vendor/laravel/framework/src/Illuminate/Redis/Connections/Connection.php(72): Predis\Client->__call('publish', Array) 5 /Users/Shared/de$/php/toters-api/vendor/laravel/framework/src/Illuminate/Redis/Connections/Connection.php(84): Illuminate\Redis\Connections\Connection->command('publish', Array) 6 /Users/Shared/dev/php/toters-api/vendor/laravel/framework/src/Illuminate/$roadcasting/Broadcasters/RedisBroadcaster.php(99): Illuminate\Redis\Connections\Connection->__call('publish', Array) 7 /Users/Shared/dev/php/toters-api/vendor/laravel/framework/src/Illuminate/Broadcasting/BroadcastEvent.php(48): Illumin$te\Broadcasting\Broadcasters\RedisBroadcaster->broadcast(Array, 'order.status', '{"event":"order...') 8 [internal function]: Illuminate\Broadcasting\BroadcastEvent->handle(Object(Illuminate\Broadcasting\Broadcasters\RedisBroadcaster)) $ /Users/Shared/dev/php/toters-api/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(29): call_user_func_array(Array, Array) 10 /Users/Shared/dev/php/toters-api/vendor/laravel/framework/src/Illuminate/Container/BoundMetho$.php(87): Illuminate\Container\BoundMethod::Illuminate\Container\{closure}() 11 /Users/Shared/dev/php/toters-api/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(31): Illuminate\Container\BoundMethod::callBoundMethod(Ob$ect(Illuminate\Foundation\Application), Array, Object(Closure)) 12 /Users/Shared/dev/php/toters-api/vendor/laravel/framework/src/Illuminate/Container/Container.php(539): Illuminate\Container\BoundMethod::call(Object(Illuminate\Foundatio$\Application), Array, Array, NULL) 13 /Users/Shared/dev/php/toters-api/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(94): Illuminate\Container\Container->call(Array) 14 /Users/Shared/dev/php/toters-api/vendor/laravel/frame$ork/src/Illuminate/Pipeline/Pipeline.php(114): Illuminate\Bus\Dispatcher->Illuminate\Bus\{closure}(Object(Illuminate\Broadcasting\BroadcastEvent)) 15 /Users/Shared/dev/php/toters-api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipe$ine.php(102): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Broadcasting\BroadcastEvent)) 16 /Users/Shared/dev/php/toters-api/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(98): Illuminate\Pip$line\Pipeline->then(Object(Closure)) 17 /Users/Shared/dev/php/toters-api/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(42): Illuminate\Bus\Dispatcher->dispatchNow(Object(Illuminate\Broadcasting\BroadcastEvent), fal$e) 18 /Users/Shared/dev/php/toters-api/vendor/laravel/framework/src/Illuminate/Queue/Jobs/Job.php(69): Illuminate\Queue\CallQueuedHandler->call(Object(Illuminate\Queue\Jobs\SyncJob), Array) 19 /Users/Shared/dev/php/toters-api/vendor/la$avel/framework/src/Illuminate/Queue/SyncQueue.php(42): Illuminate\Queue\Jobs\Job->fire() 20 /Users/Shared/dev/php/toters-api/vendor/laravel/framework/src/Illuminate/Queue/Queue.php(42): Illuminate\Queue\SyncQueue->push(Object(Illuminate$Broadcasting\BroadcastEvent), '', NULL) 21 /Users/Shared/dev/php/toters-api/vendor/laravel/framework/src/Illuminate/Broadcasting/BroadcastManager.php(128): Illuminate\Queue\Queue->pushOn(NULL, Object(Illuminate\Broadcasting\BroadcastEve$t)) 22 /Users/Shared/dev/php/toters-api/vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php(270): Illuminate\Broadcasting\BroadcastManager->queue(Object(App\Events\OrderStatusChanged)) 23 /Users/Shared/dev/php/toters-api/vend$r/laravel/framework/src/Illuminate/Events/Dispatcher.php(193): Illuminate\Events\Dispatcher->broadcastEvent(Object(App\Events\OrderStatusChanged)) 24 /Users/Shared/dev/php/toters-api/vendor/laravel/framework/src/Illuminate/Foundation/he$pers.php(446): Illuminate\Events\Dispatcher->dispatch('App\\Events\\Orde...') 25 /Users/Shared/dev/php/toters-api/app/Repositories/Orders/AppOrdersRepo.php(107): event(Object(App\Events\OrderStatusChanged)) </code></pre> <p>How do I fix this?</p> </div>
©️2020 CSDN 皮肤主题: 精致技术 设计师:CSDN官方博客 返回首页