Skip to content

Commit 704d654

Browse files
CraigLeitiantaolimingxinleo
authored
Added sentinel mode for redis. (#1868)
Co-authored-by: tiantao <[email protected]> Co-authored-by: 李铭昕 <[email protected]>
1 parent a9177da commit 704d654

File tree

4 files changed

+85
-8
lines changed

4 files changed

+85
-8
lines changed

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@
3131
"friendsofphp/php-cs-fixer": "^2.9"
3232
},
3333
"suggest": {
34-
"hyperf/di": "Create the RedisPool via dependency injection."
34+
"hyperf/di": "Create the RedisPool via dependency injection.",
35+
"ext-redis": "Required to use sentinel mode (>=5.2)."
3536
},
3637
"autoload": {
3738
"psr-4": {

publish/redis.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,13 @@
2323
'name' => null,
2424
'seeds' => [],
2525
],
26+
'sentinel' => [
27+
'enable' => (bool) env('REDIS_SENTINEL_ENABLE', false),
28+
'master_name' => env('REDIS_MASTER_NAME', 'mymaster'),
29+
'nodes' => explode(';', env('REDIS_SENTINEL_NODE', '')),
30+
'persistent' => '',
31+
'read_timeout' => 0,
32+
],
2633
'pool' => [
2734
'min_connections' => 1,
2835
'max_connections' => 10,

src/RedisConnection.php

Lines changed: 69 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,13 @@ class RedisConnection extends BaseConnection implements ConnectionInterface
4444
'name' => null,
4545
'seeds' => [],
4646
],
47+
'sentinel' => [
48+
'enable' => false,
49+
'master_name' => '',
50+
'nodes' => [],
51+
'persistent' => '',
52+
'read_timeout' => 0,
53+
],
4754
'options' => [],
4855
];
4956

@@ -93,15 +100,19 @@ public function reconnect(): bool
93100
$db = $this->config['db'];
94101
$timeout = $this->config['timeout'];
95102
$cluster = $this->config['cluster']['enable'] ?? false;
103+
$sentinel = $this->config['sentinel']['enable'] ?? false;
96104

97105
$redis = null;
98-
if ($cluster !== true) {
99-
$redis = new \Redis();
100-
if (! $redis->connect($host, $port, $timeout)) {
101-
throw new ConnectionException('Connection reconnect failed.');
102-
}
103-
} else {
104-
$redis = $this->createRedisCluster();
106+
switch (true) {
107+
case $cluster:
108+
$redis = $this->createRedisCluster();
109+
break;
110+
case $sentinel:
111+
$redis = $this->createRedisSentinel();
112+
break;
113+
default:
114+
$redis = $this->createRedis($host, $port, $timeout);
115+
break;
105116
}
106117

107118
$options = $this->config['options'] ?? [];
@@ -178,4 +189,55 @@ protected function retry($name, $arguments, \Throwable $exception)
178189

179190
return $result;
180191
}
192+
193+
protected function createRedisSentinel()
194+
{
195+
try {
196+
$nodes = $this->config['sentinel']['nodes'] ?? [];
197+
$timeout = $this->config['timeout'] ?? 0;
198+
$persistent = $this->config['sentinel']['persistent'] ?? null;
199+
$retryInterval = $this->config['retry_interval'] ?? 0;
200+
$readTimeout = $this->config['sentinel']['read_timeout'] ?? 0;
201+
$masterName = $this->config['sentinel']['master_name'] ?? '';
202+
203+
$host = '';
204+
$port = 0;
205+
foreach ($nodes as $node) {
206+
[$sentinelHost, $sentinelPort] = explode(':', $node);
207+
$sentinel = new \RedisSentinel(
208+
$sentinelHost,
209+
intval($sentinelPort),
210+
$timeout,
211+
$persistent,
212+
$retryInterval,
213+
$readTimeout
214+
);
215+
$masterInfo = $sentinel->getMasterAddrByName($masterName);
216+
if (is_array($masterInfo) && count($masterInfo) >= 2) {
217+
[$host, $port] = $masterInfo;
218+
break;
219+
}
220+
}
221+
$redis = $this->createRedis($host, $port, $timeout);
222+
} catch (\Throwable $e) {
223+
throw new ConnectionException('Connection reconnect failed ' . $e->getMessage());
224+
}
225+
226+
return $redis;
227+
}
228+
229+
/**
230+
* @param string $host
231+
* @param int $port
232+
* @param float $timeout
233+
* @return \Redis
234+
*/
235+
protected function createRedis($host, $port, $timeout)
236+
{
237+
$redis = new \Redis();
238+
if (! $redis->connect((string) $host, (int) $port, $timeout)) {
239+
throw new ConnectionException('Connection reconnect failed.');
240+
}
241+
return $redis;
242+
}
181243
}

tests/RedisConnectionTest.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,13 @@ public function testRedisConnectionConfig()
5151
'name' => null,
5252
'seeds' => [],
5353
],
54+
'sentinel' => [
55+
'enable' => false,
56+
'master_name' => '',
57+
'nodes' => [],
58+
'persistent' => '',
59+
'read_timeout' => 0,
60+
],
5461
'options' => [],
5562
'pool' => [
5663
'min_connections' => 1,

0 commit comments

Comments
 (0)