热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

memcache与mysql数据库同步

1:mysqlmemcachedUDF其实就是通过libmemcached来使用memcache的一系列函数,通过这些函数,你能对memcache进行get,set,cas,append,prepend,delete,increment,decrementobjects操作,如果我们通过mysqltrigger来使用这些函数,那么就能通过mysql

1:mysql memcached UDF 其实就是通过libmemcached来使用memcache的一系列函数,通过这些函数,你能对memcache进行get, set, cas, append, prepend, delete, increment, decrement objects操作,如果我们通过mysql trigger来使用这些函数,那么就能通过mysql

1:mysql memcached UDF 其实就是通过libmemcached来使用memcache的一系列函数,通过这些函数,你能 对memcache进行get, set, cas, append, prepend, delete, increment, decrement objects操作,如果我们通过mysql trigger来使用这些函数,那么就能通过mysql更好的,更自动的管理memcache!

2:安装方法:

1)安装memcache

2)安装libmemcached

shell> cd libmemcached-0.35
shell> ./configure --with-memcached=/usr/local/bin/memcached
shell> make && make install
shell> echo "/usr/local/lib" >> /etc/ld.so.conf
shell> ldconfig

3)安装memcached_functions_mysql
shell> tar zxvf memcached_functions_mysql-0.9.tar.gz
shell> cd memcached_functions_mysql-0.9
shell> ./configure --with-mysql=/usr/local/mysql51/bin/mysql_config --with-libmemcached =/usr/local/
shell> make && make install

4)拷贝lib文件到mysql的plugin下面
shell> cp -R /usr/local/lib/libmemcached_functions_mysql.* /usr/local/mysql51/lib/mysql/plugin/

5)添加memcache UDF 函数

在mysql里执行 source install_functions.sql

这样我们就可以使用mysql memcached UDF 了,我们可以通过下面语句查看是否已经正常安装

1)查看mysql.func,有很多函数

mysql> select * from mysql.func;
+------------------------------+-----+---------------------------------+----------+
| name | ret | dl | type |
+------------------------------+-----+---------------------------------+----------+
| memc_add | 2 | libmemcached_functions_mysql.so | function |
| memc_add_by_key | 2 | libmemcached_functions_mysql.so | function |
| memc_servers_set | 2 | libmemcached_functions_mysql.so | function |

2)添加trigger,看是否向memcache里insert、update等

具体的语句,我们可以参照:

1)memcached_functions_mysql-0.9/sql 目录下的trigger_fun.sql

2)使用参照文档:http://dev.mysql.com/doc/refman/5.1/en/ha-memcached-interfaces-mysqludf.html


我们还必须注意以下几点:

1)mysql 编译时一定不要带'--with-mysqld-ldflags=-all-static' 这个参数,因为这样就限制了mysql 的动态安装功能了

2)使用时,要观察mysql.err日志,不知道是有意还是无意,udf更新memcache都会记录在err日志里,注意清理该日志,否则一下就爆满了

3)mysql 官网有这样一句话:

The list of servers used by the memcached UDFs is not persistent over restarts of the MySQL server. If the MySQL server fails, then you must re-set the list of memcached servers.

所以,当我们重启mysql,我们必须通过select memc_servers_set('192.168.0.1:11211,192.168.0.2:11211');语句重新注册memcache服务器!

2、创建mysql的insert,update,delete触发器更新memcache,参考http://blog.csdn.net/jiedushi/article/details/6176940

测试环境在Linux下进行,版本系统为CentOS5.
以下为相关软件,包括其版本和下载地址:

mysql-5.1.30 下载
memcached-1.2.6 下载
libevent-1.4.7-stable 下载
memcached_functions_mysql-1.1 下载
libmemcached-0.26 下载


编译安装MySQL,安装因个人细好而定,省略许多与测试无关的编译细节及参数。

[c] view plaincopyprint?

  1. [root@localhost ~]#tar xzf mysql-5.1.30.tar_001.gz
  2. [root@localhost ~]#cd mysql-5.1.30
  3. [root@localhost ~]#./configure --prefix=/usr/local/mysql51
  4. [root@localhost ~]#make
  5. [root@localhost ~]#make install
  6. [root@localhost ~]#./scripts/mysql_install_db --user=mysql --skip-name-resolve
  7. [root@localhost ~]#/usr/local/mysql51/bin/mysqld_safe

省略列出安装memcached和libevent的相关命令,具体可按照实际情况安装,测试时我将libevent默认安装,memcached安装于/usr/local/memcached目录下。
启动memcached.

[c] view plaincopyprint?

  1. /usr/local/memcached/bin/memcached -d -m 50 -u root -p 11211

编译安装libmemcache.

