MySQL & NoSQL – Memcached 插件

g2md 9年前發布 | 15K 次閱讀 緩存服務器 memcached

大多數人都已經聽說 NoSQL 數據庫,其中使用最廣泛的工具是 Memcached,你們通過 Memcached 再應用層和數據庫之間添加一個緩存層。從 MySQL 5.6 開始,你可以獲得一個全新的插件,這個插件把 MySQL 和 Memcached 集成起來。在此文中,我們將學習怎樣在 Linux 中 安裝這個插件,怎樣做一些基礎的配置。

MySQL & NoSQL – Memcached 插件

先決條件

安裝 libevent。

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

命令如下:

yum install libevent -y
yum install php -y
yum install policycoreutils-python -y

譯者注:我的操作系統版本是 RHEL 6.5,而作者的 OS 版本為 CentOS。以下是我的 MySQL 版本。

mysql> SHOW VARIABLES LIKE '%version%';
+-------------------------+------------------------------+
| Variable_name           | Value                        |
+-------------------------+------------------------------+
| innodb_version          | 5.6.21                       |
| protocol_version        | 10                           |
| slave_type_conversions  |                              |
| version                 | 5.6.21                       |
| version_comment         | MySQL Community Server (GPL) |
| version_compile_machine | x86_64                       |
| version_compile_os      | Linux                        |
+-------------------------+------------------------------+
7 rows in set (0.00 sec)

安裝

安裝 Memcached 支持,我們需要創建一些為 MySQL 和 Memcached 集成服務的表。MySQL 已經包含了創建這些表的文件(innodb_memcached_config.sql),你可以在你的 basedir 子目錄中找到這個文件。為了找到你的 basedir 在什么地方,運行如下命令:

mysql> SHOW VARIABLES LIKE 'basedir';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| basedir       | /usr  |
+---------------+-------+
1 row in set (0.00 sec)

如果你通過發行版倉庫安裝 MySQL,這個文件的路徑如下:$basedir/share/mysql/innodb_memcached_config.sql

如果你使用 MySQL 二進制版本,這個文件的路徑如下:$basedir/share/innodb_memcached_config.sql

現在,我們將運行這個 SQL 文件。默認情況下,這個腳本在 test 數據庫中創建一個 test 表,但是在我們的測試中,我們將使用 memcached 數據庫。

譯者注:操作日志中的時間可能跟原文不同,以下日志來自自己的實驗。

mysql> CREATE DATABASE IF NOT EXISTS test;
Query OK, 1 row affected (0.00 sec)

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

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

Query OK, 0 rows affected (0.02 sec)

Query OK, 0 rows affected (0.02 sec)

Query OK, 1 row affected (0.01 sec)

Query OK, 1 row affected (0.00 sec)

Query OK, 1 row affected (0.01 sec)

Query OK, 1 row affected (0.01 sec)

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

Query OK, 1 row affected (0.00 sec)

mysql>

現在,讓我們創建我們自己的表,用于存放 Memcached 數據:

mysql> CREATE DATABASE IF NOT EXISTS memcached;
Query OK, 1 row affected (0.00 sec)

mysql> CREATE TABLE memcached.dados LIKE test.demo_test;
Query OK, 0 rows affected (0.02 sec)

mysql> UPDATE innodb_memcache.containers SET db_schema = 'memcached', \
    -> db_table = 'dados' WHERE name = 'aaa' LIMIT 1;
