Table des matières
安装
配置
限制
实战
Maison base de données tutoriel mysql 初窥InnoDB的Memcached插件

初窥InnoDB的Memcached插件

Jun 07, 2016 pm 04:32 PM
innodb memcached 插件

前些年,HandlerSocket的横空出世让人们眼前一亮,当时我还写了一篇文章介绍了其用法梗概,时至今日,由于种种原因,HandlerSocket并没有真正流行起来,不过庆幸的是MySQL官方受其启发,研发了基于InnoDB的Memcached插件,总算是在MySQL中延续了NoSQL的香火

前些年,HandlerSocket的横空出世让人们眼前一亮,当时我还写了一篇文章介绍了其用法梗概,时至今日,由于种种原因,HandlerSocket并没有真正流行起来,不过庆幸的是MySQL官方受其启发,研发了基于InnoDB的Memcached插件,总算是在MySQL中延续了NoSQL的香火,以前单独架设Memcached服务器不仅浪费了内存,而且还必须自己维护数据的不一致问题,有了Memcached插件,这些问题都不存在了,而且借助MySQL本身的复制功能,我们可以说是变相的实现了Memcached的复制,这更是意外之喜。

安装

为了让文章更具完整性,我们选择从源代码安装MySQL,需要注意的是早期的版本有内存泄漏,所以推荐安装最新的稳定版,截至本文发稿时为止,最新的稳定版是5.6.13,我们就以此为例来说明,过程很简单,只要激活了WITH_INNODB_MEMCACHED即可:

shell> groupadd mysql
shell> useradd -r -g mysql mysql
shell> tar zxvf mysql-5.6.13.tar.gz
shell> cd mysql-5.6.13
shell> cmake . -DWITH_INNODB_MEMCACHED=ON
shell> make
shell> make install
shell> cd /usr/local/mysql
shell> chown -R mysql .
shell> chgrp -R mysql .
shell> scripts/mysql_install_db --user=mysql
shell> chown -R root .
shell> chown -R mysql data
shell> bin/mysqld_safe --user=mysql &
shell> cp support-files/mysql.server /etc/init.d/mysql.server
Copier après la connexion

MySQL安装完毕后,需要导入Memcached插件所需要的表结构:

mysql> SOURCE /usr/local/mysql/share/innodb_memcached_config.sql
Copier après la connexion

一切就绪后就可以激活Memcached插件了(当然也可以禁止):

mysql> INSTALL PLUGIN daemon_memcached soname "libmemcached.so";
mysql> UNINSTALL PLUGIN daemon_memcached;
Copier après la connexion

说明:以后一旦修改了原本已存在的Memcached插件的配置信息,均需要使用如上命令来重启Memcached插件(先uninstall,再install),以便让修改生效。

Memcached插件相关的配置信息如下,具体介绍可以参考官方文档:

mysql> SHOW VARIABLES LIKE '%memcached%';
+----------------------------------+------------------+
| Variable_name                    | Value            |
+----------------------------------+------------------+
| daemon_memcached_enable_binlog   | OFF              |
| daemon_memcached_engine_lib_name | innodb_engine.so |
| daemon_memcached_engine_lib_path |                  |
| daemon_memcached_option          |                  |
| daemon_memcached_r_batch_size    | 1                |
| daemon_memcached_w_batch_size    | 1                |
+----------------------------------+------------------+
Copier après la connexion

注意:daemon_memcached_r_batch_size和daemon_memcached_w_batch_size,这两个选项对性能影响较大,简单点说就是控制事务提交的频率,MySQL的缺省值均为1,也就是说每次都提交,这主要是从安全性考虑的,大家可以依照自己的情况来调整。

差不多了,此时Memcached端口应该准备就绪了,你可以试试看:

shell> echo "stats" | nc localhost 11211
Copier après la connexion

换句话说,MySQL已经兼容Memcached协议,可以直接使用Memcached命令。

配置

在安装步骤里,我们导入了一个名为innodb_memcached_config.sql的脚本,它创建了一库(innodb_memcache)三表(cache_policies, config_options, containers):

mysql> USE innodb_memcache
mysql> SHOW TABLES;
+---------------------------+
| Tables_in_innodb_memcache |
+---------------------------+
| cache_policies            |
| config_options            |
| containers                |
+---------------------------+
Copier après la connexion

cache_policies定义了缓存策略,包含如下选择:

  • innodb_only:只使用InnoDB作为数据存储。

  • cache-only:只使用传统的Memcached引擎作为后端存储。

  • caching:二者皆使用,如果在Memcached里找不到,就查询InnoDB。

  • config_options定义了分隔符号:

  • separator:Memcached只识别单值,使用此分隔符(|)来连接多个字段的值。

  • table_map_delimiter:通过此分隔符(.)来确认表和键,如:@@table.key。

  • 如果我们想通过Memcached协议来访问一个表,需要先在containers中配置它:

mysql> SELECT * FROM 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
Copier après la connexion

如上已经有了test数据库的demo_test表,通过c1查询c2的值,表结构如下所示:

mysql> DESC test.demo_test;
+-------+---------------------+------+-----+---------+-------+
| Field | Type                | Null | Key | Default | Extra |
+-------+---------------------+------+-----+---------+-------+
| c1    | varchar(32)         | NO   | PRI |         |       |
| c2    | varchar(1024)       | YES  |     | NULL    |       |
| c3    | int(11)             | YES  |     | NULL    |       |
| c4    | bigint(20) unsigned | YES  |     | NULL    |       |
| c5    | int(11)             | YES  |     | NULL    |       |
+-------+---------------------+------+-----+---------+-------+
Copier après la connexion

缺省情况下有一行数据:

mysql> SELECT * FROM test.demo_test;
+----+--------------+------+------+------+
| c1 | c2           | c3   | c4   | c5   |
+----+--------------+------+------+------+
| AA | HELLO, HELLO |    8 |    0 |    0 |
+----+--------------+------+------+------+
Copier après la connexion

让我们用Memcached协议来访问看看:

shell> echo "get @@aaa.AA" | nc localhost 11211
VALUE @@aaa.AA 8 12
HELLO, HELLO
END
Copier après la connexion

我们还可以先设定缺省访问的表,然后后续的查询就只写键名就可以了:

shell> (echo "get @@aaa"; echo "get AA") | nc localhost 11211
VALUE @@aaa 0 14
test/demo_test
END
VALUE AA 8 12
HELLO, HELLO
END
Copier après la connexion

虽然我的例子都是通过命令行执行的,但是大家很容易就更改写成PHP之类的方法。

限制

Memcached插件用起来非常简单,不过并不是一切都很完美,比如说:当我们配置表的时候,containers表的字段,除了key_columns和value_columns以外,其它的字段,如:flags,cas_column,expire_time_column等也必须设定,可是很多时候,我们在原表中找不到贴切的字段,此时就只能对应新建三个字段,味道很恶心。