[c] view plaincopyprint?

  1. [root@localhost ~]#tar xzf libmemcached-0.26.tar.gz
  2. [root@localhost ~]#cd libmemcached-0.26
  3. [root@localhost ~]#./configure --with-memcached=/usr/local/memcached/bin/memcached
  4. [root@localhost ~]# make && make install

编译安装Memcache UDFs for MySQL.

[c] view plaincopyprint?

  1. [root@localhost ~]# tar xzf memcached_functions_mysql-1.1.tar.gz
  2. [root@localhost ~]# cd memcached_functions_mysql-1.1
  3. [root@localhost ~]# ./configure --with-mysql-cOnfig=/usr/local/mysql51/bin/mysql_config
  4. [root@localhost ~]# make && make install

编译完成后将编译好的库文件复制到mysql的插件目录下,以便于加载使用。

[c] view plaincopyprint?

  1. cp /usr/local/lib/libmemcached_functions_mysql* /usr/local/mysql51/lib/mysql/plugin/

进入memcached_functions_mysql的源码目录,在目录下有相关添加UDF的SQL文件用于初始化。

在mysql的shell中执行memcached_functions_mysql源码目录下的sql/install_functions.sql
或者运行memcached_functions_mysql源码目录下utils/install.pl这个perl脚本,把memcache function作为UDF加入mysql。

[root@localhost ~]# mysql

检查安装是否成功


mysql> select name,dl from mysql.func;

二. 测试用例设计情况:

(1).新建两张表:urls和results,用来更新urls表里面的内容,让系统自动更新memcached的内容。results用来记录更新memcached失败的记录。
sql语句如下:
use tests;
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). 建立三个trigger.

当向urls表里面插入数据时,对memcached执行set操作,trigger如下:
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如下:

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如下:

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相关参数

设置同时UDF操作的memcaced的机器IP和端口:

mysql> SELECT memc_servers_set('192.168.3.184:11900');
&#43;---------------------------------------&#43;
| memc_servers_set('192.168.3.184:11900') |
&#43;---------------------------------------&#43;
| 0 |
&#43;---------------------------------------&#43;
1 row in set (0.00 sec)


mysql> select memc_server_count();
&#43;---------------------&#43;
| memc_server_count() |
&#43;---------------------&#43;
| 1 |
&#43;---------------------&#43;
1 row in set (0.00 sec)


在mysql命令行列出可以修改memcached参数的行为:
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中,报错提示,如果不设置此&#20540;,如果memcached失败,mysql需要等到timeout
才可以插入到表中。
mysql> select memc_servers_behavior_set('MEMCACHED_BEHAVIOR_NO_BLOCK','1');
&#43;--------------------------------------------------------------&#43;
| memc_servers_behavior_set('MEMCACHED_BEHAVIOR_NO_BLOCK','1') |
&#43;--------------------------------------------------------------&#43;
| 0 |
&#43;--------------------------------------------------------------&#43;
1 row in set (0.00 sec)

mysql> select memc_servers_behavior_set('MEMCACHED_BEHAVIOR_TCP_NODELAY','1');
&#43;-----------------------------------------------------------------&#43;
| memc_servers_behavior_set('MEMCACHED_BEHAVIOR_TCP_NODELAY','1') |
&#43;-----------------------------------------------------------------&#43;
| 0 |
&#43;-----------------------------------------------------------------&#43;
1 row in set (0.00 sec)


三. 简单的功能测试:


1. 向表urls里面插入数据,然后查memcached是否也set进数据:

mysql> insert into urls (id,url) values (1, 'http://www.sina.com.cn');
Query OK, 1 row affected, 1 warning (0.00 sec)

mysql> select memc_get('1');
&#43;------------------------&#43;
| memc_get('1') |
&#43;------------------------&#43;
| http://www.sina.com.cn |
&#43;------------------------&#43;
1 row in set (0.00 sec)


1> telnet 192.168.3.184 11900
Trying 192.168.3.184...
Connected to 192.168.3.184 (192.168.3.184).
Escape character is '^]'.
get 1
VALUE 1 0 22
http://www.sina.com.cn
END


2.更新表urls里面的数据,然后查询memcached里面是否也更新:
mysql> update test.urls set url='http://blog.sina.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.sina.com.cn');
&#43;---------------------------------------------&#43;
| memc_replace('1','http://blog.sina.com.cn') |
&#43;---------------------------------------------&#43;
| 0 |
&#43;---------------------------------------------&#43;
1 row in set (0.00 sec)

mysql> select memc_get('1');
&#43;-------------------------&#43;
| memc_get('1') |
&#43;-------------------------&#43;
| http://blog.sina.com.cn |
&#43;-------------------------&#43;
1 row in set (0.00 sec)


