MySQL InnoDB memcached插件

InnoDB memcached插件
InnoDB memcached插件(daemon_memcached)提供了一个集成的memcached守护进程,可以自动存储和检索InnoDB表中的数据,将MySQL服务器变成一个快速的“key value store”。您可以使用简单的get、set和incr操作来避免与SQL解析和构造查询优化计划相关的性能开销,而不是在SQL 中制定查询。您还可以通过SQL访问相同的InnoDB表,以获得便利性,复杂的查询,批量操作以及传统数据库软件的其他优势。

这个“nosql-style”的接口使用memcached API来加速数据库操作,让InnoDB使用其缓冲池机制处理内存缓存。在InnoDB表中,通过memcached操作(如add、set和incr)修改的数据被存储在磁盘中。

InnoDB memcached插件的好处
下面概述daemon_memcached插件的优点。InnoDB表和memcached的组合比单独使用任何一个都有优势。
.直接访问InnoDB存储引擎避免了SQL的解析和规划开销。

.在与MySQL服务器相同的进程空间中运行memcached可以避免来回传递请求的网络开销。

.使用memcached协议写入的数据被透明地写入到InnoDB表中,而不需要经过MySQL SQL层。更新非关键数据时,可以通过控制写频率来获得更高的原始性能。

.通过memcached协议请求的数据可以透明地从InnoDB表中查询,而无需经过MySQL SQL层。

.对相同数据的后续请求由InnoDB缓冲池提供。缓冲池处理内存中的缓存。您可以使用InnoDB配置选项来调优数据密集型操作的性能。

.根据应用程序的类型,数据可以是非结构化的,也可以是结构化的。您可以为数据创建一个新表,也可以使用现有的表。

.InnoDB可以将多个列值组合和分解为单个memcached项值,从而减少应用程序中需要解析和连接字符串的数量。例如,你可以将字符串值2|4| 6|8存储在memcached缓存中,并让InnoDB根据分隔符分割该值,然后将结果存储在4个数值列中。

.内存和磁盘之间的传输是自动处理的,简化了应用程序逻辑。

.数据存储在MySQL数据库中,以防止崩溃、中断和损坏。

.你可以通过SQL访问底层的InnoDB表,用于报告、分析、即席查询、批量加载、多步事务计算、集合操作(如union和intersection),以及其他适合SQL表现力和灵活性的操作。

.可以在主服务器上使用daemon_memcached插件并结合MySQL复制来确保高可用性。

.memcached与MySQL的集成提供了一种持久化内存数据的方法,这样您就可以将它用于更重要的数据类型。您可以在应用程序中使用更多的add、incr和类似的写操作,而不必担心数据可能丢失。您可以停止和启动memcached服务器,而不会丢失对缓存数据的更新。为了防止意外的中断,你可以利用InnoDB的崩溃恢复、复制和备份功能。

.InnoDB快速主键查找的方式非常适合memcached的单元素查询。daemon_memcached插件使用的直接、低级数据库访问路径对于键值查找来说比等价的SQL查询要高效得多。

.memcached的序列化特性可以将复杂的数据结构、二进制文件甚至代码块转换为可存储的字符串,它提供了一种将此类对象放入数据库的简单方 法。

.因为可以通过SQL访问底层数据,所以可以生成报告、跨多个键进行搜索或更新,并在memcached数据上调用AVG()和MAX()等函数。使用 memcached所有这些操作都是昂贵或复杂的。

.不需要在启动时手动将数据加载到memcached中。当应用程序请求特定的键时,值会自动从数据库中检索出来,并使用InnoDB缓冲池缓存在内存 中。

.因为memcached消耗的CPU相对较少,而且它的内存占用很容易控制,所以它可以在同一个系统上与MySQL实例一起轻松运行。

.因为数据一致性是由常规InnoDB表使用的机制强制执行的,所以你不必担心memcached数据过期,或者在缺少键的情况下查询数据库的回滚逻辑 。

InnoDB memcached架构
InnoDB memcached插件将memcached作为一个MySQL插件守护进程来实现直接访问InnoDB存储引擎,绕过MySQL SQL层。

daemon_memcached插件的特性:
.Memcached作为mysqld的守护程序插件。mysqld和memcached都运行在相同的进程空间中,对数据的访问延迟非常低。

.直接访问InnoDB表,绕过SQL解析器,优化器,甚至Handler API层。

.标准memcached协议,包括基于文本的协议和二进制协议。daemon_memcached插件通过memcapable命令的所有55个兼容性测试。

.多列支持。您可以将多个列映射到键/值存储的“值”部分,列值由用户指定的分隔符分隔。

