Skip to content

Commit

Permalink
imiphp#98 新增支持 Redis 哨兵模式、集群模式
Browse files Browse the repository at this point in the history
cache、lock、queue、rate-limit 改造兼容

# Conflicts:
#	src/Components/swoole/src/Redis/Pool/CoroutineRedisPool.php
#	src/Lock/Handler/Redis.php
#	src/Redis/RedisHandler.php
#	src/Redis/RedisResource.php
#	src/Redis/SyncRedisPool.php
#	src/Server/ConnectContext/BinderHandler/Redis.php
#	src/Server/ConnectContext/StoreHandler/Redis.php
#	src/Server/Group/Handler/Redis.php
  • Loading branch information
Yurunsoft committed Jul 21, 2021
1 parent e6391e7 commit 9a8db03
Show file tree
Hide file tree
Showing 15 changed files with 290 additions and 95 deletions.
9 changes: 9 additions & 0 deletions .github/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,15 @@ services:
retries: 3
start_period: 5s

postgres:
image: postgres:13
environment:
POSTGRES_USER: root
POSTGRES_DB: db_imi_test
POSTGRES_PASSWORD: root
ports:
- "5432:5432"

redis:
image: redis:6-alpine
container_name: redis
Expand Down
3 changes: 2 additions & 1 deletion .github/swoole.dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ FROM phpswoole/swoole:${SWOOLE_DOCKER_VERSION}
ARG PHP_JIT="0"

RUN set -eux \
&& apt-get update && apt-get -y install procps \
&& apt-get update && apt-get -y install procps libpq-dev unzip \
&& docker-php-ext-install bcmath mysqli pdo_mysql pcntl \
&& pecl install redis \
&& docker-php-ext-enable redis \
&& wget -O ext-postgresql.zip https://github.com/swoole/ext-postgresql/archive/refs/tags/v4.6.1.zip && unzip ext-postgresql.zip && cd ext-postgresql && phpize && ./configure && make -j$(sysctl -n hw.ncpu) && make install && docker-php-ext-enable swoole_postgresql && php --ri swoole_postgresql\
&& ( \
[ $(php -r "echo PHP_VERSION_ID < 80000 ? 1 : 0;") = "0" ] \
|| (pecl install hprose && docker-php-ext-enable hprose) \
Expand Down
30 changes: 30 additions & 0 deletions doc/components/redis/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ return [
],
// 数组资源配置
'resource' => [
// --- 单机模式配置 ---
// 'mode' => \Imi\Redis\Enum\RedisMode::STANDALONE,
// 'host' => '127.0.0.1',
// 'port' => 6379,
// 是否自动序列化变量
Expand All @@ -61,6 +63,34 @@ return [
// 'password' => null,
// 第几个库
// 'db' => 0,

// --- 哨兵模式配置 ---
'mode' => \Imi\Redis\Enum\RedisMode::SENTINEL,
'master' => 'master 名称',
'nodes' => [
// 支持两种格式
// 格式一
'127.0.0.1:6379',
// 格式二
[
'host' => '127.0.0.1'
'port' => 6379,
],
],
'timeout' => null,
'retryInterval' => null,
'readTimeout' => null,

// --- 集群模式配置 ---
'mode' => \Imi\Redis\Enum\RedisMode::CLUSTER,
'seeds' => [
'127.0.0.1:6379',
'127.0.0.1:6380',
],
'name' => null,
'persistent' => null,
'timeout' => null,
'readTimeout' => null,
],
// uri资源配置,以分号;分隔多个,参数使用query参数格式,特殊字符需要转码
// 'resource' => 'tcp://192.168.0.222&timeout=60;tcp://192.168.0.222',
Expand Down
19 changes: 10 additions & 9 deletions src/Cache/Handler/RedisHash.php
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,8 @@ public function getMultiple($keys, $default = null)
static $script = <<<SCRIPT
local key = KEYS[1]
local result = {}
for i = 2, #KEYS do
table.insert(result, redis.call('hget', key, KEYS[i]))
for i = 1, #ARGV do
table.insert(result, redis.call('hget', key, ARGV[i]))
end
return result
SCRIPT;
Expand All @@ -152,7 +152,7 @@ public function getMultiple($keys, $default = null)
$evalResult = $redis->evalEx($script, array_merge(
[$key],
$members
), \count($members) + 1);
), 1);
$result = array_merge($result, $evalResult);
}

