??xml version="1.0" encoding="utf-8" standalone="yes"?> 1. 起因Q?随着twitter sina微博Q腾讯微博的开攑^台相l推? 大部分和互联|相关的公司又多了一个营销的手D:信息同步。也x用户把自q新浪微博账号或者腾讯微博̎号和你的|站兌h了,用户在你的网站生的 M信息都可以同步发送到sina微博Qqq微博上去Q前提是l过用户的允许,q样用户既可以不需要同L信息复制到多个网站, 又可以相应的推广你的|站的入口曝光率Q。目前同步比较好的例子是Q微博通,街旁Q切客等?br /> 3. pȝ扩展?br /> a). 如果脚本处理q慢Q可能造成~冲队列拥堵Q我们可能通过扩展后台脚本个数来加快同步到W三方^台的处理速度?br /> b). 如果需要同步的信息量过? 造成写入队列的ƈ发数极大Q肯能通过扩展队列服务来达到分散减压的目的(基本不会出现)?/p> 5. 效率如何 假设你的|站每天产生100W条信?需要同步到W三方^台?br /> redis官方试数据QSET操作每秒?110000 ơ,GET操作每秒?81000 ơ)?br /> 一个脚本每天的同步? 86400/2 = 43200, (假设q_每同步一条信息花Ҏ(gu)间ؓ2sQ? 一个脚本每天大概可以同?W条数据?br /> q_每秒同步的数?100W/86400 < 12?高峰时期扩大十倍也是每秒 120条信息。由此可见每?00W 甚至 1000W的信息同步量对redis来说都是没有M压力的?br /> 我们只需要加快脚本处理的速度卛_Q?100W数据只需要同?5个脚本负责同步即可,Q数据量增加了,扩展h非常斚wQ?/p> ȝQ此方式已经应用于国内某LBSCQ每天的PV大概300WQ生的信息同步量每天大?W左右。当前是2个脚本负责同步相x作,队列里面基本没有M拥堵信息?/p>
2. Z么要用缓冲队列服务,我们举个例子。如果你做了一个网站,用户在你的网站上兌了sina微博QQQ微博Q开心网Qh人网Q? 豆瓣Qtwitter, facebookQ可能还要在国外讄代理Q等{第三方q_Q用户生了一个动作后Q比如发了一条心情状态)Q你的网站要同时同步到这些网站去Q每个第? 方^台都要经q多ơ外|httphQ所有的q些h加v来是可能是很长的旉(几秒Q? 甚至几十U?Q这对于前段用户肯定肯定是无法忍受的。所以这个时候同步信息的话必采取异步的方式Q也是用户在你的网站发表一个状态服务端只是把这条状 体对应的信息存储hQ?然后提C用户发表成功, 具体的信息同步是后端以脚本的方式异步q行的。用户通俗的话来说是用户先发表后同步Q由于校本执行速度很快Q? 用户几乎感觉不出来同步的旉差。你也许会问我怎么知道哪些信息要同步到W三方^台去呢,q也是使用redis使用~冲队列服务器的原因Q当用户发表? 息后Q我们同事把信息写入~冲队列服务器,后台脚本会不停的L查缓冲队列服务器是否有数据,如果有数据则取出发送到W三方开攑^台?/p>
]]>
差不多在一q前Q写q一文章介l?a target="_blank">MySQL数据映射到MemcachedQ当时MySQL和Memcached Functions for MySQL都还不够成熟Q时q一q_Memcached Functions for MySQL升C0.8版本Q而MySQL也发布了GA版本Q加上很多朋友反应前一文章中的实C们因U种原因没能成功Q于是便有了q篇文章Q就当是上一文章的升版本吧?/p>
试环境在Linux下进行,版本pȝ为CentOS5.
以下为相兌YӞ包括其版本和下蝲地址Q?/p>
mysql-5.1.30 下蝲
memcached-1.2.6 下蝲
libevent-1.4.7-stable 下蝲
memcached_functions_mysql-0.8 下蝲
libmemcached-0.26 下蝲
~译安装MySQL,安装因个人细好而定Q省略许多与试无关的编译细节及参数?/p>
[root@localhost ~]#tar xzf mysql-5.1.30.tar_001.gz [root@localhost ~]#cd mysql-5.1.30 [root@localhost ~]#./configure --prefix=/usr/local/mysql51 [root@localhost ~]#make [root@localhost ~]#make install [root@localhost ~]#./scripts/mysql_install_db --user=mysql --skip-name-resolve [root@localhost ~]#/usr/local/mysql51/bin/mysqld_safe
省略列出安装memcached和libevent的相兛_令,具体可按照实际情况安装,试时我libevent默认安装Qmemcached安装?usr/local/memcached目录下?br /> 启动memcached.
/usr/local/memcached/bin/memcached -d -m 50 -u root -p 11211
~译安装libmemcache.
[root@localhost ~]#tar xzf libmemcached-0.26.tar.gz [root@localhost ~]#cd libmemcached-0.26 [root@localhost ~]#./configure --with-memcached=/usr/local/memcached/bin/memcached [root@localhost ~]# make && make install
~译安装Memcache UDFs for MySQL.
[root@localhost ~]# tar xzf memcached_functions_mysql-0.8.tar.gz [root@localhost ~]# cd memcached_functions_mysql-0.8 [root@localhost ~]# ./configure --with-mysql-config=/usr/local/mysql51/bin/mysql_config [root@localhost ~]# make && make install
~译完成后将~译好的库文件复制到mysql的插件目录下Q以便于加蝲使用?/p>
cp /usr/local/lib/libmemcached_functions_mysql* /usr/local/mysql51/lib/mysql/plugin/
q入memcached_functions_mysql的源码目录,在目录下有相x加UDF的SQL文g用于初始化?/p>
[root@localhost ~]# mysql <sql/install_functions.sql
注:如果对这些UDFs不熟(zhn)或者不懂,可进行源码目录参?a target="_blank">READMEQ里Ҏ(gu)相应的说明?/p>
xQ相兌Y件的~译和安装完成,q行试Q我们要辑ֈ的目的是当MySQL有新记录插入Ӟ同时插入到Memcached中,当记录更新时同步更新Memcached中的记录Q删除时同时也删除Memcached相关的记录,为此创徏三个触发器来实现Q如果对MySQL的触发程序不熟?zhn)可以参考MySQL手册W?1章,下面SQL中的memcached为需要操作的表名QSQL如下Q?/p>
#插入数据时插入Memcached create trigger mysqlmmci after insert on memcached for each row set @tmp = memc_set(NEW.key, NEW.value); #更新记录时更新Memcached create trigger mysqlmmcu after update on memcached for each row set @tmp = memc_set(NEW.key, NEW.value); #删除记录时删除Memcached相应的记?/span> create trigger mysqlmmcd before delete on memcached for each row set @tmp = memc_delete(OLD.key);
以下为测试记录,在对MySQL操作的同时操作Memcached来查看情况,当然你也可以在启动Memcached的时候带-vv参数来查看相关信?
MySQL操作相关的记录:
[root@localhost ~]#mysql -S /tmp/mysql51.sock Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 6 Server version: 5.1.30 Source distribution Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql> use test; Database changed mysql> create table `memcached` (`key` varchar(10), `value` varchar(100)); Query OK, 0 rows affected (0.00 sec) mysql> create trigger mysqlmmci after insert on memcached for each row set @tmp = memc_set(NEW.key, NEW.value); Query OK, 0 rows affected (0.00 sec) mysql> create trigger mysqlmmcu after update on memcached for each row set @tmp = memc_set(NEW.key, NEW.value); Query OK, 0 rows affected (0.00 sec) mysql> create trigger mysqlmmcd before delete on memcached for each row set @tmp = memc_delete(OLD.key); Query OK, 0 rows affected (0.00 sec) mysql> insert into memcached values("keyi", "valuei"),("keyu","valueu"),("keyd", "valued"); Query OK, 3 rows affected (0.00 sec) Records: 3 Duplicates: 0 Warnings: 0 mysql> update memcached set `value`="update" where `key`="keyu"; Query OK, 1 row affected (0.00 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> delete from memcached where `key`="keyd"; Query OK, 1 row affected (0.00 sec) mysql> quit Bye
Memcache查看时的记录Q?/p>
[root@localhost ~]#telnet 127.0.0.1 11211 Trying 127.0.0.1... Connected to 127.0.0.1. Escape character is '^]'. get keyi VALUE keyi 0 6 valuei END get keyu VALUE keyu 0 6 valueu END get keyd VALUE keyd 0 6 valued END get keyu VALUE keyu 0 6 update END get keyd END quit Connection closed by foreign host.
xQ我们基本实现的MySQL的数据同步到Memcached中,性能暂时q没有测试,当然上面只是单的实现的数据映的功能Q如果在实现的生产环境中Q则需要考虑名字I间Q高可靠性的问题Q这些都是可以通过数据库名-表名-关键字的斚w能达到KEY唯一的目的,而高可靠性则是一个比较大的问题?/p>