HandlerSocke源码t自带C++客户端的so库以及c++例子(和下面的第一个基本一样),只不过没什么具体的文档介绍,于是给个例子(可以看一下安装包里的协议说明,更容易理解)
//======================================
// Name : hsTest.cpp
// Author : asyty
// Version :
// Copyright : Your copyright notice
// Description : hsClient
//======================================
#include<iostream>
#include<handlersocket/hstcpcli.hpp>
#include<handlersocket/string_util.hpp>
using namespace dena;
using namespace std;
int main() {
/*********创建client***********/
config conf;
conf["host"] = "127.0.0.1";
conf["port"] = "9998";
socket_args sock_args;
sock_args.set(conf);
hstcpcli_ptr cli = hstcpcli_i::create(sock_args);
/*******通过索引打开连接 ************/
int code = 0;
size_t numflds = 0;
//写请求buffer,column之间除了逗号不允许空格,通过下面的request_send发送请求
// db name // table // index
cli->request_buf_open_index(1, "test", "table", "index_1", "colum1,colum2");
do { //发送request_buf_open_index请求
if (cli->request_send() != 0) {
fprintf(stderr, "request_send: %s\n", cli->get_error().c_str());
break;
}
if ((code = cli->response_recv(numflds)) != 0) {
fprintf(stderr, "response_recv: %s\n", cli->get_error().c_str());
break;
}
} while (false);
cli->response_buf_remove();
/*********获取数据************/
char key_buf[32] = { 0 };
uint32_t uid = 2;
snprintf(key_buf, 32, "%u", uid);
const string key(key_buf);
const string_ref keyref(key.data(), key.size());
const string kTestEqualOp("=");
const string_ref kTestEqualOpRef(kTestEqualOp.data(), kTestEqualOp.size());
cli->request_buf_exec_generic(1, kTestEqualOpRef, &keyref, 1, 0, 0, string_ref(), 0, 0);
do {//发送request_buf_exec_generic
if (cli->request_send() != 0) {
fprintf(stderr, "request_send: %s\n", cli->get_error().c_str());
break;
}
if ((code = cli->response_recv(numflds)) != 0) {
fprintf(stderr, "response_recv: %s\n", cli->get_error().c_str());
break;
}
while (true) {
const string_ref * const row = cli->get_next_row();
if (row == 0) {
break;
}
for (size_t i = 0; i < numflds; ++i) {
const string val(row[i].begin(), row[i].size());
printf(" %s", val.c_str());
}
printf("\n");
}
} while (false);
cli->response_buf_remove();
cli->close()
return 0;
}
对于多线程的使用,hstcpcli_i这个结构体部分结构如下
namespace dena {
struct hstcpcli : public hstcpcli_i, private noncopyable {
hstcpcli(const socket_args& args);
virtual void close();
virtual int reconnect();
................
virtual int request_send();
virtual int response_recv(size_t& num_flds_r);
................
private:
int read_more();
void clear_error();
int set_error(int code, const std::string& str);
private:
auto_file fd;
socket_args sargs;
string_buffer readbuf;
string_buffer writebuf;
size_t response_end_offset; /* incl newline */
size_t cur_row_offset;
size_t num_flds;
size_t num_req_bufd; /* buffered but not yet sent */
size_t num_req_sent; /* sent but not yet received */
size_t num_req_rcvd; /* received but not yet removed */
int error_code;
std::string error_str;
std::vector<string_ref> flds;
};
它其实就是socket客户端,有两个string buffer 一个负责存发送数据 一个负责接收数据,如果多个请求同时发送,接收数据就会各种混乱出错。。。所以 它本身是不支持并发的,除非自己写代码控制并发。。。
因此 多线程的操作应该使用不同的hstcpcli,open index时可以使用相同的index_id
//============================================================================
// Name : hsMultiTest.cpp
// Author : asyty
// Version :
// Copyright : Your copyright notice
// Description : multithread test
//============================================================================
#include<iostream>
#include<pthread.h>
#include<handlersocket/hstcpcli.hpp>
#include<handlersocket/string_util.hpp>
using namespace dena;
using namespace std;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int pthread_id = 1;
void* cli_thread(void *args) {
pthread_mutex_lock(&mutex);
int tid = pthread_id;
pthread_id++;
pthread_mutex_unlock(&mutex);
config conf;
conf["host"] = "127.0.0.1";
conf["port"] = "9998";
socket_args sock_args;
sock_args.set(conf);
hstcpcli_ptr cli = hstcpcli_i::create(sock_args);
int code = 0;
size_t numflds = 0;
cli->request_buf_open_index(tid, "test", "table",
"PRIMARY", "colum2,colum3");
do {
if (cli->request_send() != 0) {
fprintf(stderr, "request_send: %s\n", cli->get_error().c_str());
cli->close();
pthread_exit(NULL);
}
if ((code = cli->response_recv(numflds)) != 0) {
fprintf(stderr, "response_recv: %s\n", cli->get_error().c_str());
cli->close();
pthread_exit(NULL);
}
} while (false);
cli->response_buf_remove();
char key_buf[32] = { 0 };
uint32_t uid = 0;
const string kTestEqualOp("=");
const string_ref kTestEqualOpRef(kTestEqualOp.data(), kTestEqualOp.size());
for (uid = 1000 * tid + 1; uid <= 1000 * tid + 1000; uid++) {
snprintf(key_buf, 32, "%u", uid);
const string key(key_buf);
const string_ref keyref(key.data(), key.size());
cli->request_buf_exec_generic(tid, kTestEqualOpRef, &keyref, 1, 0, 0,
string_ref(), 0, 0);
do {
if (cli->request_send() != 0) {
fprintf(stderr, "request_send: %s\n", cli->get_error().c_str());
break;
}
if ((code = cli->response_recv(numflds)) != 0) {
fprintf(stderr, "response_recv: %s\n",
cli->get_error().c_str());
break;
}
while (true) {
const string_ref * const row = cli->get_next_row();
if (row == 0) {
break;
}
for (size_t i = 0; i < numflds; ++i) {
const string val(row[i].begin(), row[i].size());
printf(" %s", val.c_str());
}
printf("\n");
}
} while (false);
cli->response_buf_remove();
}
cli->close();
}
int main(int argc, char** argv) {
pthread_t *id;
int tid, ret, ths;
struct timeval start, end;
if(argc < 2)
return 0;
ths = atoi(argv[1]);
if(ths <= 0)
return 0;
id = new pthread_t[ths];
for (tid = 1; tid <= ths; tid++) {
ret = pthread_create(&id[tid], NULL, cli_thread, (void*) &tid);
if (ret != 0) {
printf("Create pthread error!\n");
} else {
printf("create pthread %d\n", tid);
}
usleep(1000);
}
printf("This is the main process.\n");
for (tid = 0; tid < ths; tid++) {
pthread_join(id[tid], NULL);
}
delete[] id;
return 0;
}
C++客户端和JAVA客户端(某淘宝人士开发的hs4j)相比,连接延时几乎可以忽略不计,在同样的机器上测试并发,在1000并发数下,java客户端读取性能能飙到15万/秒,C++能达到40万/秒,性能相差还是很大的,只不过hs4j用起来更方便
转载请注明源
分享到:
相关推荐
有关HandlerSocket的更多信息,请查看HandlerSocket上的。安装,请在您的php项目目录中运行以下命令: php composer.phar require tz-lom/hsphp --no-update使用范例选择 $ c = new \ HSPHP \ ReadSocket ();$ c ->...
MySQL插件HandlerSocket是一个创新性的开源项目,设计目的是为了提高数据库的读写性能,特别是对于大规模数据处理场景。它允许应用程序直接与InnoDB存储引擎交互,绕过了SQL查询解析、优化和执行等传统步骤,从而...
1. **创建客户端对象**:通过 `HSClientImpl` 创建一个连接到 HandlerSocket 服务器的客户端实例,例如连接到本地的 9999 端口。 2. **打开索引会话**:使用 `openIndexSession` 方法打开一个索引会话,指定数据库名...
### HandlerSocket详细介绍 #### 一、由来与背景 HandlerSocket是一种开源的高性能数据库缓存系统,它结合了MySQL和memcached的优点,旨在提供一种快速、高效的数据存储和检索方式。HandlerSocket最初由Yoshinori ...
acl_cpp 是基于 acl 库的 C++ 库,包括 MIIME 解析、Handlersocket 客户端库、数据库连接池(支持mysql/sqlite)、WEB 编程、数据库编程、阻塞/非阻塞数据流等内容。
HandlerSocket的应用场景:MySQL自身的局限性,很多站点都采用了MySQL+Memcached的经典架构,甚至一些网站放弃MySQL而采用NoSQL产品,比如Redis/MongoDB等。不可否认,在做一些简单查询(尤其是PK查询)的时候,很多...
关于HandlerSocket的文档很少。 MySQL插件作者的有一些幻灯片。 日本最大的社交游戏平台的数据库基础设施架构师的博客。 另一篇有关在基于RedHat的系统上安装HandlerSocket并使其运行的博客。 使用此PHP扩展在另...
HandlerSocket是MySQL提供的一种高性能、低延迟的接口,旨在为InnoDB存储引擎提供NoSQL风格的访问方式。通过绕过SQL解析和优化步骤,HandlerSocket能显著提高数据读取和写入的速度,尤其适用于大数据量的实时应用。 ...
一、HandlerSocket是什么?HandlerSocket是akira higuchi写的一个MySQL的插件。以MySQL Daemon Plugin的形式提供类似NoSQL的网络服务,通过这个插件,你可以直接跟MySQL后端的存储引擎做key-value式的交互,省去了...
HandlerSocket是一个MySQL插件,它通过直接访问MySQL的数据存储层,跳过了SQL解析和查询计划等耗时步骤,从而极大地提高了读取速度。在内存足够大以容纳索引的情况下,使用HandlerSocket可以使MySQL的查询性能提升...
mysql-handlersocket-1.0.6-1.DC.1.x86_64
结合以上信息,我们可以推测这个压缩包可能包含了一个使用PHP实现的HandlerSocket客户端,允许开发者在PHP应用程序中直接与MySQL的HandlerSocket插件通信,以提高数据库操作的性能。使用这个库的开发者需要了解PHP...
Redis、Hash算法数据库、LSM算法数据库、HandlerSocket、分布式数据库
3. "php-handelrsocket":这可能是PHP HandlerSocket扩展的源码目录,包含所有相关源文件和头文件,开发者可以在这个目录下找到具体的C或C++源代码,以及可能的Makefile或构建脚本。 学习和使用这个资源,你可以: ...
handlersocket-go 转到用于连接到HandlerSocket Mysql插件的库。 参见github.com/ahiguti/HandlerSocket-Plugin-for-MySQL/ 安装 $ go get github.com/bketelsen/handlersocket-go 阅读示例-最佳示例在TEST文件中。...
HandlerSocket是一个特殊的MySQL客户端库,它绕过了MySQL的标准查询解析器,直接通过套接字与MySQL服务器进行交互,从而实现了极高的数据读取性能。这种技术常用于大数据量的实时查询场景,如日志分析或在线分析处理...
1、常见网络应用库:SMTP 客户端库/PING 库/memcache 客户端库/handlersocket 客户端库/beanstalk 客户端库 2、HTTP 网络库:HTTP 客户端/服务端库,C++版 HttpServlet 类,HTTP COOKIE/HTTP SESSION 等 3、邮件解析...