MySQL & NoSQL – Memcached 插件

大多数人都已经听说 NoSQL 数据库,其中使用最广泛的工具是 Memcached,你们通过 Memcached 再应用层和数据库之间添加一个缓存层。从 MySQL 5.6 开始,你可以获得一个全新的插件,这个插件把 MySQL 和 Memcached 集成起来。在此文中,我们将学习怎样在 Linux 中 安装这个插件,怎样做一些基础的配置。

先决条件

安装 libevent。

译者注:以下命令由译者提供。

命令如下:

  1. yum install libevent -y
  2. yum install php -y
  3. yum install policycoreutils-python -y
  1. mysql> SHOW VARIABLES LIKE '%version%';
  2. +-------------------------+------------------------------+
  3. |Variable_name|Value|
  4. +-------------------------+------------------------------+
  5. | innodb_version |5.6.21|
  6. | protocol_version |10|
  7. | slave_type_conversions ||
  8. | version |5.6.21|
  9. | version_comment |MySQLCommunityServer(GPL)|
  10. | version_compile_machine | x86_64 |
  11. | version_compile_os |Linux|
  12. +-------------------------+------------------------------+
  13. 7 rows inset(0.00 sec)

安装

安装 Memcached 支持,我们需要创建一些为 MySQL 和 Memcached 集成服务的表。MySQL 已经包含了创建这些表的文件(innodb_memcached_config.sql),你可以在你的 basedir 子目录中找到这个文件。为了找到你的 basedir 在什么地方,运行如下命令:

  1. mysql> SHOW VARIABLES LIKE 'basedir';
  2. +---------------+-------+
  3. |Variable_name|Value|
  4. +---------------+-------+
  5. | basedir |/usr |
  6. +---------------+-------+
  7. 1 row inset(0.00 sec)

如果你通过发行版仓库安装 MySQL,这个文件的路径如下:$basedir/share/mysql/innodb_memcached_config.sql

如果你使用 MySQL 二进制版本,这个文件的路径如下:$basedir/share/innodb_memcached_config.sql

现在,我们将运行这个 SQL 文件。默认情况下,这个脚本在 test 数据库中创建一个 test 表,但是在我们的测试中,我们将使用 memcached 数据库。

译者注:操作日志中的时间可能跟原文不同,以下日志来自自己的实验。

  1. mysql> CREATE DATABASE IF NOT EXISTS test;
  2. Query OK,1 row affected (0.00 sec)
  3. mysql> source /usr/share/mysql/innodb_memcached_config.sql
  4. Query OK,1 row affected (0.00 sec)
  5. Database changed
  6. Query OK,0 rows affected (0.14 sec)
  7. Query OK,0 rows affected (0.02 sec)
  8. Query OK,0 rows affected (0.02 sec)
  9. Query OK,1 row affected (0.01 sec)
  10. Query OK,1 row affected (0.00 sec)
  11. Query OK,1 row affected (0.01 sec)
  12. Query OK,1 row affected (0.01 sec)
  13. Database changed
  14. Query OK,0 rows affected (0.03 sec)
  15. Query OK,1 row affected (0.00 sec)
  16. mysql>

现在,让我们创建我们自己的表,用于存放 Memcached 数据:

  1. mysql> CREATE DATABASE IF NOT EXISTS memcached;
  2. Query OK,1 row affected (0.00 sec)
  3. mysql> CREATE TABLE memcached.dados LIKE test.demo_test;
  4. Query OK,0 rows affected (0.02 sec)
  5. mysql> UPDATE innodb_memcache.containers SET db_schema ='memcached', \
  6. -> db_table ='dados' WHERE name ='aaa' LIMIT 1;
  7. Query OK,1 row affected (0.05 sec)
  8. Rows matched:1Changed:1Warnings:0
  9. mysql> DROP DATABASE test;
  10. Query OK,1 row affected (0.09 sec)