.默认情况下,memcached协议用于直接向InnoDB读取和写入数据,让MySQL使用InnoDB缓冲池管理内存缓存。默认设置代表了高可靠性和数据库 应用程序最少意外的组合。例如,默认设置避免在数据库端提交未提交的数据,或者为memcached get请求返回过时的数据。

.高级用户可以将系统配置为传统的memcached服务器,所有数据只缓存在memcached引擎(内存缓存)中,或者使用“memcached引擎”(内存缓存) 和InnoDB memcached引擎(InnoDB作为后端持久存储)的组合。

.通过innodb_api_bk_commit_interval、daemon_memcached_r_batch_size和daemon_memcached_w_batch_size配置选项来控制数据在InnoDB和 memcached操作之间来回传递的频率。批量大小选项的默认值为1,表示最大可靠性。

.通过daemon_memcached_option配置参数指定memcached选项的能力。例如,您可以更改memcached监听的端口,减少最大同时连接数,更改键值 对的最大内存大小,或打开错误日志的调试消息。

.innodb_api_trx_level配置选项控制memcached处理的查询的事务隔离级别。尽管memcached没有事务的概念,但是您可以使用这个选项来控制 memcached对daemon_memcached插件使用的表发出的SQL语句所引起的更改的处理速度。默认情况下,innodb_api_trx_level设置为READ UNCOMMITTED。

.innodb_api_enable_mdl选项可以用来在MySQL级别锁定表,这样映射的表就不能被DDL通过SQL接口删除或修改。如果没有锁,表可以从MySQL层 删除,但仍然保留在InnoDB存储中,直到memcached或其他用户停止使用它。MDL代表“元数据锁定”。

InnoDB memcached与传统memcached的区别
您可能已经熟悉在MySQL中使用memcached,如使用MySQL与memcached中所述。本节描述集成的InnoDB memcached插件与传统memcached的不同之 处。
.安装: memcached库随MySQL服务器一起提供,使得安装和设置相对容易。安装过程中需要运行innodb_memcached_config.sql脚本创建一个 demo_test表供memcached使用,发出INSTALL PLUGIN语句以启用daemon_memcached插件,并将所需的memcached选项添加到MySQL配置文件或启动 脚本中。对于memcp、memcat和memcapable等其他实用程序,您可能仍然需要安装传统的memcached发行版。

.部署:对于传统的memcached,通常会运行大量低容量的memcached服务器。但是,典型的daemon_memcached插件部署只涉及少量已经在运行 MySQL的中等或高性能服务器。这种配置的好处是提高了单个数据库服务器的效率,而不是利用未使用的内存或在大量服务器上分布查找。在默 认配置中,memcached只使用很少的内存,而内存中的查找是从InnoDB缓冲池中提供的,它会自动缓存最新和频繁使用的数据。与传统的MySQL服 务器实例一样,保持innodb_buffer_pool_size配置选项的值尽可能高(不引起操作系统级别的分页),以便尽可能多的工作在内存中.终止执行。

.过期:默认情况下(即使用innodb_only缓存策略),总是返回InnoDB表中最新的数据,因此过期选项没有实际作用。如果将缓存策略更改为缓存 或仅缓存,则过期选项照常工作,但是如果在从内存缓存过期之前在基础表中更新了请求的数据,则请求的数据可能会过期。

.命名空间:memcached就像一个大目录,您可以为文件提供带有前缀和后缀的详细名称,以防止文件发生冲突。daemon_memcached插件允许对键 使用类似的命名约定,但增加了一点。Key名称格式为@@table_id.key.table_id被解码为引用一个特定的表,使用来自 innodb_memcache.containers表的映射数据。在指定的表中查找或写入键。

@@符号只适用于get、add和set函数的单独调用,而不适用于诸如incr或delete之类的其他调用。要为会话中的后续memcached操作指定一个默认 表,可以使用带table_id的@@符号执行get请求,但不带key部分。例如:

get @@table_id

后续的get、set、incr、delete等操作将使用innodb_memcache.containers.name列中table_id指定的表。

.哈希和分布: 默认配置使用innodb_only缓存策略,适合传统的部署配置,即所有数据都在所有服务器上可用,例如一组复制从服务器。

如果像在分片配置中那样物理地划分数据,就可以在运行daemon_memcached插件的多台机器上划分数据,并使用传统的memcached散列机制将请 求路由到特定的机器上。在MySQL端,通常通过add请求向memcached插入所有数据,以便将适当的值存储在适当的服务器上的数据库中。

.内存使用:默认情况下(在innodb_only缓存策略下),memcached协议在InnoDB表之间来回传递信息,InnoDB缓冲池处理内存查找,而不是 memcached内存使用的增长和收缩。memcached端使用的内存相对较少。

