redis client pool

本文介绍了一个使用C++实现的Redis客户端池,包括客户端类和客户端池类的详细代码。客户端类提供了连接Redis服务器、设置和获取值的方法,而客户端池类则管理多个客户端实例,提供客户端资源的获取和释放。通过这个实现,可以有效地管理和复用Redis客户端,提高应用程序的性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.redis_client.hpp

#ifndef REDIS_CLIENT_HPP_
#define REDIS_CLIENT_HPP_
#include <hiredis/hiredis.h>
#include <string.h>
#include <iostream>
#include <string>
using namespace std;
class redis_client {
public:
	redis_client() {
		conn_ = nullptr;
	}
	redis_client(const redis_client &) = delete;
	redis_client & operator = (const redis_client &) = delete;
	virtual ~redis_client() {
		if (nullptr != conn_) {
			redisFree(conn_);
			conn_ = nullptr;
		}
	}
	inline bool connect(const char *ip, int port) {
		conn_ = redisConnect(ip, port);
		if (nullptr == conn_) {
			cerr << "connection is null...!" << endl;
			return false;
		}
		if (conn_->err) {
			cerr << "connection failed err = " << conn_->errstr << endl;
			return false;
		}
		return true;
	}
	bool set_value(const char *key, const string &value) {
		if (nullptr == conn_) {
			cerr << "redis client conn is null...!" << endl;
			return false;
		}
		if (value.size() > MAXVALUESIZE) {
			cerr << "value size is over 1M...!" << endl;
			return false;
		}
		size_t keylen = strlen(key);
		if (keylen > MAXKEYSIZE) {
			cerr << "key size is over 1k...!" << endl;
			return false;
		}
		redisReply *reply = (redisReply *)redisCommand(conn_, "set %b %b", key, keylen, value.c_str(), value.size());
		if (nullptr == reply) {
			cerr << "reply is null...!" << endl;
			return false;
		}
		bool succ = true;
		if (nullptr == reply->str) {
			succ = false;
			cerr << "reply string is null...!" << endl;
		}
		else if (strcasecmp(reply->str, "ok")) {
			succ = false;
			cerr << "reply error = " << reply->str << endl;
		}
		freeReplyObject(reply);
		reply = nullptr;
		return succ;
	}
	bool get_value(const char *key, string &value) {
		if (nullptr == conn_) {
			cerr << "redis client conn is null...!" << endl;
			return false;
		}
		size_t keylen = strlen(key);
		if (keylen > MAXKEYSIZE) {
			cerr << "key size is over 1k...!" << endl;
			return false;
		}
		redisReply *reply = (redisReply *)redisCommand(conn_, "get %s", key);
		if (nullptr == reply) {
			cerr << "reply is null...!" << endl;
			return false;
		}
		bool succ = true;
		if (nullptr == reply->str) {
			succ = false;
			cerr << "reply string is null...!" << endl;
		}
		else if (REDIS_REPLY_NIL == reply->type) {
			succ = false;
			cerr << "reply error = " << reply->str << endl;
		}
		else {
			value.assign(reply->str, reply->len);
		}
		freeReplyObject(reply);
		reply = nullptr;
		return succ;
	}
private:
	redisContext *conn_;
private:
	static const size_t MAXVALUESIZE = 1024 * 1024;
	static const size_t MAXKEYSIZE = 1024;
	static const size_t MAXCHANNELSIZE = 10;
};

#endif /* REDIS_CLIENT_HPP_ */

2.redis_client_pool.hpp

#ifndef REDIS_CLIENT_POOL_HPP_
#define REDIS_CLIENT_POOL_HPP_
#include <vector>
#include <memory>
#include <functional>
#include <mutex>
#include "redis_client.hpp"
struct redis_client_pool_config {
	redis_client_pool_config() {
		poolsize_ = 32;
		port_ = 6379;
		ip_ = "127.0.0.1";
	}
	size_t poolsize_;
	string ip_;
	int port_;
};
using delete_type = function<void(redis_client *)>;
class redis_client_pool {
public:
	redis_client_pool() = default;
	virtual ~redis_client_pool() = default;
public:
	bool init(const redis_client_pool_config &config) {
		if (config.poolsize_ > POOLCAPACITY) {
			cerr << "pool size is over limit...!" << endl;
			return false;
		}
		for (size_t i = 0;i < config.poolsize_;i++) {
			unique_ptr<redis_client>ptr(new redis_client);
			if (!ptr->connect(config.ip_.c_str(), config.port_)) {
				return false;
			}
			clients_.push_back(move(ptr));
		}
		return true;
	}
	unique_ptr<redis_client, delete_type>get_client() {
		lock_guard<mutex>lock(pool_lock_);
		if (clients_.empty()) {
			return nullptr;
		}
		unique_ptr<redis_client, delete_type>ptr(clients_.back().release(), [this](redis_client *client) {
			pool_lock_.lock();
			clients_.push_back(unique_ptr<redis_client>(client));
			pool_lock_.unlock();
		});
		clients_.pop_back();
		return move(ptr);
	}

private:
	vector<unique_ptr<redis_client> >clients_;
	mutex pool_lock_;
private:
	static const size_t POOLCAPACITY = 128;


};

#endif /* REDIS_CLIENT_POOL_HPP_ */

3.main.cpp

#include "redis_client_pool.hpp"
int main() {
	redis_client_pool mypool;
	redis_client_pool_config config;
	if (false == mypool.init(config)) {
		return -1;
	}
	const char *key = "key0";
	string value = "value0";
	auto client_ptr = mypool.get_client();
	if (nullptr == client_ptr) {
		return -1;
	}
	if (client_ptr->set_value(key, value)) {
		cout << "set value to redis server ok." << endl;
	}
	string new_value;
	if (client_ptr->get_value(key, new_value)) {
		cout << "get value = " << new_value << " from redis server ok." << endl;
	}

	return 0;
}

4.make.sh

 g++ -std=c++14 -g -o Test main.cpp  redis_client.hpp -lhiredis

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值