通过MySQL的UDFs和Trigger操作Memcached

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介:

通过MySQL的UDFs和Trigger操作Memcached


UDFs是User Defined Functions的缩写,表示MySQL的用户定义函数,应用程序可以利用这些函数从MySQL 5.0以上版本的数据库中访问Memcached写入或者获取的数据。此外,MySQL从5.1版本开始支持触发器,从而可以在触发器中使用UDFs直接更新Memcached的内容,这种方式降低了应用程序设计和编写的复杂性。下面简单介绍UDFs的安装和使用。

 

UDFs安装



安装UDFs,需要依次安装MySQL、libevent、memcached、libmemcached、memcached_functions_sql。

 

1. 安装mysql-5.6.24.tar.gz

参照之前的博文《InnoDB memcached插件部署》中MySQL安装部分。

 

2. 安装libevent-2.0.22-stable.tar.gz和安装memcached-1.4.22.tar.gz

参照之前的博文《Memcached 1.4.22安装和配置》

 

3. 安装libmemcached-0.34.tar.gz

memcached functions for mysql官网发布的1.1版本是09年的,只兼容libmemcached0.34版本。

1
2
3
4
5
6
7
mkdir  -p  /usr/local/libmemcached
wget https: //launchpad .net /libmemcached/1 .0 /0 .34/+download /libmemcached-0 .34. tar .gz
tar  zxvf libmemcached-0.34. tar .gz
cd  libmemcached-0.34
. /configure  --prefix= /usr/local/libmemcached  --with-memcached= /usr/local/bin/memcached
make
make  install

 

4. 安装memcached_functions_mysql

1
2
3
4
5
6
wget https: //launchpad .net /memcached-udfs/trunk/1 .1/+download /memcached_functions_mysql-1 .1. tar .gz
tar  xvf memcached_functions_mysql-1.1. tar .gz
cd  memcached_functions_mysql-1.1
. /configure  --prefix= /usr/local/memcache_mysql  --with-mysql= /usr/local/mysql/bin/mysql_config  --with-libmemcached= /usr/local/libmemcached
make
make  install

 

5. 拷贝lib文件到mysql的plugin下面

1
cp  /usr/local/memcache_mysql/lib/libmemcached_functions /usr/local/mysql/lib/plugin

 

6. 配置动态链接库

1
2
echo  "/usr/local/lib"  >>  /etc/ld .so.conf
ldconfig

 

7. 添加memcache UDF 函数

1
mysql < . /sql/install_functions .sql

 

备注:

首次需要使用CREATE FUNCTION来初始化用户定义函数。有两种方法可以初始化所有MySQL提供的用户定义函数:

第一种方法是在MySQL的SQL命令行中执行memcached_functions_mysql源码目录下的sql/install_functions.sql。第二种方法是运行memcached_functions_mysql源码目录下的utils/install.pl这个Perl脚本,把memcache function作为UDFs加入MySQL。

 

8. 执行下面SQL命令,查看安装是否成功。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
mysql>  select  name ,dl  from  mysql.func;
+ ------------------------------+---------------------------------+
name  | dl |
+ ------------------------------+---------------------------------+
| memc_add | libmemcached_functions_mysql.so |
| memc_add_by_key | libmemcached_functions_mysql.so |
| memc_servers_set | libmemcached_functions_mysql.so |
| memc_server_count | libmemcached_functions_mysql.so |
| memc_set | libmemcached_functions_mysql.so |
| memc_set_by_key | libmemcached_functions_mysql.so |
| memc_cas | libmemcached_functions_mysql.so |
| memc_cas_by_key | libmemcached_functions_mysql.so |
| memc_get | libmemcached_functions_mysql.so |
| memc_get_by_key | libmemcached_functions_mysql.so |
| memc_get_cas | libmemcached_functions_mysql.so |
| memc_get_cas_by_key | libmemcached_functions_mysql.so |
| memc_delete | libmemcached_functions_mysql.so |
| memc_delete_by_key | libmemcached_functions_mysql.so |
| memc_append | libmemcached_functions_mysql.so |
| memc_append_by_key | libmemcached_functions_mysql.so |
| memc_prepend | libmemcached_functions_mysql.so |
| memc_prepend_by_key | libmemcached_functions_mysql.so |
| memc_increment | libmemcached_functions_mysql.so |
| memc_decrement | libmemcached_functions_mysql.so |
| memc_replace | libmemcached_functions_mysql.so |
| memc_replace_by_key | libmemcached_functions_mysql.so |
| memc_servers_behavior_set | libmemcached_functions_mysql.so |
| memc_servers_behavior_get | libmemcached_functions_mysql.so |
| memc_behavior_set | libmemcached_functions_mysql.so |
| memc_behavior_get | libmemcached_functions_mysql.so |
| memc_list_behaviors | libmemcached_functions_mysql.so |
| memc_list_hash_types | libmemcached_functions_mysql.so |
| memc_list_distribution_types | libmemcached_functions_mysql.so |
| memc_udf_version | libmemcached_functions_mysql.so |
| memc_libmemcached_version | libmemcached_functions_mysql.so |
| memc_stats | libmemcached_functions_mysql.so |
| memc_stat_get_keys | libmemcached_functions_mysql.so |
| memc_stat_get_value | libmemcached_functions_mysql.so |
+ ------------------------------+---------------------------------+
34  rows  in  set  (0.00 sec)

 

