数据库

Redis


Redis 是一种开源的内存存储,用作分布式、内存中的键值数据库、缓存和消息代理,并可选择持久化。

Redis Wrapper 允许您在 Postgres 数据库中读取 Redis 中的数据。

准备#

在查询 Redis 之前,您需要启用 Wrappers 扩展并在 Postgres 中存储您的凭据。

启用 Wrappers#

确保 wrappers 扩展已安装在您的数据库上

1
create extension if not exists wrappers with schema extensions;

启用 Redis Wrapper#

启用 redis_wrapper FDW

1
create foreign data wrapper redis_wrapper
2
handler redis_fdw_handler
3
validator redis_fdw_validator;

存储您的凭据(可选)#

默认情况下,Postgres 将 FDW 凭据以明文形式存储在 pg_catalog.pg_foreign_server 中。任何访问此表的人都可以查看这些凭据。Wrappers 旨在与 Vault 配合使用,Vault 为存储凭据提供额外的安全级别。我们建议使用 Vault 存储您的凭据。

1
-- Save your Redis connection URL in Vault and retrieve the created `key_id`
2
select vault.create_secret(
3
'redis://username:password@127.0.0.1:6379/db',
4
'redis',
5
'Redis connection URL for Wrappers'
6
);

连接到 Redis#

我们需要向 Postgres 提供连接到 Redis 的凭据。我们可以使用 create server 命令来执行此操作

1
create server redis_server
2
foreign data wrapper redis_wrapper
3
options (
4
conn_url_id '<key_ID>' -- The Key ID from above.
5
);

创建模式#

我们建议创建一个模式来保存所有外部表

1
create schema if not exists redis;

选项#

创建 Redis 外表时,可用的选项如下

  • src_type - Redis 中的外表源类型,必需。

它可以是以下类型之一:

源类型描述
list单个列表
set单个集合
hash单个哈希
zset单个排序集合
streamStream
multi_list多个列表,由 src_key 模式指定
multi_set多个集合,由 src_key 模式指定
multi_hash多个哈希,由 src_key 模式指定
multi_zset多个排序集合,由 src_key 模式指定
  • src_key - Redis 中的源对象键,必需。

对于 multi_* 类型的外部表,此键可以是模式。对于其他类型,此键必须返回确切的一个值。例如,

源类型src_key 示例
list, set, hash, zset, streammy_list, list:001, hash_foo, zset:1000 等。
multi_list, multi_set, multi_hash, multi_zsetmy_list:*, set:*, zset:* 等。

实体#

List#

这是一个代表 Redis List 的对象。

参考:Redis 文档

操作#

对象选择插入更新删除截断
List

用法#

1
create foreign table redis.list (
2
element text
3
)
4
server redis_server
5
options (
6
src_type 'list',
7
src_key 'my_list'
8
);

说明#

  • 元素按插入顺序存储
  • 查询返回列表中的所有元素
  • 不支持查询推送

Set#

这是一个代表 Redis Set 的对象。

参考:Redis 文档

操作#

对象选择插入更新删除截断
Set

用法#

1
create foreign table redis.set (
2
element text
3
)
4
server redis_server
5
options (
6
src_type 'set',
7
src_key 'set'
8
);

说明#

  • 集合内的元素是唯一的
  • 元素顺序没有保证
  • 不支持查询推送

Hash#

这是一个代表 Redis Hash 的对象。

参考:Redis 文档

操作#

对象选择插入更新删除截断
Hash

用法#

1
create foreign table redis.hash (
2
key text,
3
value text
4
)
5
server redis_server
6
options (
7
src_type 'hash',
8
src_key 'hash'
9
);

说明#

  • 哈希内的键值对
  • 不支持查询推送
  • 键和值都作为文本返回

Sorted Set#

这是一个代表 Redis Sorted Set 的对象。

参考:Redis 文档

Operations#

对象选择插入更新删除截断
Sorted Set

Usage#

1
create foreign table redis.zset (
2
element text
3
)
4
server redis_server
5
options (
6
src_type 'zset',
7
src_key 'zset'
8
);

Notes#

  • 元素按其分数排序
  • 集合内的元素是唯一的
  • 分数信息未在外部表中公开

Stream#

这是一个代表 Redis Stream 的对象。

参考:Redis 文档

操作#

对象选择插入更新删除截断
Stream

用法#

1
create foreign table redis.stream (
2
id text,
3
items jsonb
4
)
5
server redis_server
6
options (
7
src_type 'stream',
8
src_key 'stream'
9
);

说明#

  • Stream 条目具有唯一的 ID
  • 项目以 JSONB 格式存储
  • 条目按其 ID 排序

多个对象#

Redis wrapper 支持使用模式匹配查询相同类型的多个对象。

操作#

对象类型选择插入更新删除截断
多个列表
多个集合
多个哈希
多个 ZSet

用法#

1
create foreign table redis.multi_lists (
2
key text,
3
items jsonb
4
)
5
server redis_server
6
options (
7
src_type 'multi_list',
8
src_key 'list:*'
9
);

说明#

  • src_key 选项中使用模式匹配
  • 结果包括对象键和 JSONB 格式的项目
  • 项目格式因对象类型而异

查询下推支持#

此 FDW 不支持推送。

支持的 Redis 数据类型#

所有 Redis 值都将作为 Postgres 中的 textjsonb 列存储,以下是支持的 Redis 数据类型

Redis 类型外部表类型 (src_type)
Listlist
Setset
Hashhash
Sorted Setzset
Streamstream
多个列表multi_list
多个集合multi_set
多个哈希multi_hash
多个排序集合multi_zset

限制#