此外,containers表还有如下限制:

  • key_columns字段的类型必须是CHAR或VARCHAR,且最大长度是250个字符。

  • value_columns字段的类型必须是CHAR或VARCHAR或BLOB,长度不限。

  • cas_column字段的类型必须是BIGINT。

  • expiration_time_column字段的类型必须是INT。

  • flags字段的类型必须是INT。

  • 说明:随着MySQL版本的更新,这些限制可能会发生变化,请大家以实际情况为准。

    实战

    让我们以一个用户登录的例子来检验一下学习成果:

    首先在测试数据库创建一个用户表:

    USE `test`
    CREATE TABLE `users` (
        `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
        `username` VARCHAR(15) NOT NULL,
        `password` VARCHAR(32) NOT NULL,
        `email` text NOT NULL,
        `flags` INT(10) UNSIGNED DEFAULT '0',
        `cas_column` BIGINT(20) UNSIGNED DEFAULT '0',
        `expire_time_column` INT(10) UNSIGNED DEFAULT '0',
        PRIMARY KEY (`id`),
        UNIQUE KEY `username` (`username`)
    ) ENGINE=InnoDB;
    Copier après la connexion

    然后添加几行测试数据:

    INSERT INTO `users` (`username`, `password`, `email`)
    VALUES
    ('foo', 'ffffffffffffffffffffffffffffffff', 'foo@domain.com'),
    ('bar', 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb', 'bar@domain.com');
    Copier après la connexion

    接着在containers里配置这个表:

    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', 'users', 'username', 'password|email',
        'flags', 'cas_column', 'expire_time_column', 'username'
    );
    Copier après la connexion

    这里我们定义了多个字段(password和email)作为value_columns,并且使用竖线作为分隔符,实际上使用空格,逗号之类分隔符也可以,在innodb_config.c文件的源代码中能查到如下关于分隔符的定义,文档里并没有涵盖这些信息:

    static const char* sep = " ;,|\n";
    Copier après la connexion

    最后使用Memcached协议来访问一下,这里我们换个花样,执行一个MGET操作:

    shell> echo "get foo bar" | nc localhost 11211
    VALUE foo 0 47
    ffffffffffffffffffffffffffffffff|foo@domain.com
    VALUE bar 0 47
    bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb|bar@domain.com
    END
    Copier après la connexion

    既然我定义value_columns的时候设置了多个字段,那么返回数据的时候自然也返回多个字段的数据,并且它们依照innodb_memcache.config_options表中的separator字段来分隔,缺省情况下是一个竖线,如果你的字段内容里包含了竖线,那么就会和缺省值发生冲突,此时你可以更新separator的定义,比如改成三个竖线等等,需要提醒的是,修改后别忘了重启Memcached插件。

    说明:因为们在配置的时候把表命名为default,所以在请求的时候不用传递表名。

    本文在使用Memcached插件的时候,所有例子均使用的是读操作,实际上写操作也是支持的,不过在实际使用时,我更倾向于写操作都通过SQL来执行,而Memcached插件仅处理KV形式的读操作,实际压力测试的结果显示,Memcached插件比SQL的方式,性能提升了百分之一百左右,虽然仍不及独立的Memcached,但考虑到其它的优势,这个结果已经很让人欣喜了,下一站,InnoDB的Memcached插件!大家做好准备吧。

    Déclaration de ce site Web
    Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

    Article chaud

    Repo: Comment relancer ses coéquipiers
    3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
    R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
    1 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
    Combien de temps faut-il pour battre Split Fiction?
    3 Il y a quelques semaines By DDD
    Hello Kitty Island Adventure: Comment obtenir des graines géantes
    3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌

    Article chaud

    Repo: Comment relancer ses coéquipiers
    3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
    R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
    1 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
    Combien de temps faut-il pour battre Split Fiction?
    3 Il y a quelques semaines By DDD
    Hello Kitty Island Adventure: Comment obtenir des graines géantes
    3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌

    Tags d'article chaud

    Bloc-notes++7.3.1

    Bloc-notes++7.3.1

    Éditeur de code facile à utiliser et gratuit

    SublimeText3 version chinoise

    SublimeText3 version chinoise

    Version chinoise, très simple à utiliser

    Envoyer Studio 13.0.1

    Envoyer Studio 13.0.1

    Puissant environnement de développement intégré PHP

    Dreamweaver CS6

    Dreamweaver CS6

    Outils de développement Web visuel

    SublimeText3 version Mac

    SublimeText3 version Mac

    Logiciel d'édition de code au niveau de Dieu (SublimeText3)

    Guide du débutant PyCharm : compréhension complète de l'installation du plug-in ! Guide du débutant PyCharm : compréhension complète de l'installation du plug-in ! Feb 25, 2024 pm 11:57 PM

    Guide du débutant PyCharm : compréhension complète de l'installation du plug-in !

    Erreur de chargement du plugin dans Illustrator [Corrigé] Erreur de chargement du plugin dans Illustrator [Corrigé] Feb 19, 2024 pm 12:00 PM

    Erreur de chargement du plugin dans Illustrator [Corrigé]

    Quel est le répertoire d'installation de l'extension du plug-in Chrome ? Quel est le répertoire d'installation de l'extension du plug-in Chrome ? Mar 08, 2024 am 08:55 AM

    Quel est le répertoire d'installation de l'extension du plug-in Chrome ?

    Partagez trois solutions expliquant pourquoi le navigateur Edge ne prend pas en charge ce plug-in Partagez trois solutions expliquant pourquoi le navigateur Edge ne prend pas en charge ce plug-in Mar 13, 2024 pm 04:34 PM

    Partagez trois solutions expliquant pourquoi le navigateur Edge ne prend pas en charge ce plug-in

    PyCharm Community Edition prend-il en charge suffisamment de plugins ? PyCharm Community Edition prend-il en charge suffisamment de plugins ? Feb 20, 2024 pm 04:42 PM

    PyCharm Community Edition prend-il en charge suffisamment de plugins ?

    Comment utiliser le plug-in WordPress pour implémenter la fonction de lecture vidéo Comment utiliser le plug-in WordPress pour implémenter la fonction de lecture vidéo Sep 05, 2023 pm 12:55 PM

    Comment utiliser le plug-in WordPress pour implémenter la fonction de lecture vidéo

    Comment ajouter une fonctionnalité de commande en ligne au plugin WordPress Comment ajouter une fonctionnalité de commande en ligne au plugin WordPress Sep 05, 2023 pm 03:42 PM

    Comment ajouter une fonctionnalité de commande en ligne au plugin WordPress

    Comment ajouter la fonctionnalité du mini-programme WeChat au plug-in WordPress Comment ajouter la fonctionnalité du mini-programme WeChat au plug-in WordPress Sep 06, 2023 am 09:03 AM

    Comment ajouter la fonctionnalité du mini-programme WeChat au plug-in WordPress

    See all articles