pgpool-II 入门教程 [ 基于内存的查询缓存 ]

# 关于本文档

在本教程中，将讲解一个简单的方法来在共享内存中试用“基于内存的查询缓存”。

你需要的是一个安装有 PostgreSQL 和 pgpool-II 的 Linux 测试环境。你可以在任何模式中使用 基于内存的查询缓存：复制模式，主/备模式和原始模式。

返回顶部

# 基于内存的查询缓存

## 配置 pgpool.conf

### 基本参数

设置 "memory_cache_enabled" 为 on 以启用基于内存的查询缓存功能。

    # If on, use the memory cache functionality, off by default
    memory_cache_enabled = on

pgpool 会建立“OID 映射”文件，它用于指明哪个缓存用于哪个数据库和表。指定你希望用于这个用途的目录。

    # Temporary work directory to record table oids
    memqcache_oiddir = '/var/log/pgpool/oiddir'

### 关于共享内存

参数 "memqcache_method" 用于选择缓存的存储类型，默认为 "shmem"。

    # Cache storage method. either 'shmem'(shared memory) or 'memcached'. 'shmem' by default
    memqcache_method = 'shmem'

### 关于日志

参数 "log_per_node_statement" 可以帮助你了解某个查询是在哪个后端上执行。设置本参数为 on。

    log_per_node_statement = on
                                       # Log all statements
                                       # with node and backend informations

## 启动 pgpool

使用 "-n" 参数（表示以非守护进程模式）启动 pgpool-II 并重定向日志消息到 pgpool.log 中。

    $ {installed_dir}/bin/pgpool -n -f {installed_dir}/etc/pgpool.conf > pgpool.log 2>&1

建立数据库和表。

    $ createdb -p 9999 test

    $ psql -p 9999 test
    test=> CREATE TABLE table_cache_ok (a INT);
    CREATE TABLE

    test=> INSERT INTO table_cache_ok VALUES (1), (2), (3);
    INSERT 0 3

    test=> SELECT * FROM table_cache_ok ORDER BY a;
     a
    ---
     1
     2
     3
    (3 rows)

## 试用查询缓存

执行一个 SELECT 语句。

    test=> SELECT * FROM table_cache_ok WHERE a = 1;
     a
    ---
     1
    (1 row)

log_per_node_statement 的输出显示 SELECT 语句被实际执行了。

    LOG:   DB node id: 0 backend pid: 11203 statement: SELECT * FROM table_cache_ok WHERE a = 1;

再次执行相同的 SELECT 语句。

    test=> SELECT * FROM table_cache_ok WHERE a = 1;
     a
    ---
     1
    (1 row)

这次日志消息显示 SELECT 语句的结果来源于缓存。

    LOG:   query result fetched from cache. statement: SELECT * FROM table_cache_ok WHERE a = 1;

返回顶部

# 查询缓存的更多内容

## 自动失效

### 当一个表被更新

当一个表被更新，这个表中缓存的 SELECT 的结果会过期。 pgpool 默认情况下会自动忽略那个表上的所有缓存。

#### 配置

通过 "memqcache_auto_cache_invalidation" 指定动作。它的默认值是 "on"。

    # If on, invalidation of query cache is triggered by corresponding
    # DDL/DML/DCL(and memqcache_expire).  If off, it is only triggered
    # by memqcache_expire.  on by default.
    memqcache_auto_cache_invalidation = on

修改这个参数的值后，重启 pgpool。

#### 尝试自动失效的效果

确认你可以从缓存中获得 SELECT 语句的结果。

    test=> SELECT * FROM table_cache_ok WHERE a = 1;
    LOG:   query result fetched from cache. statement: SELECT * FROM table_cache_ok WHERE a = 1;

在这个表中执行 INSERT INTO 。

    test=> INSERT INTO table_cache_ok VALUES (5);
    INSERT 0 1

再次执行相同的 SELECT 语句，这条 SELECT 语句被实际执行。

    test=> SELECT * FROM table_cache_ok WHERE a = 1;
    LOG:   DB node id: 0 backend pid: 11203 statement: SELECT * FROM table_cache_ok WHERE a = 1;

### 缓存过期

pgpool 会忽略比指定过期周期更旧的缓存。

#### 配置

通过 "memqcache_expire" 指定过期周期。默认为 0 秒，不过为了测试我们在这里设置为 5 秒。

    # Memory cache entry life time specified in seconds.
    # 0 means infinite life time. 0 by default.
    memqcache_expire = 5

修改这个参数的值后，重启 pgpool。

#### Try

确认你可以从缓存中获得 SELECT 语句的结果。

    test=> SELECT * FROM table_cache_ok WHERE a = 1;
    LOG:   query result fetched from cache. statement: SELECT * FROM table_cache_ok WHERE a = 1;

等 5 秒钟...

再次执行相同的 SELECT 语句，这条 SELECT 语句被实际执行。

    test=> SELECT * FROM table_cache_ok WHERE a = 1;
    LOG:   DB node id: 0 backend pid: 11203 statement: SELECT * FROM table_cache_ok WHERE a = 1;