如果将缓存策略切换为缓存或仅缓存,则适用memcached内存使用的常规规则。用于memcached数据值的内存是按“slab”分配的。您可以控制 slab大小和用于memcached的最大内存。无论采用哪种方式,都可以使用熟悉的统计系统(例如,通过telnet会话通过标准协议访问)监视daemon_memcached插件并对其进行故障排除。额 外的实用程序不包含在daemon_memcached插件中。您可以使用memcached-tool脚本来安装完整的memcached发行版。

线程使用:MySQL线程和memcached线程共存于同一服务器上。操作系统对线程施加的限制适用于线程总数。

日志使用:由于memcached守护进程与MySQL服务器一起运行并写入stderr,因此用于记录日志的-v、-vv和-vvv选项将输出写入MySQL错误日志。

memcached操作:熟悉的memcached操作,如get、set、add和delete都是可用的。序列化(即表示复杂数据结构的确切字符串格式)取决于语言接口 。

使用memcached作为MySQL前端:这是InnoDB memcached插件的主要目的。集成的memcached守护进程提高了应用程序的性能,并且让InnoDB处理内 存和磁盘之间的数据传输简化了应用程序的逻辑。

工具:MySQL服务器包括libmemcached库,但不包括其他命令行实用程序。要使用memcp、memcat和memcapable等命令,请安装完整的memcached发 行版。当memm和memflush从缓存中删除项时,这些项也会从底层InnoDB表中删除。

编程接口:可以使用所有支持的语言(C和c++、Java、Perl、Python、PHP和Ruby),通过daemon_memcached插件访问MySQL服务器。与传统的 memcached服务器一样指定服务器主机名和端口。默认情况下,daemon_memcached插件在端口11211上监听。可以同时使用文本和二进制协议。您 可以在运行时自定义memcached函数的行为。序列化(即表示复杂数据结构的确切字符串格式)取决于语言接口。

常见问题:MySQL为传统的memcached提供了广泛的常见问题解答。常见问题解答是最适用的,除了使用InnoDB表作为memcached数据的存储介质意 味着您可以将memcached用于比以前更写密集型的应用程序,而不是作为只读缓存。

设置InnoDB memcached插件
下面描述如何在MySQL服务器上设置daemon_memcached插件。因为memcached守护进程与MySQL服务器紧密集成,以避免网络流量并最小化延迟, 所以您可以在使用此特性的每个MySQL实例上执行此过程。

先决条件
.daemon_memcached插件仅支持Linux、Solaris和OS X平台。不支持其他操作系统。

.当从源代码构建MySQL时,您必须使用-DWITH_INNODB_MEMCACHED=ON进行构建。这个构建选项在MySQL插件目录(plugin_dir)中生成两个共享库 ,用于运行daemon_memcached插件:
.libmemcached.so:MySQL的memcached守护进程插件。

.innodb_engine.so:memcached的一个InnoDB API插件。

.Libevent必须安装。
.如果您没有从源代码构建MySQL,则libevent库不会包含在您的安装中。请按照操作系统的安装方法安装libevent 1.4.12及以上版本。例如, 根据不同的操作系统,你可能会使用apt-get、yum或port install。例如,在Ubuntu Linux中,使用:

sudo apt-get install libevent-dev

.如果您从源代码版本安装MySQL,则libevent 1.4.12与软件包捆绑在一起,位于MySQL源代码目录的顶层。如果您使用的是捆绑版本的 libevent,则无需执行任何操作。如果您想使用本地系统版本的libevent,则必须将-DWITH_LIBEVENT build选项设置为system或yes来构建 MySQL。

安装和配置InnoDB memcached插件
1.运行位于MYSQL_HOME/share中的innodb_memcached_config.sql配置脚本配置daemon_memcached插件,使其可以与InnoDB表交互。这个脚本安 装了innodb_memcache数据库,包含三个必需的表(cache_policies, config_options和containers)。它还将demo_test样例表安装到test数据库 中。

mysql> source /mysqlsoft/mysql/share/innodb_memcached_config.sql
Query OK, 1 row affected (0.01 sec)

Database changed
Query OK, 0 rows affected (0.08 sec)

Query OK, 0 rows affected (0.09 sec)

Query OK, 0 rows affected (0.09 sec)

Query OK, 1 row affected (0.02 sec)

Query OK, 1 row affected (0.01 sec)

Query OK, 1 row affected (0.03 sec)

Query OK, 1 row affected (0.01 sec)

Query OK, 1 row affected, 1 warning (0.04 sec)

Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
Query OK, 0 rows affected (0.07 sec)

