千家信息网

MySQL的NoSQL扩展---HandlerSocket插件

发表于:2025-01-31 作者:千家信息网编辑
千家信息网最后更新 2025年01月31日,MySQL的NoSQL扩展---HandlerSocket插件
千家信息网最后更新 2025年01月31日MySQL的NoSQL扩展---HandlerSocket插件MySQL的NoSQL扩展---HandlerSocket插件 一.HandlerSocket介绍: 201011月日本社交游戏开发公司DeNA发布了MySQL HandlerSocket插件。Handlersocket插件是由日本人Yoshinori Matsunobu开发的。传统的关系型数据库在处理每个请求的时候,都需要做SQL解析,查询优化,执行,事务管理,锁管理等一系列的开销操作,消耗性能。非关系型数据库(NoSQL)就去掉了这些操作。通过handlersocket插件,可以直接跟MySQL的存储引擎层做key-value式的交互操作,省略了MySQLSQL层次的处理,大大的减少了资源的开销。 二.HandlerSocket架构: HandlerSocketMySQL内部实现一个NoSQL的网络服务,以mysqld进程的daemon存在,监听特定端口(99989999)与client通过TCP/IP接收NoSQL的协议和API,然后通过MySQL存储引擎API直接进行CRUD相关的操作。同时,还可以通过传统的MySQL的方式进行操作。 简单快速的操作通过handlersocket来实现。复杂的操作通过传统的MySQL方式来实现。 HandlerSocket结构图如下: 1.MySQL Client àMySQL Upper Layer àStorage Engine Layer 使用MySQL传统的方式,客户端通过3306端口与Upper层交互,在Upper层进行SQL解析,打开表,查询优化,关闭表等等操作,然后再提交到Storage Engine 层。 2.HandlerSocket Client àHandlerSocket daemon plugin àStorage Engine Layer 使用HandlerSocket方式,减少了很多在传统方式下的SQL层的操作。使用9998端口进行读操作,使用9999端口进行写操作。 三.HandlerSocket优缺点: 优点: 1.省去了MySQLSQL层相关的操作,大大的减少了CPU的消耗。 2. 采用合并操作的方式,合并多个请求同时执行,减少了CPU开销和IO操作次数。 3. 基于简单的文本协议,节省网络流量,提高网络吞吐量。 4. 能同时使用传统的MySQLHandlerSocket的方式访问MySQL数据库,互不冲突。 5. 支持大的并发连接。 6. 可以继续使用MySQLReplication等等成熟机制。 7. 避免有双重缓存。 8. 具有较高的读写性能,在CPU Bound的场景中,读取性能一般是同等环境下的MySQL3-7.5倍。同时写入性能也能达到3-5倍。 不足之处: 1.由于采用合并操作的方式,响应时间比MySQL来说大一些。 2.没有安全相关的保证,绝大部分NoSQL产品都有这样的问题。 3.IO Bound的场景中,性能的提升可能不是很明显。 4.目前只支持MySQL5.1MySQL5.5版本的Innodb存储引擎。 四.HandlerSocket的安装: 1.下载安装 # wget https://download.github.com/ahiguti-HandlerSocket-Plugin-for-MySQL-1.0.6-71-g159ea6d.tar.gz # tar zxvf ahiguti-HandlerSocket-Plugin-for-MySQL-1.0.6-71-g159ea6d.tar.gz -C ../software/ # cd ../software/ahiguti-HandlerSocket-Plugin-for-MySQL-159ea6d/ # ./autogen.sh # ./configure --prefix=/usr/local/handlersocket --with-mysql-source=/usr/local/src/software/mysql-5.1.36 //mysql源码目录 --with-mysql-bindir=/usr/local/mysql-5.1.36/bin //mysql安装目录可执行目录 --with-mysql-plugindir=/usr/local/mysql-5.1.36/lib/mysql/plugin //mysql插件目录 # make # make install 2.修改配置文件 my.cnf文件[mysqld]下增加以下配置: loose_handlersocket_port = 9998 //指定读请求端口号 loose_handlersocket_port_wr = 9999 //指定写请求端口号 loose_handlersocket_threads = 16 //指定读线程数目 loose_handlersocket_threads_wr = 1 //指定写线程数目 3.安装handlersocket.so > INSTALL PLUGIN handlersocket SONAME 'handlersocket.so'; 4.查看进程状态 # netstat -ntpl tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTEN 31402/mysqld tcp 0 0 0.0.0.0:9998 0.0.0.0:* LISTEN 31402/mysqld tcp 0 0 0.0.0.0:9999 0.0.0.0:* LISTEN 31402/mysqld 5.常见问题 configure: error: MySQL source version does not match MySQL binary version 解决方法:在configure.in文件中首行添加一行[MySQL Server] 5.1.36 五.HandlerSocket性能测试: 先来看看软件作者的测试结果: 环境:2.53GHZ8CPU32G内存的Nehalem服务器 结果: 六.安装PHP扩展包php-handlersocket # wget http://php-handlersocket.googlecode.com/files/php-handlersocket-0.0.7.tar.gz # tar zxvf php-handlersocket-0.0.7.tar.gz -C ../software/ # /usr/local/php5.2.13/bin/phpize # ./configure --prefix=/usr/local/php-handlersocket \ --with-php-config=/usr/local/php5.2.13/bin/php-config \ --with-handlersocket \ --with-handlersocket-includedir=/usr/local/handlersocket/include/handlersocket # make # make install # vim /usr/local/Zend/etc/php.ini 添加下面一行 extension=/usr/local/php5.2.13/lib/php/extensions/no-debug-zts-20060613/handlersocket.so 查看是否加载成功: 常见问题: cc -shared .libs/handlersocket.o -lstdc++ -L/usr/local/handlersocket/include/handlersocket/lib -lhsclient -Wl,-rpath -Wl,/usr/local/handlersocket/include/handlersocket/lib -Wl,-soname -Wl,handlersocket.so -o .libs/handlersocket.so /usr/bin/ld: cannot find -lhsclient collect2: ld returned 1 exit status make: *** [handlersocket.la] Error 1 解决方法:# cd /usr/local/handlersocket # cp -rf lib include/handlersocket/ 七.测试: 1.建立测试表 mysql> create table `test_hs` ( -> `id` int(10) auto_increment not null, -> `k` varchar(50) default null, -> `v` varchar(50) default null, -> primary key (`id`), -> key `index_k` (`k`) -> )engine=innodb; mysql> insert into test_hs values ('','k1','v1'); mysql> insert into test_hs values ('','k2','v2'); mysql> insert into test_hs values ('','k3','v3'); 2.PHP使用实例 $host = 'localhost'; $port = 9998; $port_wr = 9999; $dbname = 'hstestdb'; $table = 'hstesttbl'; //GET $hs = new HandlerSocket($host, $port); if (!($hs->openIndex(1, $dbname, $table, HandlerSocket::PRIMARY, 'k,v'))) { echo $hs->getError(), PHP_EOL; die(); } $retval = $hs->executeSingle(1, '=', array('k1'), 1, 0); var_dump($retval); $retval = $hs->executeMulti( array(array(1, '=', array('k1'), 1, 0), array(1, '=', array('k2'), 1, 0))); var_dump($retval); unset($hs); //UPDATE $hs = new HandlerSocket($host, $port_wr); if (!($hs->openIndex(2, $dbname, $table, '', 'v'))) { echo $hs->getError(), PHP_EOL; die(); } if (!($hs->executeUpdate(2, '=', array('k1'), array('V1'), 1, 0))) { echo $hs->getError(), PHP_EOL; die(); } unset($hs); //INSERT $hs = new HandlerSocket($host, $port_wr); if (!($hs->openIndex(3, $dbname, $table, '', 'k,v'))) { echo $hs->getError(), PHP_EOL; die(); } if (!($hs->executeInsert(3, array('k2', 'v2')))) { echo $hs->getError(), PHP_EOL; } if (!($hs->executeInsert(3, array('k3', 'v3')))) { echo $hs->getError(), PHP_EOL; } if (!($hs->executeInsert(3, array('k4', 'v4')))) { echo $hs->getError(), PHP_EOL; } unset($hs); //DELETE $hs = new HandlerSocket($host, $port_wr); if (!($hs->openIndex(4, $dbname, $table, '', ''))) { echo $hs->getError(), PHP_EOL; die(); } if (!($hs->executeDelete(4, '=', array('k2')))) { echo $hs->getError(), PHP_EOL; die(); } 3.方法注释 openIndex(1, $dbname, $table, HandlerSocket::PRIMARY, 'k,v') 打开索引,第一个参数1用来在每个HandlerSocket对象中唯一标识一个表名;$dbname表示为数据库名;$table表示为表名;HandlerSocket::PRIMARY表示为索引名;'k,v'表示为要查询的列名。 executeSingle(1, '=', array('k1'), 1, 0) 执行查询,第一个参数要跟之前的openIndex方法中的第一个参数保持一致;第二个参数'='表示检索的条件,支持'=','>=','<=','>','<';第三个参数array('k1')表示一个arrayref,指定检索的key,其长度必须小于或者等于对应索引的列数;第四个和第五个参数指定查询的limitoffset executeMulti 可在一次调用中执行多个操作。
0