1> telnet 192.168.3.184 11900
Trying 192.168.3.184...
Connected to 192.168.3.184 (192.168.3.184).
Escape character is '^]'.
get 1
VALUE 1 0 23
http://blog.sina.com.cn
END


3.删除表urls里面的数据,然后查memcached是否也删除:
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');
&#43;---------------&#43;
| memc_get('1') |
&#43;---------------&#43;
| NULL |
&#43;---------------&#43;
1 row in set (0.00 sec)


1> telnet 192.168.3.184 11900
Trying 192.168.3.184...
Connected to 192.168.3.184 (192.168.3.184).
Escape character is '^]'.
get 1
END

四. 利用php脚本insert, update,delete表urls里面的数据,进行测试。

每条记录的平均长度是:17K

单独向表urls里面插入10万条记录需要的时间为:75秒
单独对表urls里面更新10万条记录需要的时间为:70秒
单独对表urls里面删除10万条记录需要的时间为:105秒

同时进行30万数据的insert,update, delete操作需要时间为:241秒

上面操作都没有memcached失败情况:
mysql> select * from results;
Empty set (0.00 sec)


测试脚本如下:

插入脚本:
0> more a.php

$cOnn= mysql_connect("192.168.1.61","test","test") or die(mysql_error());

mysql_select_db("test",$conn) or die(mysql_error());

//$sql = "show tables";

echo date("Y-m-d H:i:s");
//mysql_query($sql) or die(mysql_error());

for ($i=1; $i<=100000; $i&#43;&#43;) {
$sql="insert into urls (id,url) values ($i, 'http://$i$i$i$i$i$i$i$i$i$i$i$i$i$i$i$i$i$i$i$i$i$i$i$i$i.com');";
mysql_query($sql) or die(mysql_error());
}

echo "/n";
echo date("Y-m-d H:i:s");

?>

更新脚本:
0> more b.php

$cOnn= mysql_connect("192.168.1.61","test","test") or die(mysql_error());

mysql_select_db("test",$conn) or die(mysql_error());

//$sql = "show tables";

echo date("Y-m-d H:i:s");
//mysql_query($sql) or die(mysql_error());

for ($i=1; $i<=100000; $i&#43;&#43;) {
$sql="update test.urls set url='http://xxxx.$i$i$i$i$i$i$i$i$i$i$i$i$i$i$i$i$i$i$i$i$i$i$i$i$i$i$i.com' where id=$i;";
mysql_query($sql) or die(mysql_error());
}

echo "/n";
echo date("Y-m-d H:i:s");

?>

删除脚本:
0> more c.php

$cOnn= mysql_connect("192.168.1.61","test","test") or die(mysql_error());

mysql_select_db("test",$conn) or die(mysql_error());

//$sql = "show tables";

echo date("Y-m-d H:i:s");
//mysql_query($sql) or die(mysql_error());

for ($i=1; $i<=100000; $i&#43;&#43;) {
$sql="delete from test.urls where id=$i;";
mysql_query($sql) or die(mysql_error());
}

echo "/n";
echo date("Y-m-d H:i:s");

?>


五. 结论:
测试依赖的环境比较多,可能数据会不准确。整体来看速度还不错。
适合项目应用相对比较小的场合。

优点:
触发器中使用 UDFs 直接更新 Memcached 的内容,减轻了应用程序设计和编写的复杂性。

缺点:
1. 如果出现mysql服务重启,需要重新设置连接memcached关系(SELECT memc_servers_set('192.168.3.184:11900'))
2. 有可能存在bug问题,导致mysql的crash(测试时没遇到:)).