Query OK, 1 row affected (0.03 sec)

执行innodb_memcached_config.sql脚本是一次性操作。如果以后卸载并重新安装daemon_memcached插件,这些表将保留在原来的位置。

mysql> use innodb_memcache
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show tables;
+---------------------------+
| Tables_in_innodb_memcache |
+---------------------------+
| cache_policies            |
| config_options            |
| containers                |
+---------------------------+
3 rows in set (0.00 sec)


mysql> use test
Database changed
mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| demo_test      |
+----------------+
1 row in set (0.00 sec)

在这些表中,innodb_memcache.containers表是最重要的。containers表中的条目提供了到InnoDB表列的映射。daemon_memcached插件使用的每 个InnoDB表都需要在containers表中添加一个条目。

innodb_memcached_config.sql脚本在容器表中插入单个条目,该条目为demo_test表提供映射。它还将一行数据插入demo_test表中。该数据允 许您在安装完成后立即验证安装。

mysql> select * from innodb_memcache.containers\G;
*************************** 1. row ***************************
                  name: aaa
             db_schema: test
              db_table: demo_test
           key_columns: c1
         value_columns: c2
                 flags: c3
            cas_column: c4
    expire_time_column: c5
unique_idx_name_on_key: PRIMARY
1 row in set (0.00 sec)

ERROR:
No query specified

mysql> select * from test.demo_test;
+----+--------------+------+------+------+
| c1 | c2           | c3   | c4   | c5   |
+----+--------------+------+------+------+
| AA | HELLO, HELLO |    8 |    0 |    0 |
+----+--------------+------+------+------+
1 row in set (0.00 sec)



mysql> INSTALL PLUGIN daemon_memcached soname "libmemcached.so";
Query OK, 0 rows affected (0.18 sec)

一旦安装了这个插件,每次MySQL服务器重新启动时,它就会自动激活。

验证InnoDB和memcached的安装
要验证daemon_memcached插件设置,请使用telnet会话发出memcached命令。默认情况下,memcached守护进程监听端口11211。

[root@localhost /]# netstat -ltnp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:11211           0.0.0.0:*               LISTEN      998/mysqld
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1630/sshd
tcp6       0      0 :::3306                 :::*                    LISTEN      998/mysqld
tcp6       0      0 :::11211                :::*                    LISTEN      998/mysqld
tcp6       0      0 :::22                   :::*                    LISTEN      1630/sshd

1.从test.demo_test表中检索数据。demo_test表中的单行数据的键值为AA。

mysql> select * from test.demo_test;
+----+--------------+------+------+------+
| c1 | c2           | c3   | c4   | c5   |
+----+--------------+------+------+------+
| AA | HELLO, HELLO |    8 |    0 |    0 |
+----+--------------+------+------+------+
1 row in set (0.00 sec)


[root@localhost /]# telnet localhost 11211
Trying ::1...
Connected to localhost.
Escape character is '^]'.
get AA
VALUE AA 8 12
HELLO, HELLO
END

2.使用set命令插入数据。

set BB 10 0 16
GOODBYE, GOODBYE
STORED

说明:
.set命令用来存储值

.BB 是键

.10是操作标志;被memcached忽略,但可以被客户端用来表示任何类型的信息;如果未使用,则指定0

.0为过期时间(TTL);如果未使用,则指定0

.16是所提供值块的长度,以字节为单位

.GOODBYE, GOODBYE是存储的值

3.通过连接MySQL服务器,查询test.demo_test表,验证插入的数据是否存储在MySQL中。

mysql> select * from test.demo_test;
+----+------------------+------+------+------+
| c1 | c2               | c3   | c4   | c5   |
+----+------------------+------+------+------+
| AA | HELLO, HELLO     |    8 |    0 |    0 |
| BB | GOODBYE, GOODBYE |   10 |    1 |    0 |
+----+------------------+------+------+------+
2 rows in set (0.00 sec)

4.返回到telnet会话并检索您先前使用BB键插入的数据。

get BB
VALUE BB 10 16
GOODBYE, GOODBYE
END

如果关闭MySQL服务器,同时也关闭了集成的memcached服务器,那么进一步访问memcached数据的尝试将会失败,并出现连接错误。通常, memcached数据在此时也会消失,当memcached重启时,需要应用程序逻辑将数据加载回内存。但是,InnoDB memcached插件会自动完成这个过
程。

重新启动MySQL时,get操作再次返回存储在早期memcached会话中的键/值对。当一个键被请求并且相关的值不在内存缓存中时,该值将自动从 MySQL test.demo_test表中查询。