使用Trigger操作Memcached



1. 创建两张表

新建两张表:urls和results,更新urls表中的内容,使系统自动更新Memcached的内容。results用来记录更新Memcached失败的记录。

SQL代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
use test;
drop  table  if exists urls;
CREATE  TABLE  `urls` (
`id`  int (10)  NOT  NULL ,
`url`  varchar (255)  NOT  NULL  DEFAULT  '' ,
PRIMARY  KEY  (`id`)
);
drop  table  if exists results;
CREATE  TABLE  `results` (
`id`  int (10)  NOT  NULL ,
`result`  varchar (255)  NOT  NULL  DEFAULT  'error' ,
` time timestamp  NULL  DEFAULT  CURRENT_TIMESTAMP ,
PRIMARY  KEY  (`id`)
);

 

2. 建立3个trigger

当向urls表中插入数据时,对Memcached执行set操作。trigger的代码如下:

1
2
3
4
5
6
7
8
9
10
11
DELIMITER //
DROP  TRIGGER  IF EXISTS url_mem_insert;
CREATE  TRIGGER  url_mem_insert
BEFORE  INSERT  ON  urls
FOR  EACH ROW  BEGIN
set  @mm = memc_set(NEW.id, NEW.url);
if @mm <> 0  then
insert  into  results(id)  values (NEW.id);
end  if;
END  //
DELIMITER ;


当对urls表中的数据进行更新时,对Memcached执行replace操作。trigger代码如下:

1
2
3
4
5
6
7
8
9
10
11
DELIMITER //
DROP  TRIGGER  IF EXISTS url_mem_update;
CREATE  TRIGGER  url_mem_update
BEFORE  UPDATE  ON  urls
FOR  EACH ROW  BEGIN
set  @mm = memc_replace(OLD.id,NEW.url);
if @mm <> 0  then
insert  into  results(id)  values (OLD.id);
end  if;
END  //
DELIMITER ;


当对urls表中的数据进行删除操作时,对Memcached执行delete操作。trigger代码如下:

1
2
3
4
5
6
7
8
9
10
11
DELIMITER //
DROP  TRIGGER  IF EXISTS url_mem_delete;
CREATE  TRIGGER  url_mem_delete
BEFORE  DELETE  ON  urls
FOR  EACH ROW  BEGIN
set  @mm = memc_delete(OLD.ID);
if @mm <> 0  then
insert  into  results(id)  values (OLD.id);
end  if;
END  //
DELIMITER ;

 

3. 设置Memcached相关参数

设置UDFs操作Memcaced服务器的IP地址和端口。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
mysql>  SELECT  memc_servers_set( '192.168.11.52:11211' );
+ -----------------------------------------+
| memc_servers_set( '192.168.11.52:11211' ) |
+ -----------------------------------------+
| 0 |
+ -----------------------------------------+
1 row  in  set  (0.07 sec)
mysql> select  memc_server_count();
+ ---------------------+
| memc_server_count() |
+ ---------------------+
| 1 |
+ ---------------------+
1 row  in  set  (0.00 sec)


在MySQL命令行中列出可以修改Memcached参数的行为,执行的命令和输出结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
mysql> select  memc_list_behaviors()\G
*************************** 1. row ***************************
memc_list_behaviors():
MEMCACHED SERVER BEHAVIORS
MEMCACHED_BEHAVIOR_SUPPORT_CAS
MEMCACHED_BEHAVIOR_NO_BLOCK
MEMCACHED_BEHAVIOR_TCP_NODELAY
MEMCACHED_BEHAVIOR_HASH
MEMCACHED_BEHAVIOR_CACHE_LOOKUPS
MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE
MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE
MEMCACHED_BEHAVIOR_BUFFER_REQUESTS
MEMCACHED_BEHAVIOR_KETAMA
MEMCACHED_BEHAVIOR_POLL_TIMEOUT
MEMCACHED_BEHAVIOR_RETRY_TIMEOUT
MEMCACHED_BEHAVIOR_DISTRIBUTION
MEMCACHED_BEHAVIOR_BUFFER_REQUESTS
MEMCACHED_BEHAVIOR_USER_DATA
MEMCACHED_BEHAVIOR_SORT_HOSTS
MEMCACHED_BEHAVIOR_VERIFY_KEY
MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT
MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED
MEMCACHED_BEHAVIOR_KETAMA_HASH
MEMCACHED_BEHAVIOR_BINARY_PROTOCOL
MEMCACHED_BEHAVIOR_SND_TIMEOUT
MEMCACHED_BEHAVIOR_RCV_TIMEOUT
MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT
MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK
MEMCACHED_BEHAVIOR_IO_BYTES_WATERMARK
1 row  in  set  (0.00 sec)


设置MEMCACHED_BEHAVIOR_NO_BLOCK为打开状态,这样在Memcached出现问题(不能连接)时,数据可以继续插入MySQL中,但有报错提示;如果不设置此值,那么Memcached失败时,数据需要等到Memcached失败超时后才可以插入到表中。


通过下面的设置,可以避免这种情况的发生。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
mysql> select  memc_servers_behavior_set( 'MEMCACHED_BEHAVIOR_NO_BLOCK' , '1' );
+ --------------------------------------------------------------+
| memc_servers_behavior_set( 'MEMCACHED_BEHAVIOR_NO_BLOCK' , '1' ) |
+ --------------------------------------------------------------+
| 0 |
+ --------------------------------------------------------------+
1 row  in  set  (0.00 sec)
mysql> select  memc_servers_behavior_set( 'MEMCACHED_BEHAVIOR_TCP_NODELAY' , '1' );
+ -----------------------------------------------------------------+
| memc_servers_behavior_set( 'MEMCACHED_BEHAVIOR_TCP_NODELAY' , '1' ) |
+ -----------------------------------------------------------------+
| 0 |
+ -----------------------------------------------------------------+
1 row  in  set  (0.00 sec)

 

4. 对memcached_functions_mysql的简单功能进行测试

1)向表urls中插入数据,然后查看Memcached是否对数据执行set操作。

1
2
3
4
5
6
7
8
9
mysql> insert  into  urls (id,url)  values  (1,  'http://www.test.com.cn' );
Query OK, 1 row affected, 1 warning (0.00 sec)
mysql>  select  memc_get( '1' );
+ ------------------------+
| memc_get( '1' ) |
+ ------------------------+
| http://www.test.com |
+ ------------------------+
1 row  in  set  (0.00 sec)
1
2
3
4
5
6
7
8
1>telnet 192.168.11.52 11211
Trying 192.168.11.52...
Connected to 192.168.11.52 (192.168.11.52).
Escape character is  '^]' .
get 1
VALUE 1 0 22
http: //www . test .com.cn
END


2)更新表urls里面的数据,然后查询Memcached中是否也进行了更新。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
mysql> update  test.urls  set  url= 'http://blog.test.com.cn'  where  id=1;
Query OK, 1 row affected, 1 warning (0.00 sec)
Rows  matched: 1 Changed: 1 Warnings: 0
mysql>  select  memc_replace( '1' , 'http://blog.test.com.cn' );
+ ---------------------------------------------+
| memc_replace( '1' , 'http://blog.test.com.cn' ) |
+ ---------------------------------------------+
| 0 |
+ ---------------------------------------------+
1 row  in  set  (0.00 sec)
mysql>  select  memc_get( '1' );
+ -------------------------+
| memc_get( '1' ) |
+ -------------------------+
| http://blog.test.com.cn |
+ -------------------------+
1 row  in  set  (0.00 sec)
1
2
3
4
5
6
7
8
1>telnet 192.168.11.52 11211
Trying 192.168.11.52...
Connected to 192.168.11.52(192.168.11.52).
Escape character is  '^]' .
get 1
VALUE 1 0 23
http: //blog . test .com.cn
END


3)删除表urls中的数据,然后查看Memcached是否也将该数据删除了。

1
2
3
4
5
6
7
8
9
10
mysql> delete  from  test.urls  where  id=1;
Query OK, 1 row affected, 1 warning (0.00 sec)
Rows  matched: 1 Changed: 1 Warnings: 0
mysql>  select  memc_get( '1' );
+ ---------------+
| memc_get( '1' ) |
+ ---------------+
NULL  |
+ ---------------+
1 row  in  set  (0.00 sec)
1
2
3
4
5
6
1>telnet 192.168.11.52 11211
Trying 192.168.11.52...
Connected to 192.168.11.52 (192.168.11.52).
Escape character is  '^]' .
get 1
END

 

5. 使用memcached_functions_mysql的经验与技巧

memcached_functions_mysql使用起来比较简单,但是由于环境的差别,在实践过程中可能会遇到诸多的问题。下面总结了一些在使用memcached_functions_mysq过程中可能出现的问题和注意事项。


1) MySQL重启问题

如果MySQL服务器出现重启,需要重新设置连接Memcached关系(SELECT memc_servers_set('192.168.11.52:11211'))。


2) 程序BUG问题

memcached_functions_mysql的源程序有可能存在bug,并且会导致MySQL的失败。针对这个问题,读者要尽量选择源程序的稳定版本。


3) 网络因素

网络因素是指MySQL和Memcached是否处在同一个IDC、它们之间的网络性能是否很好。网络性能越好,则速度越快。使用本机的Memcached可以适当减少网络开销。


4) 插入的数据量

插入数据量的大小包含两个方面:向MySQL插入每条记录的大小,向Memcached中更新数据的大小。更新MySQL、Memcached的数据越大,更新的速度越慢。因此,要做好前期规划。


5) 延时问题

如果MySQL所在的机器使用的资源比较大,会导致更新Memcached过于缓慢,即出现类似m/s的延时问题。


6) 容灾问题

如果MySQL和Memcached中有宕机情况出现时,需要考虑怎么恢复,根据前一小节的测试可以这样考虑:建一张错误表,如果在更新mc时出现问题,自动把更新错误的记录插到这张表中,通过查询这张表,可以知道哪些数据在什么时间出现过更新错误。


如果memcached_functions_mysql应用于生产环境,需要考虑监控和出现问题时的恢复工作(写好脚本以完善这个工作)。


7) MySQL自身因素

如执行的MySQL语句的效率以及连接MySQL的client程序(php)的连接开销等,这些问题都需要考虑。

















本文转自UltraSQL51CTO博客,原文链接: http://blog.51cto.com/ultrasql/1641786,如需转载请自行联系原作者





相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
1月前
|
SQL 关系型数据库 MySQL
Python怎么操作Mysql数据库
Python怎么操作Mysql数据库
49 0
|
1月前
|
SQL 关系型数据库 MySQL
python如何操作mysql数据库
python如何操作mysql数据库
24 0
|
2月前
|
SQL 存储 算法
mysql常用指令操作
mysql常用指令操作
|
17天前
|
存储 SQL 关系型数据库
【MySQL】4. 表的操作
【MySQL】4. 表的操作
19 0
|
3月前
|
关系型数据库 MySQL
MySQL对小数进行四舍五入等操作
MySQL对小数进行四舍五入等操作
25 0
|
30天前
|
SQL 关系型数据库 MySQL
|
3月前
|
SQL 关系型数据库 MySQL
MySQL | 数据库的管理和操作【表的增删改查】(一)
MySQL | 数据库的管理和操作【表的增删改查】
|
3月前
|
SQL 关系型数据库 MySQL
MySQL | 数据库的管理和操作【表的增删改查】(二)
MySQL | 数据库的管理和操作【表的增删改查】(二)
|
16天前
|
缓存 关系型数据库 MySQL
MySQL查询优化:提速查询效率的13大秘籍(合理使用索引合并、优化配置参数、使用分区优化性能、避免不必要的排序和group by操作)(下)
MySQL查询优化:提速查询效率的13大秘籍(合理使用索引合并、优化配置参数、使用分区优化性能、避免不必要的排序和group by操作)(下)
|
1月前
|
存储 SQL 关系型数据库
【mysql】—— 表的操作
【mysql】—— 表的操作