下一步是在 MySQL 中安装 Memcached 插件。为了实现这个功能,我们将会使用INSTALL PLUGIN 命令:

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

验证此插件是否成功安装,我们可以运行如下命令:

  1. mysql> \! netstat -tunap | grep LIST | grep mysql
  2. tcp 000.0.0.0:112110.0.0.0:* LISTEN 1858/mysqld
  3. tcp 00:::11211:::* LISTEN 1858/mysqld
  4. tcp 00:::3306:::* LISTEN 1858/mysqld

配置和使用

现在,我们将会通过一种编程语言——PHP,比如使用这种方式:

  1. [root@mysql memcache]# cat test1.php

译者注:原文是 new Memcached(),此处改为 new Memcache(),以下的 PHP 脚本均为 new Memcache()。

  1. <?php
  2. $m =newMemcache();
  3. $m->addServer('localhost',11211);
  4. $m->set('key1','Testing memcached');
  5. echo 'Value of key1 is:'. $m->get('key1')."\n";
  6. ?>
  1. [root@mysql memcache]# php test1.php
  2. Value of key1 is:Testing memcached

现在,让我们看看在 MySQL 中存储了些什么?

  1. mysql> SELECT * FROM memcached.dados;
  2. +------+-------------------+------+------+------+
  3. | c1 | c2 | c3 | c4 | c5 |
  4. +------+-------------------+------+------+------+
  5. | key1 |Testing memcached |0|1|0|
  6. +------+-------------------+------+------+------+
  7. 1 row inset(0.00 sec)

如果我们在 MySQL 中手动更改一个记录,会发生什么?

  1. mysql> UPDATE memcached.dados \
  2. -> SET c2 ='Entry modified directly on MySQL';
  3. Query OK,1 row affected (0.03 sec)
  4. Rows matched:1Changed:1Warnings:0
  1. [root@mysql memcache]# cat test2.php
  1. <?php
  2. $m =newMemcache();
  3. $m->addServer('localhost',11211);
  4. echo 'Value of key1 is:'. $m->get('key1')."\n";
  5. ?>
  1. [root@mysql memcache]# php test2.php
  2. Value of key1 is:Entry modified directly on MySQL
  3. [root@mysql memcache]#

如果我们想存放条目到不同的 MySQL 表,那么又会怎样?

我们仅仅需要创建一个新的表,添加一个新的容器,并且使用在 innodb_memcache 数据库的 config_options 表定义的分隔符。

  1. mysql> SELECT * FROM innodb_memcache.config_options \
  2. -> WHERE name ='table_map_delimiter';
  3. +---------------------+-------+
  4. | name | value |
  5. +---------------------+-------+
  6. | table_map_delimiter |.|
  7. +---------------------+-------+
  8. 1 row inset(0.00 sec)
  9. mysql> CREATE TABLE memcached.dados2 LIKE memcached.dados;
  10. Query OK,0 rows affected (0.08 sec)
  11. mysql> INSERT INTO innodb_memcache.containers(name, db_schema, db_table,\
  12. -> key_columns, value_columns, flags, cas_column, expire_time_column,\
  13. -> unique_idx_name_on_key) \
  14. -> VALUES('bbb','memcached','dados2','c1','c2','c3','c4','c5','PRIMARY');
  15. Query OK,1 row affected (0.06 sec)

我们已经创建一个名为 dados2 的新表,并且添加了一个新的名为 bbb 的容器指向那个表,现在我们仅仅需要在 Memcached 中使用它作为前缀即可。

  1. [root@mysql memcache]# cat test3.php
  1. <?php
  2. $m =newMemcache();
  3. $m->addServer('localhost',11211);
  4. $m->set('@@bbb.key1','Should be stored on dados2 table');
  5. echo 'Value of bbb.key1 is:'. $m->get('@@bbb.key1')."\n";
  6. ?>
  1. [root@mysql memcache]# php test3.php
  2. Value of bbb.key1 is:Should be stored on dados2 table
  1. mysql> SELECT * FROM memcached.dados2;
  2. +------+----------------------------------+------+------+------+
  3. | c1 | c2 | c3 | c4 | c5 |
  4. +------+----------------------------------+------+------+------+
  5. | key1 |Should be stored on dados2 table |0|2|0|
  6. +------+----------------------------------+------+------+------+
  7. 1 row inset(0.00 sec)