## 白名单和黑名单

### 只缓存某些表的结果

#### 配置

如果你只想缓存某些表的结果，可以通过 "white_memqcache_table_list" 指定。

可以使用正则表达式（会自动添加 ^ 和 $）。

    white_memqcache_table_list = '.*_cache_ok'
                                       # Comma separated list of table names to memcache
                                       # that don't write to database
                                       # Regexp are accepted

修改这个参数的值后，重新加载配置文件。

    $ {installed_dir}/bin/pgpool reload

#### 尝试

建立一个不需要缓存的表

    $ psql -p 9999 test
    test=> CREATE TABLE table_cache_ng (a INT);
    CREATE TABLE

    test=> INSERT INTO table_cache_ng VALUES (1), (2), (3);
    INSERT 0 3

确认是否 SELECT FROM 在 white_memqcache_table_list 中的表被缓存。

    test=> SELECT * FROM table_cache_ok WHERE a = 1;
    LOG:   DB node id: 0 backend pid: 11203 statement: SELECT oid FROM pg_database WHERE datname = 'test'

    test=> SELECT * FROM table_cache_ok WHERE a = 1;
    LOG:   query result fetched from cache. statement: SELECT * FROM table_cache_ok WHERE a = 1;

确认是否 SELECT FROM 不在 white_memqcache_table_list 中的表不被缓存。

    test=> SELECT * FROM table_cache_ng WHERE a = 1;
    LOG:   DB node id: 0 backend pid: 11203 statement: SELECT * FROM table_cache_ok WHERE a = 1;

    test=> SELECT * FROM table_cache_ng WHERE a = 1;
    LOG:   DB node id: 0 backend pid: 11203 statement: SELECT * FROM table_cache_ok WHERE a = 1;

### 不缓存某些表的结果

#### Config

如果你不想缓存某些表的结果，可以通过 "black_memqcache_table_list" 指定。

可以使用正则表达式（会自动添加 ^ 和 $）。

    black_memqcache_table_list = '.*_cache_ng'
                                       # Comma separated list of table names not to memcache
                                       # that don't write to database
                                       # Regexp are accepted

修改这个参数的值后，重新加载配置文件。

    $ {installed_dir}/bin/pgpool reload

#### Try

确认是否 SELECT FROM 在 black_memqcache_table_list 中的表不被缓存。

    test=> SELECT * FROM table_cache_ng WHERE a = 1;
    LOG:   DB node id: 0 backend pid: 11203 statement: SELECT * FROM table_cache_ok WHERE a = 1;

    test=> SELECT * FROM table_cache_ng WHERE a = 1;
    LOG:   DB node id: 0 backend pid: 11203 statement: SELECT * FROM table_cache_ok WHERE a = 1;

确认是否 SELECT FROM 不在 black_memqcache_table_list 中的表被缓存。

    test=> SELECT * FROM table_cache_ok WHERE a = 1;
    LOG:   DB node id: 0 backend pid: 11203 statement: SELECT oid FROM pg_database WHERE datname = 'test'

    test=> SELECT * FROM table_cache_ok WHERE a = 1;
    LOG:   query result fetched from cache. statement: SELECT * FROM table_cache_ok WHERE a = 1;

## 还有什么内容？

### 太大的结果集

SELECT 的结果集的大小会受限于 "memqcache_maxcache"。

    # Maximum SELECT result size in bytes.
    # Must be smaller than memqcache_cache_block_size. Defaults to 400KB.
    memqcache_maxcache = 409600

如果结果集大于 memqcache_maxcache，日志信息会告诉我们。 以下是一个示例，memqcache_maxcache 被设置为 1024 字节而 SELECT 出来的表的大小超过 10 MB。

    LOG:   DB node id: 0 backend pid: 17749 statement: SELECT * FROM pgbench_accounts ;
    LOG:   pool_add_temp_query_cache: data size exceeds memqcache_maxcache.
                                      current:983 requested:110 memq_maxcache:1024

### 指定某个查询不需要缓存

如果白名单和黑名单还不够用，可以在查询最开始的地方 put the text "/* NO QUERY CACHE */" at the head of the queries.

    LOG:   statement: SELECT * FROM table_cache_ok WHERE a = 1;
    LOG:   query result fetched from cache. statement: SELECT * FROM table_cache_ok WHERE a = 1;

    LOG:   statement: /* NO QUERY CACHE */ SELECT * FROM table_cache_ok WHERE a = 1;
    LOG:   DB node id: 0 backend pid: 18070 statement: /* NO QUERY CACHE */ SELECT * FROM table_cache_ok WHERE a = 1;
    LOG:   statement: /* NO QUERY CACHE */ SELECT * FROM table_cache_ok WHERE a = 1;
    LOG:   DB node id: 0 backend pid: 18070 statement: /* NO QUERY CACHE */ SELECT * FROM table_cache_ok WHERE a = 1;

当然，这种方法需要修改你的程序。

返回顶部

<copyright> Copyright © 2003 – 2013 pgpool Global Development Group </copyright>