真正的线上环境比这个复杂很多。我想到的需要考虑的问题:
1. 网络因素,mysql和memcached是否放在同一IDC,他们之间的网络性能是否很好。网络性能越好,速度肯定越快,如果使用本机的memcached能适当的减少网络开销。
2. 插入的数据量,向mysql插入每条记录的size,以及向memcached里面更新的数据size大小。更新mysql,memcached的数据size越大,更新的速度越慢。
所以前期规划好,在memcached里面存那两列(key-value)是关键。
3. 延时问题需要考虑,mysql所在机器如果资源使用比较狠,会导致更新memcached慢(出现类&#20284;m/s的延时问题)。
4. 考虑容灾问题,如果两者中有down出现时,需要考虑怎么恢复,当前的测试是这样考虑的:建一张错误表,如果在出现更新mc出现问题时,自动把更新错误的记录插到
一张表里面,通过查这张表,可以知道哪些数据在什么时间更新错误,如果应用于生产环境,需要考虑监控和出现问题时恢复工作(写好脚本完善这个工作)。
5. mysql自身因素,例如执行的mysql语句效率,以及连接mysql的client程序(php)的连接开销等等。

参考

http://blog.sina.com.cn/s/blog_499740cb0100g45p.html

http://www.libing.name/2009/02/06/mysql-map-data-to-memcached.html

推荐阅读
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • CentOS 7部署KVM虚拟化环境之一架构介绍
    本文介绍了CentOS 7部署KVM虚拟化环境的架构,详细解释了虚拟化技术的概念和原理,包括全虚拟化和半虚拟化。同时介绍了虚拟机的概念和虚拟化软件的作用。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • 本文介绍了在Mac上搭建php环境后无法使用localhost连接mysql的问题,并通过将localhost替换为127.0.0.1或本机IP解决了该问题。文章解释了localhost和127.0.0.1的区别,指出了使用socket方式连接导致连接失败的原因。此外,还提供了相关链接供读者深入了解。 ... [详细]
  • 本文介绍了在CentOS上安装Python2.7.2的详细步骤,包括下载、解压、编译和安装等操作。同时提供了一些注意事项,以及测试安装是否成功的方法。 ... [详细]
  • CEPH LIO iSCSI Gateway及其使用参考文档
    本文介绍了CEPH LIO iSCSI Gateway以及使用该网关的参考文档,包括Ceph Block Device、CEPH ISCSI GATEWAY、USING AN ISCSI GATEWAY等。同时提供了多个参考链接,详细介绍了CEPH LIO iSCSI Gateway的配置和使用方法。 ... [详细]
  • centos安装Mysql的方法及步骤详解
    本文介绍了centos安装Mysql的两种方式:rpm方式和绿色方式安装,详细介绍了安装所需的软件包以及安装过程中的注意事项,包括检查是否安装成功的方法。通过本文,读者可以了解到在centos系统上如何正确安装Mysql。 ... [详细]
  • Centos下安装memcached+memcached教程
    本文介绍了在Centos下安装memcached和使用memcached的教程,详细解释了memcached的工作原理,包括缓存数据和对象、减少数据库读取次数、提高网站速度等。同时,还对memcached的快速和高效率进行了解释,与传统的文件型数据库相比,memcached作为一个内存型数据库,具有更高的读取速度。 ... [详细]
  • 腾讯安全平台部招聘安全工程师和数据分析工程师
    腾讯安全平台部正在招聘安全工程师和数据分析工程师。安全工程师负责安全问题和安全事件的跟踪和分析,提供安全测试技术支持;数据分析工程师负责安全产品相关系统数据统计和分析挖掘,通过用户行为数据建模为业务决策提供参考。招聘要求包括熟悉渗透测试和常见安全工具原理,精通Web漏洞,熟练使用多门编程语言等。有相关工作经验和在安全站点发表作品的候选人优先考虑。 ... [详细]
  • Python项目实战10.2:MySQL读写分离性能优化
    本文介绍了在Python项目实战中进行MySQL读写分离的性能优化,包括主从同步的配置和Django实现,以及在两台centos 7系统上安装和配置MySQL的步骤。同时还介绍了创建从数据库的用户和权限的方法。摘要长度为176字。 ... [详细]
  • 本文介绍了使用CentOS7.0 U盘刻录工具进行安装的详细步骤,包括使用USBWriter工具刻录ISO文件到USB驱动器、格式化USB磁盘、设置启动顺序等。通过本文的指导,用户可以轻松地使用U盘安装CentOS7.0操作系统。 ... [详细]
  • 本文详细介绍了SQL日志收缩的方法,包括截断日志和删除不需要的旧日志记录。通过备份日志和使用DBCC SHRINKFILE命令可以实现日志的收缩。同时,还介绍了截断日志的原理和注意事项,包括不能截断事务日志的活动部分和MinLSN的确定方法。通过本文的方法,可以有效减小逻辑日志的大小,提高数据库的性能。 ... [详细]
  • 本文介绍了Python高级网络编程及TCP/IP协议簇的OSI七层模型。首先简单介绍了七层模型的各层及其封装解封装过程。然后讨论了程序开发中涉及到的网络通信内容,主要包括TCP协议、UDP协议和IPV4协议。最后还介绍了socket编程、聊天socket实现、远程执行命令、上传文件、socketserver及其源码分析等相关内容。 ... [详细]
  • 如何在php中将mysql查询结果赋值给变量
    本文介绍了在php中将mysql查询结果赋值给变量的方法,包括从mysql表中查询count(学号)并赋值给一个变量,以及如何将sql中查询单条结果赋值给php页面的一个变量。同时还讨论了php调用mysql查询结果到变量的方法,并提供了示例代码。 ... [详细]
author-avatar
夜冷
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有