averias/phpredis-bloom

使用 phpredis 扩展的 RedisBloom 模块 PHP 客户端

1.2.2 2021-01-03 15:57 UTC

README

Test Coverage Maintainability Build Status Packagist Version GitHub

PhpRedisBloom

PhpRedisBloom

PHP 客户端用于 RedisLab/RedisBloom 模块,它是 Redis 核心的概率数据结构扩展。

目录

简介

PhpRedisBloom 提供了 RedisBloom 模块 的完整命令集,并在 phpredis 的基础上构建,使用它作为 Redis 客户端,因此您也可以利用一些 phpredis 作为 Redis 客户端所包含的功能。

要求

  • Redis 服务器 4.0+ 版本(Redis 模块仅在 Redis 4.0+ 中可用)
  • 按照 构建和运行 中指定的方式在 Redis 服务器上安装 RedisBloom 模块
  • PHP 7.2+,已安装 PHP Redis 扩展 5

用法

客户端

执行 PhpRedisBloom 命令有两种方式

使用 RedisBloomClient 执行命令

use Averias\RedisBloom\Factory\RedisBloomFactory;

// instantiate a RedisBloomClient from RedisBloomFactory with default connection options
$factory = new RedisBloomFactory();
$client = $factory->createClient();

// then you can execute whatever redis bloom command for each of the 4 data types
$result = $client->bloomFilterAdd('filter-key', 'item-15');

使用 RedisBloom 数据类型类(Bloom 过滤器、Cuckoo 过滤器、Count-Min Sketch 和 Top-K)执行命令

// example for BloomFilter data types class
use Averias\RedisBloom\Factory\RedisBloomFactory;

// instantiate a BloomFilter class from RedisBloomFactory with default connection options
$factory = new RedisBloomFactory();
$bloomFilter = $factory->createBloomFilter('filter-key');

// then you can execute whatever Bloom Filter command on 'filter-key' filter
// adding one item to Bloom Filter 'filter-key'
$result = $bloomFilter->add('item1'); // returns true

// adding 2 items more to Bloom Filter 'filter-key'
$result = $bloomFilter->multiAdd('item2', 15); // returns and array [true, true]

// checking if item 'item1' exists in 'filter-key' Bloom Filter
$result = $bloomFilter->exists('item1'); // returns true

// adding one item more
$result = $bloomFilter->add(17.2); // returns true

// checking if a list items exist in 'filter-key' Bloom Filter
$result = $bloomFilter->multiExists('item1', 15, 'foo'); // returns and array [true, true, false] since 'foo' doesn't exists 

项目

只能添加或插入字符串、整数和浮点数作为 4 个数据结构的唯一项值,但请注意,所有项目都存储为字符串,因此添加整数 13 或字符串 13 将产生相同的结果。对于允许插入重复项的数据结构(如 Cuckoo 过滤器),它将增加该项的计数或在不允许插入重复项的结构中在第二次插入时失败。

浮点数也有相同的行为,首先插入一个浮点数 17.2,然后插入其字符串表示 17.2,将在第二次插入时在不允许重复项的 Bloom 过滤器中抛出异常,在 Cuckoo 过滤器、Count-Min Sketch 和 Top-k 中,第二次插入后计数器将增加到 2。

您可以查看 examples/inserting-numbers.php 中的示例以了解此行为。

为什么要有 RedisBloomClient 和每个 RedisBloom 数据类型的类?

  • RedisBloomClient 允许您在不同的过滤器上执行任何 RedisBloom 命令(Bloom 过滤器、Cuckoo 过滤器、Mins-Sketch 和 Top-K 命令),也可以执行 Redis 命令和原始 Redis 命令。因此,它是一个通用客户端,当您需要管理不同的过滤器和键或甚至想要执行正常的 Redis 命令时推荐使用。
  • RedisBloom 数据类型类(Bloom 过滤器、Cuckoo 过滤器、Mins-Sketch 和 Top-K 类)仅执行属于该数据类型的命令,并且仅在单个过滤器上执行。当您需要管理单个过滤器时,它们非常有用。

自动连接、断开和重新连接

RedisBloomClient 和 Redis Bloom 数据类型在创建后会自动连接到 Redis,您可以通过调用其 disconnect 方法从 Redis 实例断开它们

$client->disconnect()

$bloomFilter->disconnect()

这将返回 true 或 false,具体取决于断开连接是否成功。

在成功断开一次连接后,如果重新使用对象发送更多命令,客户端或数据类型对象将自动重新连接(请参见下面的示例)

