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