Expand Down Expand Up @@ -193,8 +193,9 @@ public function setMultiple($values, $ttl = null)
{
static $script = <<<SCRIPT
local key = KEYS[1]
for i = 2, #KEYS do
redis.call('hset', key, KEYS[i], ARGV[i - 1])
local halfLen = #ARGV / 2
for i = 1, halfLen do
redis.call('hset', key, ARGV[i], ARGV[halfLen + i])
end
return true
SCRIPT;
Expand All @@ -220,7 +221,7 @@ public function setMultiple($values, $ttl = null)
$result = Redis::use(function (\Imi\Redis\RedisHandler $redis) use ($script, $setValues) {
foreach ($setValues as $key => $item)
{
$result = false !== $redis->evalEx($script, array_merge([$key], $item['member'], $item['value']), \count($item['member']) + 1);
$result = false !== $redis->evalEx($script, array_merge([$key], $item['member'], $item['value']), 1);
if (!$result)
{
return $result;
Expand Down Expand Up @@ -248,8 +249,8 @@ public function deleteMultiple($keys)
{
static $script = <<<SCRIPT
local key = KEYS[1]
for i = 2, #KEYS do
redis.call('hdel', key, KEYS[i])
for i = 1, #ARGV do
redis.call('hdel', key, ARGV[i])
end
return true
SCRIPT;
Expand All @@ -269,7 +270,7 @@ public function deleteMultiple($keys)
$result = $redis->evalEx($script, array_merge(
[$key],
$members
), \count($members) + 1);
), 1);
if (!$result)
{
return $result;
Expand Down
36 changes: 33 additions & 3 deletions src/Components/queue/src/Driver/RedisQueueDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -581,22 +581,52 @@ protected function parseTimeoutMessages(int $count = 100): int
*/
public function getMessageKeyPrefix(): string
{
return $this->prefix . $this->name . ':message:';
$redis = RedisManager::getInstance($this->poolName);
if ($redis->isCluster())
{
$name = '{' . $this->name . '}';
}
else
{
$name = $this->name;
}

return $this->prefix . $name . ':message:';
}

/**
* 获取消息 ID 的键.
*/
public function getMessageIdKey(): string
{
return $this->prefix . $this->name . ':message:id';
$redis = RedisManager::getInstance($this->poolName);
if ($redis->isCluster())
{
$name = '{' . $this->name . '}';
}
else
{
$name = $this->name;
}

return $this->prefix . $name . ':message:id';
}

/**
* 获取队列的键.
*/
public function getQueueKey(int $queueType): string
{
return $this->prefix . $this->name . ':' . strtolower(QueueType::getName($queueType));
$redis = RedisManager::getInstance($this->poolName);
if ($redis->isCluster())
{
$name = '{' . $this->name . '}';
}
else
{
$name = $this->name;
}

return $this->prefix . $name . ':' . strtolower(QueueType::getName($queueType));
}
}
4 changes: 2 additions & 2 deletions src/Components/rate-limit/src/WorkerLimiterLock.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public static function lock(string $name, int $max, ?float $timeout, ?string $po
{
$now = microtime(true);
$args = [
$name, // 名称
'{' . $name . '}', // 名称
$max, // 最大允许数量
$now, // 当前时间
null === $timeout ? null : ($now + $timeout), // 过期时间
Expand Down Expand Up @@ -78,7 +78,7 @@ public static function lock(string $name, int $max, ?float $timeout, ?string $po
public static function unlock(string $name, int $workerId, ?string $poolName = null)
{
$args = [
$name, // 名称
'{' . $name . '}', // 名称
$workerId, // 任务ID
];
$numKeys = 1;
Expand Down
23 changes: 4 additions & 19 deletions src/Components/swoole/src/Redis/Pool/CoroutineRedisPool.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,38 +4,23 @@

namespace Imi\Swoole\Redis\Pool;

use Imi\App;
use Imi\Pool\TUriResourceConfig;
use Imi\Redis\RedisHandler;
use Imi\Redis\RedisResource;
use Imi\Redis\Traits\TRedisPool;
use Imi\Swoole\Pool\BaseAsyncPool;

class CoroutineRedisPool extends BaseAsyncPool
{
use TRedisPool;
use TUriResourceConfig;

/**
* 数据库操作类.
* Êý¾Ý¿â²Ù×÷Àà.
*/
protected string $handlerClass = \Redis::class;

public function __construct(string $name, \Imi\Pool\Interfaces\IPoolConfig $config = null, $resourceConfig = null)
public function __construct(string $name, ?\Imi\Pool\Interfaces\IPoolConfig $config = null, $resourceConfig = null)
{
parent::__construct($name, $config, $resourceConfig);
$this->initUriResourceConfig();
}

/**
* 创建资源.
*
* @return \Imi\Redis\RedisResource
*/
protected function createResource(): \Imi\Pool\Interfaces\IPoolResource
{
$config = $this->getNextResourceConfig();
$class = $config['handlerClass'] ?? $this->handlerClass;
$db = App::getBean(RedisHandler::class, new $class());

return new RedisResource($this, $db, $config);
}
}
14 changes: 7 additions & 7 deletions src/Lock/Handler/Redis.php
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,9 @@ protected function __tryLock(): bool
return ImiRedis::use(function (RedisHandler $redis): bool {
return 1 == $redis->evalEx(<<<SCRIPT
local key = KEYS[1]
local content = KEYS[2]
local ttl = ARGV[2]
local db = tonumber(ARGV[1])
local content = ARGV[1]
local ttl = ARGV[3]
local db = tonumber(ARGV[2])
if db then
redis.call('select', db)
end
Expand All @@ -117,7 +117,7 @@ protected function __tryLock(): bool
$this->guid,
$this->db,
$this->lockExpire,
], 2);
], 1);
}, $this->poolName, true);
}

Expand All @@ -129,8 +129,8 @@ protected function __unlock(): bool
return ImiRedis::use(function (RedisHandler $redis): bool {
return false !== $redis->evalEx(<<<SCRIPT
local key = KEYS[1]
local content = KEYS[2]
local db = tonumber(ARGV[1])
local content = ARGV[1]
local db = tonumber(ARGV[2])
if db then
redis.call('select', db)
end
Expand All @@ -144,7 +144,7 @@ protected function __unlock(): bool
$this->key,
$this->guid,
$this->db,
], 2);
], 1);
}, $this->poolName, true);
}
}
27 changes: 27 additions & 0 deletions src/Redis/Enum/RedisMode.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

declare(strict_types=1);

namespace Imi\Redis\Enum;

class RedisMode
{
/**
* 单机.
*/
public const STANDALONE = 'standalone';

/**
* 哨兵模式.
*/
public const SENTINEL = 'sentinel';

/**
* 集群模式.
*/
public const CLUSTER = 'cluster';

private function __construct()
{
}
}
Loading

0 comments on commit 9a8db03

Please sign in to comment.