创建新的表和列映射
这个例子展示了如何使用daemon_memcached插件设置自己的InnoDB表。
1.创建一个InnoDB表。表必须有一个具有唯一索引的键列。city表的键列是city_id,它被定义为主键。该表还必须包括用于标记、cas和过期值 的列。可能有一个或多个值列。城市表有三个值列(名称、州、国家)。

mysql> create table test.city (
    -> city_id varchar(32),
    -> name varchar(1024),
    -> state varchar(1024),
    -> country varchar(1024),
    -> flags int,
    -> cas bigint unsigned,
    -> expiry int,
    -> primary key(city_id)
    -> ) engine=innodb;
Query OK, 0 rows affected (0.08 sec)

2.在innodb_memcache中添加一个表项。以便daemon_memcached插件知道如何访问InnoDB表。该表项必须满足innodb_memcache.containers表定义。

mysql> desc innodb_memcache.containers;
+------------------------+--------------+------+-----+---------+-------+
| Field                  | Type         | Null | Key | Default | Extra |
+------------------------+--------------+------+-----+---------+-------+
| name                   | varchar(50)  | NO   | PRI | NULL    |       |
| db_schema              | varchar(250) | NO   |     | NULL    |       |
| db_table               | varchar(250) | NO   |     | NULL    |       |
| key_columns            | varchar(250) | NO   |     | NULL    |       |
| value_columns          | varchar(250) | YES  |     | NULL    |       |
| flags                  | varchar(250) | NO   |     | 0       |       |
| cas_column             | varchar(250) | YES  |     | NULL    |       |
| expire_time_column     | varchar(250) | YES  |     | NULL    |       |
| unique_idx_name_on_key | varchar(250) | NO   |     | NULL    |       |
+------------------------+--------------+------+-----+---------+-------+
9 rows in set (0.00 sec)

city表的innodb_memcache.containers表项定义为:

mysql> insert into innodb_memcache.containers (
    -> name, db_schema, db_table, key_columns, value_columns,
    -> flags, cas_column, expire_time_column, unique_idx_name_on_key)
    -> values ('default', 'test', 'city', 'city_id', 'name|state|country',
    -> 'flags','cas','expiry','primary');
Query OK, 1 row affected (0.04 sec)

.default指定给containers.name列以将ctiy表配置为默认值,InnoDB表与daemon_memcached插件一起使用。

.多个InnoDB表列(name, state, country)被映射containers.value_columns使用” | “分隔符。

.innodb_memcache.containers的flags、cas_column和expire_time_column字段在使用daemon_memcached插件的应用程序中通常不重要。但是, 每个表都需要一个指定的InnoDB表列。在插入数据时,如果这些列未使用,则将它们指定为0。

3.更新innodb_memcache.containers表后,重新启动daemon_memcache插件以应用更改。

mysql> UNINSTALL PLUGIN daemon_memcached;
Query OK, 0 rows affected (2.01 sec)

mysql> INSTALL PLUGIN daemon_memcached soname "libmemcached.so";
Query OK, 0 rows affected (0.10 sec)

4.通过telnet,使用memcached set命令向city表插入数据。

[root@localhost ~]# telnet localhost 11211
Trying ::1...
Connected to localhost.
Escape character is '^]'.
set B 0 0 22
BANGALORE|BANGALORE|IN
STORED

5.使用MySQL查询test.city表,以验证插入的数据是否已存储。

mysql> select * from test.city;
+---------+-----------+-----------+---------+-------+------+--------+
| city_id | name      | state     | country | flags | cas  | expiry |
+---------+-----------+-----------+---------+-------+------+--------+
| B       | BANGALORE | BANGALORE | IN      |     0 |    2 |      0 |
+---------+-----------+-----------+---------+-------+------+--------+
1 row in set (0.00 sec)

6.使用MySQL,向test.city表插入额外的数据。

mysql> insert into city values ('c','chennai','tamil nadu','in', 0, 0 ,0);
Query OK, 1 row affected (0.02 sec)

mysql> insert into city values ('d','delhi','delhi','in', 0, 0, 0);
Query OK, 1 row affected (0.00 sec)

mysql> insert into city values ('h','hyderabad','telangana','in', 0, 0, 0);

Query OK, 1 row affected (0.05 sec)

mysql> insert into city values ('m','mumbai','maharashtra','in', 0, 0, 0);
Query OK, 1 row affected (0.02 sec)

7.使用telnet,发出memcached get命令来检索使用MySQL插入的数据。

get H
VALUE H 0 22
hyderabad|telangana|in
END
get C
VALUE C 0 21
chennai|tamil nadu|in
END

发表评论

电子邮件地址不会被公开。