利用HandlerSocket让MySQL具有NoSQL功能
上一篇 / 下一篇 2011-06-06 22:00:40 / 个人分类:mysql
目前使用MySQL的网站,多半同时使用Memcache作为键值缓存。虽然这样的架构极其流行,有众多成功的案例,但过于依赖Memcache,无形中让Memcache成为故障的根源:51Testing软件测试网,sX7W/eM$P6EJoN*]@
- Memcache数据一致性的问题:当MySQL数据变化后,如果不能及时有效的清理掉过期的数据,就会造成数据不一致。这在强调即时性的Web2.0时代,不可取。
- Memcache崩溃后的雪崩效应:作为缓存的Memcache一旦崩溃,MySQL很可能在短时间内承受高负载而宕机。据说前段时间新浪微博就遭遇了这样的问题。
注:关于清理过期数据的问题,可以在程序架构上想办法,如果数据操作有统一DAO封装的话,可以利用Observer模式来清理过期数据,非主题内容,资料自查。51Testing软件测试网_-ye1DX;A,y3[
面对这些问题,HandlerSocket项目是个不错的解决方案,它通过插件的方式赋予MySQL完整的NoSQL功能,从原理上讲,它跳过MySQL中最耗时的语法解析,查询计划等步骤,直接读取数据,如果内存够大,能装下索引,MySQL的查询效率能提高若干倍!51Testing软件测试网5Rq/Z)T5M7B)h
性能测试:Using MySQL as a NoSQL – A story for exceeding 750,000 qps51Testing软件测试网!^4L(NP O5qX8N
因为HandlerSocket的性能足够好,所以就没有必要使用Memcache了,能节省大量的硬件资源,相当低碳!而且HandlerSocket操作的是MySQL放在内存中的索引,没有额外的缓存,所以自然就不存在数据一致性的问题。51Testing软件测试网9K `8B_ N5VaD
安装
}h:?)Xt1J X0如果使用Percona Server版本的MySQL就简单了,因为它已经内置了HandlerSocket支持,不过考虑到其内置的版本不够新,存在一些早已修复的BUG,所以最好采用源代码编译。51Testing软件测试网!wa"G H O9d
注:旧版本HandlerSocket的一些问题可参见:What’s up with HandlerSocket?51Testing软件测试网cXC Or O9Sh!LDL
官方已经有了一份简单的安装文档,但在我实际安装时,遇到了一些其他未说明的问题,所以这里就把相应的安装过程再写一遍。51Testing软件测试网&@ g Y%hiYz
首先要确保已经安装了MySQL5.1以上的版本,我用的是Ubuntu操作系统,事先已经用apt安装了MySQL5.1.37,同时还需要相应的mysql_config,如果是Ubuntu的话,可以:
Y8Y r~$Dxs7ud#b%dG0 n5bf(P(PaB0shell> aptitude install libmysqld-dev |
51Testing软件测试网ta+r`ZP]v#O{
注:如果你用的MySQL是从源代码编译的或官方提供的二进制版本,可以略过此步。51Testing软件测试网&DF P hB-t7c"@
接着下载一份和系统MySQL版本一致的MySQL源代码和HandlerSocket源代码:
1o? \]#A8Yk ]!x5Y0n0mysql-5.1.37.tar.gz
1D2x{ k!P0A[0ahiguti-HandlerSocket-Plugin-for-MySQL-1.0.6-76-gf5f7443.tar.gz
U"PPd1KZx6ZU0bHVwy0 shell> tar zxf mysql-5.1.37.tar.gz shell> tar zxf ahiguti-HandlerSocket-Plugin-for-MySQL-1.0.6-76-gf5f7443.tar.gz shell> cd ahiguti-HandlerSocket-Plugin-for-MySQL-f5f7443 shell> ./autogen.sh shell> ./configure --with-mysql-source=../mysql-5.1.37 \ --with-mysql-bindir=/usr/bin \ --with-mysql-plugindir=/usr/lib/mysql/plugin |
其中的参数含义如下:with-mysql-source表示MySQL源代码目录,with-mysql-bindir表示MySQL二进制可执行文件目录(也就是mysql_config所在目录),with-mysql-plugindir表示MySQL插件目录,如果不清楚这个目录在哪,可以按如下方法查询:51Testing软件测试网T4G/GK(p }&G4Q
ib*_,I9s_)^s&ht*{0mysql> SHOW VARIABLES LIKE 'plugin%'; +---------------+-----------------------+ | Variable_name | Value | +---------------+-----------------------+ | plugin_dir | /usr/lib/mysql/plugin | +---------------+-----------------------+ |
51Testing软件测试网 t!V!I lp(nf4c
运行命令后,如果你使用的是MySQL5.1.37版本的话,会遇到如下错误信息:
AY|;tI y Ex!NR:F0h0MySQL source version does not match MySQL binary version
#\+N1L] u0明明我们的MySQL源代码版本和二进制版本都是5.1.37,为什么还会出现这个错误呢?通过查询HandlerSocket的编译脚本,发现原来它会检索MySQL源代码目录中的VERSION文件,可MySQL5.1.37的源代码目录里不知何故竟然没有这个文件,所以就报错了,既然知道了原因,那我们就照猫画虎做一个VERSION文件放到MySQL源代码目录,内容如下:
-q~ L.@5t!mC ? ](Nkq051Testing软件测试网c'E6\6Sa{F.Z;F
MYSQL_VERSION_MAJOR=5 MYSQL_VERSION_MINOR=1 MYSQL_VERSION_PATCH=37 MYSQL_VERSION_EXTRA= |
再次运行configure脚本,应该就OK了,把剩下的步骤进行完:
W6[!ui;wE#M xjr0e9K%KBOd,W d0 shell> make shell> make install |
51Testing软件测试网vW%wy~
接着需要配置一下HandlerSocket,编辑MySQL配置文件,加入如下内容:51Testing软件测试网^$ca ndg$C
4R^O6BrRs1T6}0 [mysqld] loose_handlersocket_port = 9998 # the port number to bind to (for read requests) loose_handlersocket_port_wr = 9999 # the port number to bind to (for write requests) loose_handlersocket_threads = 16 # the number of worker threads (for read requests) loose_handlersocket_threads_wr = 1 # the number of worker threads (for write requests) open_files_limit = 65535 # to allow handlersocket accept many concurrent # connections, make open_files_limit as large as # possible. |
此外,InnoDB的innodb_buffer_pool_size,或MyISAM的key_buffy_size等关系到缓存索引的选项尽可能设置大一些,这样才能发挥HandlerSocket的潜力。51Testing软件测试网? L7pN"QEbE
注:apt包管理下的配置文件一般是/etc/mysql/my.cnf,否则一般是/etc/my.cnf
%m_G$n!u4U0最后登陆MySQL并激活HandlerSocket插件:51Testing软件测试网#T#G%K2`MTd:E?u
51Testing软件测试网.T8S~ \1X._f
mysql> INSTALL PLUGIN handlersocket soname 'handlersocket.so'; |
如果没有问题的话,就能在MySQL里看到HandlerSocket的线程了:
8_'b8`-x+ZF B$X05n{'|LHN^fvk0mysql> SHOW PROCESSLIST; |
也可以通过查询刚配置的端口是否已经被MySQL占用来确认是否安装成功:51Testing软件测试网v&kTx:mc?H+t{!^
V&LgA;aL7H0 shell> lsof -i :9998 shell> lsof -i :9999 |
51Testing软件测试网8`r#uWE/f9M#?!p
完活儿!现在你的MySQL已经具备NoSQL的能力了!51Testing软件测试网.h}0WQ\'R(oZ0j
实战51Testing软件测试网3|t(KC {p\E
首先创建一个测试用的表:51Testing软件测试网&Y.q2x/ND+_z
"dK&L!@JM0 CREATE TABLE IF NOT EXISTS `test`.`t` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `a` varchar(10) NOT NULL, `b` varchar(10) NOT NULL, PRIMARY KEY (`id`), KEY `a_b` (`a`,`b`) ) ENGINE=InnoDB; |