Query OK, 1 row affected (0.05 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> DROP DATABASE test;
Query OK, 1 row affected (0.09 sec)

下一步是在 MySQL 中安裝 Memcached 插件。為了實現這個功能,我們將會使用INSTALL PLUGIN 命令:

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

驗證此插件是否成功安裝,我們可以運行如下命令:

mysql> \! netstat -tunap | grep LIST | grep mysql
tcp        0      0 0.0.0.0:11211               0.0.0.0:*                   LISTEN      1858/mysqld
tcp        0      0 :::11211                    :::*                        LISTEN      1858/mysqld
tcp        0      0 :::3306                     :::*                        LISTEN      1858/mysqld

配置和使用

現在,我們將會通過一種編程語言——PHP,比如使用這種方式:

[root@mysql memcache]# cat test1.php

譯者注:原文是 new Memcached(),此處改為 new Memcache(),以下的 PHP 腳本均為 new Memcache()。

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

現在,讓我們看看在 MySQL 中存儲了些什么?

mysql> SELECT * FROM memcached.dados;
+------+-------------------+------+------+------+
| c1   | c2                | c3   | c4   | c5   |
+------+-------------------+------+------+------+
| key1 | Testing memcached |    0 |    1 |    0 |
+------+-------------------+------+------+------+
1 row in set (0.00 sec)

如果我們在 MySQL 中手動更改一個記錄,會發生什么?

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

[root@mysql memcache]#

如果我們想存放條目到不同的 MySQL 表,那么又會怎樣?

我們僅僅需要創建一個新的表,添加一個新的容器,并且使用在 innodb_memcache 數據庫的 config_options 表定義的分隔符。

mysql> SELECT * FROM innodb_memcache.config_options \
    -> WHERE name = 'table_map_delimiter';
+---------------------+-------+
| name                | value |
+---------------------+-------+
| table_map_delimiter | .     |
+---------------------+-------+
1 row in set (0.00 sec)

mysql> CREATE TABLE memcached.dados2 LIKE memcached.dados;
Query OK, 0 rows affected (0.08 sec)

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('bbb', 'memcached', 'dados2', 'c1', 'c2', 'c3','c4','c5','PRIMARY');
Query OK, 1 row affected (0.06 sec)

我們已經創建一個名為 dados2 的新表,并且添加了一個新的名為 bbb 的容器指向那個表,現在我們僅僅需要在 Memcached 中使用它作為前綴即可。

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

我們也可以映射這個表,將存儲的值分為單獨的域。

mysql> SELECT * FROM innodb_memcache.config_options \
    -> WHERE name = 'separator';
+-----------+-------+
| name      | value |
+-----------+-------+
| separator | |     |
+-----------+-------+
1 row in set (0.00 sec)

我們將會使用這個字符來把值存儲到不同的列中。讓我們創建一個表,添加到一個新的容器中(我們將會指定新的分隔符——逗號’,’,來存放我們的數據):

mysql> CREATE TABLE products \
    -> (id varchar(128), \
    -> name varchar(255), \
    -> value varchar(15), \
    -> c3 int, \
    -> c4 bigint, \
    -> c5 int, \
    -> PRIMARY KEY(id));
Query OK, 0 rows affected (0.05 sec)

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 ('products', 'memcached', 'products', 'id', 'name,value', \
    -> 'c3','c4','c5','PRIMARY');
Query OK, 1 row affected (0.06 sec)

現在,讓我們創建一個產品數組,然后添加這些數據到 Memcached 中。

[root@mysql memcache]# cat test4.php
<?php
    $m = new Memcache();
    $m->addServer('localhost', 11211);
    $products = array(
    array('1', 'TV', '1999,00'),
    array('2', 'Hack', '399,00'),
    array('3', 'Table', '599,00'),
    array('4', 'Chair', '99,00')
    );

    foreach($products as $product)
    {   
        $key = '@@products.' . $product[0];
        $value = $product[1] . '|' . $product[2];
        $m->set($key, $value);
    }
?>
[root@mysql memcache]# php test4.php
mysql> SELECT * FROM memcached.products;
+----+-------+---------+------+------+------+
| id | name  | value   | c3   | c4   | c5   |
+----+-------+---------+------+------+------+
| 1  | TV    | 1999,00 |    0 |    3 |    0 |
| 2  | Hack  | 399,00  |    0 |    4 |    0 |
| 3  | Table | 599,00  |    0 |    5 |    0 |
| 4  | Chair | 99,00   |    0 |    6 |    0 |
+----+-------+---------+------+------+------+
4 rows in set (0.00 sec)

服務器/服務 重啟

讓我們看看如果我們重啟 MySQL 服務(重啟服務器通用適用)會發生什么?

這些存儲在 Memcached 中的數據在 MySQL 服務重啟之后仍然會存在嗎?

[root@mysql memcache]# service mysql restart
Shutting down MySQL...... SUCCESS!
Starting MySQL. SUCCESS!

[root@mysql memcache]# cat test5.php
<?php
    $m = new Memcache();
    $m->addServer('localhost', 11211);
    echo 'Value of key1 is:' . $m->get('key1') . "\n";
?>
[root@mysql memcache]# php test5.php
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 模塊來允許:

type=AVC msg=audit(1423266535.066:5): avc:  denied  { name_bind } for  \
pid=1123 comm="mysqld" src=11211 scontext=system_u:system_r:mysqld_t:s0 \
tcontext=system_u:object_r:memcache_port_t:s0 tclass=tcp_socket
type=SYSCALL msg=audit(1423266535.066:5): arch=c000003e syscall=49 \
success=no exit=-13 a0=2f a1=7f3aec043230 a2=10 a3=7f3af61fa75c \
items=0 ppid=999 pid=1123 auid=4294967295 uid=27 gid=27 euid=27 suid=27 \
fsuid=27 egid=27 sgid=27 fsgid=27 tty=(none) ses=4294967295 comm="mysqld" \
exe="/usr/sbin/mysqld" subj=system_u:system_r:mysqld_t:s0 key=(null)

[root@mysql ~]# audit2why < /var/log/audit/audit.log
type=AVC msg=audit(1423266535.066:5): avc:  denied  { name_bind } for  \
pid=1123 comm="mysqld" src=11211 scontext=system_u:system_r:mysqld_t:s0 \
tcontext=system_u:object_r:memcache_port_t:s0 tclass=tcp_socket

    Was caused by:
        Missing type enforcement (TE) allow rule.

        You can use audit2allow to generate a loadable module to allow this access.

[root@mysql ~]# cd /root/
[root@mysql ~]# mkdir selinux-custom
[root@mysql ~]# cd selinux-custom
[root@mysql selinux-custom]# audit2allow -a -M mysql-memcache
******************** IMPORTANT ***********************
To make this policy package active, execute:

semodule -i mysql-memcache.pp
[root@mysql selinux-custom]# semodule -i mysql-memcache.pp

譯者注:以下為譯者添加,用于測試在 SELinux 環境下,MySQL 和 Memcached 的集成。

[root@mysql selinux-custom]# sestatus
SELinux status:                 enabled
SELinuxfs mount:                /selinux
Current mode:                   enforcing
Mode from config file:          enforcing
Policy version:                 24
Policy from config file:        targeted
[root@mysql selinux-custom]# getenforce
Enforcing
[root@mysql selinux-custom]# /etc/init.d/mysql restart
Shutting down MySQL....                                    [  OK  ]
Starting MySQL.                                            [  OK  ]
[root@mysql memcache]# cd ~/memcache
[root@mysql memcache]# cat test6.php
<?php
    $m = new Memcache();
    $m->addServer('localhost', 11211);
    echo 'Value of key1 is:' . $m->get('key1') . "\n";
?>
[root@mysql selinux-custom]# netstat -tunap | grep LIST | grep mysql
tcp        0      0 0.0.0.0:11211               0.0.0.0:*                   LISTEN      7820/mysqld
tcp        0      0 :::11211                    :::*                        LISTEN      7820/mysqld
tcp        0      0 :::3306                     :::*                        LISTEN      7820/mysqld
[root@mysql memcache]# php test6.php
Value of key1 is:Entry modified  directly on MySQL

Memcached 選項

如果你想更改任何 Memcached 特殊的選項,你可以在 MySQL 的配置文件中添加daemon_memcached_option 參數,比如更改 Memcached 端口:

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

就是這樣,我希望你已經學會了如何安裝和配置 MySQL 和 Memcached 插件的集成工作。

原文:https://blog.marceloaltmann.com/mysql-nosql-memcached-plugin/ 作者: Marcelo Altmann
譯文:http://dbarobin.com/2015/02/07/mysql-nosql-memcached-plugin/ 譯者: 溫國兵

 本文由用戶 g2md 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!