我们也可以映射这个表,将存储的值分为单独的域。

  1. mysql> SELECT * FROM innodb_memcache.config_options \
  2. -> WHERE name ='separator';
  3. +-----------+-------+
  4. | name | value |
  5. +-----------+-------+
  6. | separator |||
  7. +-----------+-------+
  8. 1 row inset(0.00 sec)

我们将会使用这个字符来把值存储到不同的列中。让我们创建一个表,添加到一个新的容器中(我们将会指定新的分隔符——逗号’,’,来存放我们的数据):

  1. mysql> CREATE TABLE products \
  2. ->(id varchar(128), \
  3. -> name varchar(255), \
  4. -> value varchar(15), \
  5. -> c3 int, \
  6. -> c4 bigint, \
  7. -> c5 int, \
  8. -> PRIMARY KEY(id));
  9. Query OK,0 rows affected (0.05 sec)
  10. mysql> INSERT INTO innodb_memcache.containers \
  11. ->(name, db_schema, db_table, key_columns, value_columns, \
  12. -> flags, cas_column, expire_time_column, unique_idx_name_on_key) \
  13. -> VALUES ('products','memcached','products','id','name,value', \
  14. ->'c3','c4','c5','PRIMARY');
  15. Query OK,1 row affected (0.06 sec)

现在,让我们创建一个产品数组,然后添加这些数据到 Memcached 中。

  1. [root@mysql memcache]# cat test4.php
  1. <?php
  2. $m =newMemcache();
  3. $m->addServer('localhost',11211);
  4. $products = array(
  5. array('1','TV','1999,00'),
  6. array('2','Hack','399,00'),
  7. array('3','Table','599,00'),
  8. array('4','Chair','99,00')
  9. );
  10. foreach($products as $product)
  11. {
  12. $key ='@@products.'. $product[0];
  13. $value = $product[1].'|'. $product[2];
  14. $m->set($key, $value);
  15. }
  16. ?>
  1. [root@mysql memcache]# php test4.php
  1. mysql> SELECT * FROM memcached.products;
  2. +----+-------+---------+------+------+------+
  3. | id | name | value | c3 | c4 | c5 |
  4. +----+-------+---------+------+------+------+
  5. |1| TV |1999,00|0|3|0|
  6. |2|Hack|399,00|0|4|0|
  7. |3|Table|599,00|0|5|0|
  8. |4|Chair|99,00|0|6|0|
  9. +----+-------+---------+------+------+------+
  10. 4 rows inset(0.00 sec)

服务器/服务 重启

让我们看看如果我们重启 MySQL 服务(重启服务器通用适用)会发生什么?

这些存储在 Memcached 中的数据在 MySQL 服务重启之后仍然会存在吗?

  1. [root@mysql memcache]# service mysql restart
  2. Shutting down MySQL...... SUCCESS!
  3. StartingMySQL. SUCCESS!
  4. [root@mysql memcache]# cat test5.php
  1. <?php
  2. $m =newMemcache();
  3. $m->addServer('localhost',11211);
  4. echo 'Value of key1 is:'. $m->get('key1')."\n";
  5. ?>
  1. [root@mysql memcache]# php test5.php
  2. Value of key1 is:Entry modified directly on MySQL

换句话说!即使服务重启或者服务器重启,这些数据仍然会存在。

SELinux

在 SELinux 启用的环境中,会阻止 Memcached 和 MySQL 集成,因为不允许监听 Memcached 端口,下面是一个怎样允许监听 Memcached 端口的例子(我使用 CentOS Linux 分发版):

