Redis

Redis 是一个开源的, 先进的键-值存储库. 因其可存储 strings, hashes, lists, sets, 和 sorted sets, 又常常称为数据结构服务器.

Predis 是一个开源的PHP库. 相比phpredis, 虽然性能稍有劣式, 但贵在升级扩展都比较容易(redis还在快速发展中). 目前luckymallredis类依赖于predis库进行开发,所以不要安装php的redis扩展. 如果想深度玩玩可直接参考Predis文档Predis Wiki.

注意: redis服务, 需要3.0.x版本

注意: redis服务必须开启持久化存储,持久化策略请参考点击链接

注意: 目前不支持, PECL安装Redis的PHP扩展. 如果安装会因命名冲突, 导致系统问题

配置

你的应用的 Redis 默认配置位于 config/redis.php 配置文件中。 在安装时会默认拷贝到 config/production/redis.php中.

例如:

return [
    'connections' => [
        'default' => [
            'servers' => [
                'redis://127.0.0.1:6379',
            ]
        ],
    ],

    'scenes' => [
        'queue' => [
            'connection' => 'default',
        ],
    ],
];

存储场景(scenes)

Redis的Cluster策略是根据Key值做一致性hash. 但问题在于不同场景下对于redis的使用频率是不同的, 根据实际业务场景, 单一场景都需要进行cluster. 因此在设计上将场景剥离出来, 不同场景指定自己的 Connection.

return [
    //...
    'scenes' => [
        'queue' => [
            'connection' => 'default',
        ],
    ],
    //...
];

连接资源(connections)

connections 定义了服务器组, 默认的服务器配置应该足以供开发使用. 你可以依照自己的环境自由地修改这个数组。简单地为每组服务器指定名称,主机地址以及所使用的端口.

return [
    //...
    'connections' => [
        'default' => [
            'servers' => [
                redis://127.0.0.1:6379',
            ]
        ],
    ],
    //...
];

连接参数同时支持[URI字符串]和命名数组两种方式:

return [
    //...
    'connections' => [
        'default' => [
            'servers' => [
                'redis://username:password@127.0.0.1:6379/?database=0&timeout=5&alias=master',
                ['scheme' => 'tcp',
                 'host' => '127.0.0.1,
                 'port' => '6379',
                 'user' => 'username',
                 'password' => 'password',
                 'timeout' => 5,
                 'alias' => 'master',
                 'database' => 0],
            ]
        ],
    ],
    //...
];

参数可参见:

alias string 别名, 主要应用场景是在[Master slave模式](#master-slave)下
weight 权重, 当配置`cluster`配置为`predis`时, 会使用客户端的`一致性hash算法`进行分区. 权重在此时生效
database string 指定数据库, 不指定时默认为0
persistent bool 持续连接
read_write_timeout string 传输的过期时间
timeout string 连接过期时间

注意: 当系统安装时, 如果在单台机器安装多个BBC, 与mysqldatabase类似, 可以通过database参数指定不同的redis database.

每组服务器配置可以支持额外的options:

return [
    //...
    'connections' => [
        'default' => [
            'servers' => [
                redis://127.0.0.1:6379',
            'options' => [
                'cluster' => 'redis'
            ]
        ],
    ],
    //...
];
  • cluster: 选择用哪种集群方式, 目前支持predisredis方式. 默认为predis方式, 使用客户端的一致性hash算法进行分区. redis方案依赖redis服务redis-cluster配置.
  • replication: 设置使用什么方式的主/从方案.

长连接

Predis支持持久连接方案. 相关的参数有path, persistent, 同时需要设置options, 指定不同Schema对应的Connection. 目前持久连接方案默认只支持两种Connection, StreamConnectionCompositeStreamConnection, 其中CompositeStreamConnection主要是针对集群诉求.

return [
    //...
    'connections' => [
        'default' => [
            'servers' => [
                redis://127.0.0.1:6379?path=a1&persistent=1',
            'options' => [
                 'tcp' => 'Predis\Connection\StreamConnection',
                 'unix' => 'Predis\Connection\StreamConnection',
                 'redis' => 'Predis\Connection\StreamConnection',
            ]
        ],
    ],
    //...
];

合并连接(aggregate-connections)

Predis支持集群方案主/从方案的连接. 默认情况下, 使用客户端的一致性hash算法进行分区, 也可使用Redis服务所提供的方式 redis-cluster. 在主/从方案中, Predis支持一主多从的形式,并且在读取操作时连接从机,写操作时连接到主机。

主/从方案

客户端连接时可以进行主/从方案的配置. 配置好后, 当执行读取操作时会连接从机; 执行写操作时会连接主机. 实现读写分离.

下面是比较基础的主/从方案配置:

return [
    //...
    'connections' => [
        'default' => [
            'servers' => [
                // 主节点的参数需要设定`alias=master`
                'tcp://127.0.0.1:6379?alias=master',
                'tcp://127.0.0.1:6380?alias=slave-01',
            ],
            'options => [
                'replication' => true,
            ],
        ],
    ],
    //...
];

虽然 Predis 可以识别读/写操作,但 EVAL, EVALSHA 是两个特例。因为客户端不知道 LUA 脚本里是否有写操作,所以通常这两个操作是在 Master 上执行。 虽然这是个默认的行为,但有些 Lua 脚本里如果不包括写操作,客户端还是可能会在 slaves 上执行。可以通过配置来指定。

return [
    //...
    'connections' => [
        'default' => [
            'servers' => [
                // 主节点的参数需要设定`alias=master`
                'tcp://127.0.0.1:6379?alias=master',
                'tcp://127.0.0.1:6380?alias=slave-01',
            ],
            'options => [
                'replication' => function () {
                    // 强制指定为 slave 上执行,不切换到 master
                    $strategy = new Predis\Replication\ReplicationStrategy();
                    $strategy -> setScriptReadOnly($LUA_SCRIPT);

                    return new Predis\Connection\Aggregate\MasterSlaveReplication($strategy);
                }
            ],
        ],
    ],
    //...
];

集群方案

通过传递简单的和配置就可以实现集群功, 并且是在客户端的一致性hash算法进行分区. 但如果想使用 redis-cluster 功能(Redis 3.0 后的版本中可用). 可以如下配置:

return [
    //...
    'connections' => [
        'default' => [
            'servers' => [
                'tcp://127.0.0.1:6379',
                'tcp://127.0.0.1:6380',
            ],
            'options => [
                'cluster' => redis,
            ],
        ],
    ],
    //...
];

当使用 redis-cluster 时,不用把集群中所有的节点都在参数中传递进去,只需要传少数几个就可以了。Predis 会自动从某一台服务器上获取所有服务器的哈希映射图。

注意: 目前 Predis 还不支持 redis-cluster 中的 主/从 结构

基本用法

你可以通过redis facade调用许多方法来和redis交互. facade支持动态方法, 这意味着你可以通过facade调用任何 Redis命令 Redis命令中文版.

注意: 使用redis时, 必须制定场景(scene).


<?php redis::scene($scene)->get($key);

当然, 正如上面所提及的, 你可在 redis facade 上使用任意 Redis 命令. luckymall 使用魔术方法来向Redis服务器传递命令, 因此也可以简单地为 Redis 命令传递参数:


<?php $values = redis::lrange('names', 5, 10);

管道命令

当你需要在一个操作中发送许多命令时,应该使用管道。pipeline 方法接受一个参数:一个接收 Redis 实例的 Closure (闭包)。你可向这个Redis实例发布所有的命令,它们会在单一操作中全被执行:


redis::scene($scene)->pipeline(function ($pipe) { for ($i = 0; $i < 1000; $i++) { $pipe->set("key:$i", $i); } });

沪ICP备05002918号

© 2003-2017 ShopEx,Inc.All rights reserved.