代码示例

以下代码片段展示了如何使用不同的连接配置实例化RedisBloom客户端和BloomFilter数据类型

<?php

use Averias\RedisBloom\Enum\Connection;
use Averias\RedisBloom\Factory\RedisBloomFactory;

require(dirname(__DIR__).'/vendor/autoload.php');

const EXAMPLE_FILTER = 'example-filter';

/**
 * Default connection params:
 * [
 *     'host' => '127.0.0.1',
 *     'port' => 6379,
 *     'timeout' => 0.0, // seconds
 *     'retryInterval' => 15 // milliseconds
 *     'readTimeout' => 2, // seconds
 *     'persistenceId' => null // string for persistent connections, null for no persistent ones
 *     'database' => 0 // Redis database index [0..15]
 * ]
 *
 * you can create a factory with default connection by not passing any param in the constructor
 * $defaultFactory = new RedisBloomFactory();
 */

// create a factory with default connection but pointing to database 15
$factoryDB15 = new RedisBloomFactory([Connection::DATABASE => 15]);

// it creates a RedisBloomClient with same default connection configuration as specified in factory above
$clientDB15 = $factoryDB15->createClient();

// using the same factory you can create a BloomFilter object pointing 
// to database 14 and filter name = 'example-filter'
$bloomFilterDB14 = $factoryDB15->createBloomFilter(EXAMPLE_FILTER, [Connection::DATABASE => 14]);

// add 'item-15' to 'example-filter' bloom filter on database 15
$clientDB15->bloomFilterAdd(EXAMPLE_FILTER, 'item-15');

// add 'item-14' to 'example-filter' bloom filter on database 14
$bloomFilterDB14->add('item-14');

// disconnect
$bloomFilterDB14->disconnect();

// create another RedisBloomClient pointing to database 14
$clientDB14 = $factoryDB15->createClient([Connection::DATABASE => 14]);

$result = $clientDB15->bloomFilterExists(EXAMPLE_FILTER, 'database15'); //true
$result = $clientDB15->bloomFilterExists(EXAMPLE_FILTER, 'database14'); // false

$result = $clientDB14->bloomFilterExists(EXAMPLE_FILTER, 'database15'); // false
$result = $clientDB14->bloomFilterExists(EXAMPLE_FILTER, 'database14'); // true

// delete bloom filter on database 15
$clientDB15->executeRawCommand('DEL', EXAMPLE_FILTER);

// delete bloom filter on database 14
$clientDB14->del(EXAMPLE_FILTER);

// disconnect

$clientDB15->disconnect();
$clientDB14->disconnect();

// automatic reconnection
$bloomFilterDB14->add('reconnected');
$exist = $bloomFilterDB14->exists('reconnected'); //true
$bloomFilterDB14->disconnect();

命令

PhpRedisBloom 命令

phpredis-bloom提供了四个RedisBloom数据类型的所有命令,请点击以下链接获取每个类型的详细信息

Phpredis 命令

您可以按照phpredis文档中指定的方式发送Redis命令(见内容表

原始命令

您可以使用RedisBloomClient::executeRawCommand发送任何您想发送到Redis的内容

use Averias\RedisBloom\Enum\BloomCommands;

// raw Redis Bloom command
$client->executeRawCommand(BloomCommands::BF_ADD, 'filter-name', 'value');

// raw Redis command
$client->executeRawCommand('hget', 'hash-key', 'foo');

测试

在本地 Redis 服务器 4.0+ 上,安装了 RedisBloom 模块和 Redis 扩展 5

从控制台运行以下命令,该命令位于此项目的根目录下

./vendor/bin/phpunit

如果您尚未配置本地的Redis服务器在127.0.0.1:6379上,您可以在运行上述命令之前,在./phpunit.xml文件中设置REDIS_TEST_SERVERREDIS_TEST_PORTREDIS_TEST_DATABASE,使用您本地的Redis主机、端口和数据库名

Docker

如果已安装Docker,请在项目的根目录下运行以下命令

bash run-tests-docker.sh

通过运行上述bash脚本,将构建两个Docker服务:一个带有PHP 7.2和启用xdebug及redis扩展的容器,另一个使用redislab\rebloom:2.0.3镜像(Redis服务器5,已安装RedisBloom模块)。然后,测试将在phpredis-bloom Docker服务容器内运行,最后将停止两个容器。

示例

许可证

PhpRedisBloom代码采用MIT许可证分发,请参阅LICENSE文件