在 /var/log/audit/audit.log 中查找包含 mysqld 和 denied 关键字的条目,如果你能找到,输入如下的命令来创建一个新的 SELinux 模块来允许:

  1. type=AVC msg=audit(1423266535.066:5): avc: denied { name_bind }for \
  2. pid=1123 comm="mysqld" src=11211 scontext=system_u:system_r:mysqld_t:s0 \
  3. tcontext=system_u:object_r:memcache_port_t:s0 tclass=tcp_socket
  4. type=SYSCALL msg=audit(1423266535.066:5): arch=c000003e syscall=49 \
  5. success=noexit=-13 a0=2f a1=7f3aec043230 a2=10 a3=7f3af61fa75c \
  6. items=0 ppid=999 pid=1123 auid=4294967295 uid=27 gid=27 euid=27 suid=27 \
  7. fsuid=27 egid=27 sgid=27 fsgid=27 tty=(none) ses=4294967295 comm="mysqld" \
  8. exe="/usr/sbin/mysqld" subj=system_u:system_r:mysqld_t:s0 key=(null)
  9. [root@mysql ~]# audit2why </var/log/audit/audit.log
  10. type=AVC msg=audit(1423266535.066:5): avc: denied { name_bind }for \
  11. pid=1123 comm="mysqld" src=11211 scontext=system_u:system_r:mysqld_t:s0 \
  12. tcontext=system_u:object_r:memcache_port_t:s0 tclass=tcp_socket
  13. Was caused by:
  14. Missing type enforcement (TE) allow rule.
  15. You can use audit2allow to generate a loadable module to allow this access.
  16. [root@mysql ~]# cd /root/
  17. [root@mysql ~]# mkdir selinux-custom
  18. [root@mysql ~]# cd selinux-custom
  19. [root@mysql selinux-custom]# audit2allow -a -M mysql-memcache
  20. ******************** IMPORTANT ***********************
  21. To make this policy package active, execute:
  22. semodule -i mysql-memcache.pp
  23. [root@mysql selinux-custom]# semodule -i mysql-memcache.pp

译者注:以下为译者添加,用于测试在 SELinux 环境下,MySQL 和 Memcached 的集成。

  1. [root@mysql selinux-custom]# sestatus
  2. SELinux status: enabled
  3. SELinuxfs mount:/selinux
  4. Current mode: enforcing
  5. Modefrom config file: enforcing
  6. Policy version:24
  7. Policyfrom config file: targeted
  8. [root@mysql selinux-custom]# getenforce
  9. Enforcing
  10. [root@mysql selinux-custom]#/etc/init.d/mysql restart
  11. Shutting down MySQL....[ OK ]
  12. StartingMySQL.[ OK ]
  13. [root@mysql memcache]# cd ~/memcache
  14. [root@mysql memcache]# cat test6.php
  1. <?php
  2. $m =newMemcache();
  3. $m->addServer('localhost',11211);
  4. echo 'Value of key1 is:'. $m->get('key1')."\n";
  5. ?>
  1. [root@mysql selinux-custom]# netstat -tunap | grep LIST | grep mysql
  2. tcp 000.0.0.0:112110.0.0.0:* LISTEN 7820/mysqld
  3. tcp 00:::11211:::* LISTEN 7820/mysqld
  4. tcp 00:::3306:::* LISTEN 7820/mysqld
  5. [root@mysql memcache]# php test6.php
  6. Value of key1 is:Entry modified directly on MySQL

Memcached 选项

如果你想更改任何 Memcached 特殊的选项,你可以在 MySQL 的配置文件中添加daemon_memcached_option 参数,比如更改 Memcached 端口:

  1. # In the configuration file, my.cnf generally
  2. daemon_memcached_option=”-p11222

就是这样,我希望你已经学会了如何安装和配置 MySQL 和 Memcached 插件的集成工作。

猜你喜欢

转载自www.linuxidc.com/Linux/2015-09/122603.htm