MySQL下的NoSQL解决方案HandlerSocket

 目前使用MySQL的网站,多半同时使用Memcache作为键值缓存。虽然这样的架构极其流行,有众多成功的案例,但过于依赖Memcache,无形中让Memcache成为故障的根源:

Memcache数据一致性的问题:当MySQL数据变化后,如果不能及时有效的清理掉过期的数据,就会造成数据不一致。这在强调即时性的Web2.0时代,不可取。

Memcache崩溃后的雪崩效应:作为缓存的Memcache一旦崩溃,MySQL很可能在短时间内承受高负载而宕机。据说前段时间新浪微博就遭遇了这样的问题。

注:关于清理过期数据的问题,可以在程序架构上想办法,如果数据操作有统一DAO封装的话,可以利用Observer模式来清理过期数据,非主题内容,资料自查。

面对这些问题,HandlerSocket项目是个不错的解决方案,它通过插件的方式赋予MySQL完整的NoSQL功能,从原理上讲,它跳过MySQL中最耗时的语法解析,查询计划等步骤,直接读取数据,如果内存够大,能装下索引,MySQL的查询效率能提高若干倍!

性能测试实例:Using MySQL as a NoSQL – A story for exceeding 750,000 qps (GFW)

因为HandlerSocket的性能足够好,所以就没有必要使用Memcache了,能节省大量的硬件资源,相当低碳!而且HandlerSocket操作的是MySQL放在内存中的索引,没有额外的缓存,所以自然就不存在数据一致性的问题。

安装

如果使用Percona Server版本的MySQL就简单了,因为它已经内置了HandlerSocket支持,不过考虑到其内置的版本不够新,存在一些早已修复的BUG,所以最好采用源代码编译。

官方已经有了一份简单的安装文档,但在我实际安装时,遇到了一些其他未说明的问题,所以这里就把相应的安装过程再写一遍。

首先要确保已经安装了MySQL5.1以上的版本,我用的是Ubuntu操作系统,事先已经用apt安装了MySQL5.1.37,同时还需要相应的mysql_config,如果是Ubuntu的话,可以:

 


shell> aptitude install libmysqld-dev

 

注:如果你用的MySQL是从源代码编译的或官方提供的二进制版本,可以略过此步。

接着下载一份和系统MySQL版本一致的MySQL源代码和HandlerSocket源代码:

mysql-5.1.37.tar.gz

ahiguti-HandlerSocket-Plugin-for-MySQL-1.0.6-76-gf5f7443.tar.gz

 


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插件目录,如果不清楚这个目录在哪,可以按如下方法查询:

 


mysql> SHOW VARIABLES LIKE 'plugin%';
+---------------+-----------------------+
| Variable_name | Value |
+---------------+-----------------------+
| plugin_dir | /usr/lib/mysql/plugin |
+---------------+-----------------------+

 

运行命令后,如果你使用的是MySQL5.1.37版本的话,会遇到如下错误信息:

MySQL source version does not match MySQL binary version

明明我们的MySQL源代码版本和二进制版本都是5.1.37,为什么还会出现这个错误呢?通过查询HandlerSocket的编译脚本,发现原来它会检索MySQL源代码目录中的VERSION文件,可MySQL5.1.37的源代码目录里不知何故竟然没有这个文件,所以就报错了,既然知道了原因,那我们就照猫画虎做一个VERSION文件放到MySQL源代码目录,内容如下:

 


MYSQL_VERSION_MAJOR=5
MYSQL_VERSION_MINOR=1
MYSQL_VERSION_PATCH=37
MYSQL_VERSION_EXTRA=

 

再次运行configure脚本,应该就OK了,把剩下的步骤进行完:

 


shell> make
shell> make install

 

接着需要配置一下HandlerSocket,编辑MySQL配置文件,加入如下内容:

 