本节描述了在使用此 FDW 时需要注意的重要限制和注意事项

  • 在处理之前,完整的结果集将加载到内存中
  • 只读访问 Redis 数据结构(无插入、更新、删除或截断操作)
  • multi_* 类型中的模式匹配仅支持基本的 Redis glob 模式
  • 使用这些外部表的物化视图在逻辑备份期间可能会失败

示例#

一些关于如何使用 Redis 外部表的示例。

让我们先在 Redis CLI 中准备一些源数据

1
127.0.0.1:6379> RPUSH list foo bar 42
2
127.0.0.1:6379> SADD set foo bar 42
3
127.0.0.1:6379> HSET hash foo bar baz qux
4
127.0.0.1:6379> ZADD zset 30 foo 20 bar 10 baz
5
127.0.0.1:6379> XADD stream * foo bar
6
127.0.0.1:6379> XADD stream * aa 42 bb 43
7
8
127.0.0.1:6379> RPUSH list:100 foo bar
9
127.0.0.1:6379> RPUSH list:200 baz
10
11
127.0.0.1:6379> SADD set:100 foo
12
127.0.0.1:6379> SADD set:200 bar
13
14
127.0.0.1:6379> HSET hash:100 foo bar
15
127.0.0.1:6379> HSET hash:200 baz qux
16
17
127.0.0.1:6379> ZADD zset:100 10 foo 20 bar
18
127.0.0.1:6379> ZADD zset:200 40 baz 30 qux

基本示例#

此示例将在您的 Postgres 数据库中创建外部表并查询其数据

  • List

    1
    create foreign table redis.list (
    2
    element text
    3
    )
    4
    server redis_server
    5
    options (
    6
    src_type 'list',
    7
    src_key 'list'
    8
    );
    9
    10
    select * from redis.list;

    查询结果

    1
    element
    2
    ---------
    3
    foo
    4
    bar
    5
    42
    6
    (3 rows)
  • Set

    1
    create foreign table redis.set (
    2
    element text
    3
    )
    4
    server redis_server
    5
    options (
    6
    src_type 'set',
    7
    src_key 'set'
    8
    );
    9
    10
    select * from redis.set;

    查询结果

    1
    element
    2
    ---------
    3
    42
    4
    foo
    5
    bar
    6
    (3 rows)
  • Hash

    1
    create foreign table redis.hash (
    2
    key text,
    3
    value text
    4
    )
    5
    server redis_server
    6
    options (
    7
    src_type 'hash',
    8
    src_key 'hash'
    9
    );
    10
    11
    select * from redis.hash;

    查询结果

    1
    key | value
    2
    -----+-------
    3
    foo | bar
    4
    baz | qux
    5
    (2 rows)
  • 排序集合

    1
    create foreign table redis.zset (
    2
    element text
    3
    )
    4
    server redis_server
    5
    options (
    6
    src_type 'zset',
    7
    src_key 'zset'
    8
    );
    9
    10
    select * from redis.zset;

    查询结果

    1
    element
    2
    ---------
    3
    baz
    4
    bar
    5
    foo
    6
    (3 rows)
  • Stream

    1
    create foreign table redis.stream (
    2
    id text,
    3
    items jsonb
    4
    )
    5
    server redis_server
    6
    options (
    7
    src_type 'stream',
    8
    src_key 'stream'
    9
    );
    10
    11
    select * from redis.stream;

    查询结果

    1
    id | items
    2
    -----------------+--------------------------
    3
    1704343825989-0 | {"foo": "bar"}
    4
    1704343829799-0 | {"aa": "42", "bb": "43"}
    5
    (2 rows)

查询多个对象示例#

此示例将使用模式在键中创建多个外部表,并从 Redis 查询多个对象

  • List

    1
    create foreign table redis.multi_lists (
    2
    key text,
    3
    items jsonb
    4
    )
    5
    server redis_server
    6
    options (
    7
    src_type 'multi_list',
    8
    src_key 'list:*'
    9
    );
    10
    11
    select * from redis.multi_lists;

    查询结果

    1
    key | items
    2
    ----------+----------------
    3
    list:100 | ["foo", "bar"]
    4
    list:200 | ["baz"]
    5
    (2 rows)
  • Set

    1
    create foreign table redis.multi_sets (
    2
    key text,
    3
    items jsonb
    4
    )
    5
    server redis_server
    6
    options (
    7
    src_type 'multi_set',
    8
    src_key 'set:*'
    9
    );
    10
    11
    select * from redis.multi_sets;

    查询结果

    1
    key | items
    2
    ---------+---------
    3
    set:100 | ["foo"]
    4
    set:200 | ["bar"]
    5
    (2 rows)
  • Hash

    1
    create foreign table redis.multi_hashes (
    2
    key text,
    3
    items jsonb
    4
    )
    5
    server redis_server
    6
    options (
    7
    src_type 'multi_hash',
    8
    src_key 'hash:*'
    9
    );
    10
    11
    select * from redis.multi_hashes;

    查询结果

    1
    key | items
    2
    ----------+----------------
    3
    hash:200 | {"baz": "qux"}
    4
    hash:100 | {"foo": "bar"}
    5
    (2 rows)
  • 排序集合

    1
    create foreign table redis.multi_zsets (
    2
    key text,
    3
    items jsonb
    4
    )
    5
    server redis_server
    6
    options (
    7
    src_type 'multi_zset',
    8
    src_key 'zset:*'
    9
    );
    10
    11
    select * from redis.multi_zsets;

    查询结果

    1
    key | items
    2
    ----------+----------------
    3
    zset:200 | ["qux", "baz"]
    4
    zset:100 | ["foo", "bar"]
    5
    (2 rows)