[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的潜力。

注:apt包管理下的配置文件一般是/etc/mysql/my.cnf,否则一般是/etc/my.cnf

最后登陆MySQL并激活HandlerSocket插件:

 


mysql> INSTALL PLUGIN handlersocket soname 'handlersocket.so';

 

如果没有问题的话,就能在MySQL里看到HandlerSocket的线程了:

 


mysql> SHOW PROCESSLIST;

 

也可以通过查询刚配置的端口是否已经被MySQL占用来确认是否安装成功:

 


shell> lsof -i :9998
shell> lsof -i :9999

 

完活儿!现在你的MySQL已经具备NoSQL的能力了!

实战

首先创建一个测试用的表:

 


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;

 

注:理论上HandlerSocket支持MyISAM,InnoDB等各种引擎,不过推荐使用InnoDB。

HandlerSocket的协议非常简单,指令通过TAB分割,一行就是一个请求。

打开索引:P <索引标识> <数据库> <表> <索引> <字段>

插入数据:<索引标识> ‘+’ <参数个数> <参数1> … <参数N>

读取数据:<索引标识> <操作> <参数个数> <参数1> … <参数N> <条数> <偏移>

SQL原型:INSERT INTO test.t (id, a, b) VALUES (1, ‘a1′, ‘b1′), (2, ‘a2′, ‘b2′)

 


shell> telnet localhost 9999
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
P 1 test t PRIMARY id,a,b
0 1
1 + 3 1 a1 b1
0 1 0
1 + 3 2 a2 b2
0 1 0

 

注:使用HandlerSocket时,因为没有实际运行SQL,所以Binlog记录的是Row格式。

SQL原型:SELECT id, a, b FROM test.t WHERE id = 1 LIMIT 1

 


shell> telnet localhost 9999
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
P 1 test t PRIMARY id,a,b
0 1
1 = 1 1 1 0
0 3 1 a1 b1

 

SQL原型:SELECT id, a, b FROM test.t WHERE id >=1 LIMIT 2

 


shell> telnet localhost 9999
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
P 1 test t PRIMARY id,a,b
0 1
1 >= 1 1 2 0
0 3 1 a1 b1 2 a2 b2

 

SQL原型:SELECT id, a, b FROM test.t WHERE a = ‘a1′ AND b = ‘b1′ LIMIT 1

 


shell> telnet localhost 9999
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
P 1 test t a_b id,a,b
0 1
1 = 2 a1 b1 1 0
0 3 1 a1 b1

 

对HandlerSocket一个常见的误解是只能执行PRIMARY类型的KV查询,实际上只要支持索引,一般的简单查询它都能胜任,篇幅所限,这里就不多说了,如果你觉得直接操作telnet有些吃力,也可以使用自己熟悉的客户端来测试,官方文档里有介绍。

时间: 2024-08-04 03:36:38

MySQL下的NoSQL解决方案HandlerSocket的相关文章

HiStore:阿里巴巴海量数据场景下的OLAP解决方案

摘要:7月27日,.阿里中间件举办了首届阿里巴巴中间件技术峰会,揭秘阿里10年分布式技术干货.在首届阿里巴巴中间件技术峰会上,阿里巴巴中间件技术专家焦方飞为大家分享阿里巴巴海量数据场景下的OLAP解决方案,此外还对阿里新推出的高性能时序数据库进行了简单介绍,精彩不容错过. 以下内容根据演讲嘉宾现场视频以及PPT整理而成. 本次分享的主题是阿里巴巴海量数据场景下的OLAP解决方案,主要是也为大家介绍一下阿里巴巴OLAP存储的一款产品--HiStore.大家都知道海量数据,包括大数据和数据仓库这些在

Linux 安装 MySQL 以及 一些常见问题解决方案

一.下载MySql浏览器打开 http://www.mysql.com/downloads/mysql/#downloads 下载 我下载的版本是Red Hat 5 版本的 http://www.mysql.com/downloads/mirror.php?id=407552 上传至服务器,或在服务器上直接 wget 下载方式下载.(我在服务器上存放在目录/opt/tools 下) 二.解压tar文件执行命令:tar -xvf MySQL-5.5.23-1.rhel5.x86_64.tar 三.

mysql启动的时参数文件中的[mysql]下的参数没有生效

问题描述 mysql启动的时参数文件中的[mysql]下的参数没有生效 my.cnf下的参数如下 [mysqld] 此处省略..... [mysql] #no-auto-rehash prompt='u@h:pd mysql>' #max_allowed_packet = 1024M ##影响mysql导人的速度 #default_character_set = gbk 启动方式 mysqld --defaults-file=/etc/my.cnf & 启动后prompt没有生效 [root

MYSQL下的幽灵表`````怎么能把它找出来`~~

问题描述 MYSQL下有个库`是直接从别的机器下复制文件过来的`在命令行MYSQL里可以show tables到全部表;但是有些表select时说不存在.从GUI里进去就看不到这些不存在的表``这是怎么回事``我的权限是ROOT``把原库中的ibdata1复制过来MYSQL可以启动`但没有什么作用```还是提示不存在``要是把``ib_logfile1``和ib_logfile0也复制过来```MYSQL就启动不起来``这两个机器上的ibdata1是一样大的`10M``ib_logfile一个是

php+mysql大量用户登录解决方案

大数据的时候,压力不在PHP,主要在MySQL. PHP可以做负载均衡,10台机器抗不住就用20台或者100台,这都不是瓶颈. 但是MySQL是单点的,无论做多少从库,都是优化查询,更新数据就无法只是简单的通过加机器解决了. 而且查询也可以通过Memcache缓存减轻压力,所以不必要做多少从库的,一般1主4从就可以了. 下面主要介绍下数据库的解决方案: 假设用户可以通过"登录名"."邮箱"或"手机号"登录. 表结构如下: 登录名与ID表,根据lo

php+mysql大量用户登录解决方案分析_php技巧

本文实例分析了php+mysql大量用户登录解决方案.分享给大家供大家参考.具体分析如下: 百度.QQ.360等大公司都拥有上亿的用户量,不仅所有子网站都通过一个账号登录,而且还开放用户平台,提供给其他网站使用,这种级别的数据量和访问量,如果不做优化,估计很快就会宕机,这些公司都是一个专门的团队,维护一个注册登录,细节设计的非常优秀,现在粗略谈下他们的设计方案. 大数据的时候,压力不在PHP,主要在MySQL,PHP可以做负载均衡,10台机器抗不住就用20台或者100台,这都不是瓶颈. 但是My

图文详解linux/windows mysql忘记root密码解决方案

经常有用户过来咨询说自己的mysql服务器忘记密码了怎么办,为了更好的解决大家的困扰,本文特归档整理了windows和linux系统下,mysql忘记密码的解决方案.本文内容是我亲测实用,当然过程中踩过的坑我也会在本文中一并分享交流.废话不多说,上菜- Windows篇 演示环境: 服务器:windows2003 64位企业版 mysql版本:5.6.17 操作步骤: 1. 关闭mysql服务. 以管理员身份登录到您的服务器系统,如果服务器上的Mysql正在运行,则先停止MySQL服务.对于Wi

MySQL中文参考手册5(安装MySQL下)

mysql|参考|参考手册|中文 MySQL中文参考手册5(安装MySQL下)转载 译者:晏子 [返回][转发] 译者:晏子 (clyan@sohu.com)主页:http://linuxdb.yeah.net 4.12 Win32 注意事项这节描述在Win32上安装和使用MySQL,这也在MySQL Win32分发所带的"readme"文件中描述.  4.12.1 在Win32上安装MySQL如果你没有一个注册的MySQL版本,你应该首先下载共享软件版本,从:  MySQL 3.21

关于mysql下的00000文件

这些东西是数据库的操作日志 mysql-bin.000001 mysql-bin.000002 mysql-bin.000003 等等好多啊~~~都200多MB了我mysql总数据库加起来都不到50MB 这些可以清理掉的. 在cmd下进到mysql下的bin目录下 输入mysql -u root -p然后输入密码 成功进去后输入reset master;记得这个;啊! mysql> reset master; Query OK, 0 rows affected, 1 warning (0.20