设为首页 收藏本站
查看: 1100|回复: 0

[经验分享] linux c/c++后台开发组件之:memcached 单机和分布式集群c++客户端

[复制链接]

尚未签到

发表于 2015-11-18 14:08:39 | 显示全部楼层 |阅读模式
  memcached 是一个高性能内存缓存,在作为缓存,不需要持久化的场性能稳定,由于现在服务器内存较大,很多应用场景单台memcached就能满足业务需求,普通的官方c API
  就能满足需求。
  


  而大型的应用数据量很大,也应该考虑单点故障,集群化可以分散压力,单点故障影响较小。集群的管理通常有两种方式:1.普通hash 2.一致性hash
  1.普通hash实现相对简单,效率更高,但是不能动态扩展,这种能满足业务数据不是经常扩展比较固定的场景,单点故障影响不大,这种长期其实很多。通常的mysql + memcached 架构很适合这种方式
  2.一致性哈希的优点就是可以动态扩展,适合业务数据持续增长的场景,实现相对复杂,通常需要代理服务器管理
  


  下面是自己实现的基于hash的memcached 集群c++客户端代码,经过线上测试,性能和稳定性没有太大的问题。
  

/************************************************
function: c++ mcached api
author:liuyi
date:2012.12.31
version:3.0
modify:2014.10.15
*************************************************/
#ifndef MULI_MEMCACHE_H
#define MULI_MEMCACHE_H
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <time.h>
#include &quot;libmemcached/memcached.h&quot;
using namespace std;
typedef unsigned int(*hash_fun)(const char*);
unsigned int rs_hash(const char *str)  
{  
unsigned int b = 378551;  
unsigned int a = 63689;  
unsigned int hash = 0;      
while (*str)  
{  
hash = hash * a + (*str++);  
a *= b;  
}
return (hash & 0x7FFFFFFF);  
}
struct memcache_info
{
string host;
int port;
};
class single_memcached
{
public:
single_memcached()
{
servers = NULL;
memc = NULL;
rc = MEMCACHED_SUCCESS;
result_buff = NULL;
}
virtual ~single_memcached()
{
memcached_free(memc);
delete []result_buff;
}
enum {MAX_VALUE_LEN = 1024*1024};
bool init(const char*host, const int& port)
{
result_buff = new char[MAX_VALUE_LEN];
if(result_buff == NULL)
return false;
memc = memcached_create(NULL);
servers = memcached_server_list_append(NULL, host, port, &rc);
if(servers == NULL)
return false;
rc = memcached_server_push(memc, servers);
if(rc == MEMCACHED_SUCCESS)
{
memcached_server_free(servers);
return true;
}
else
{
return false;
}
}
//插入或者覆盖原有数据 expiration为有效时间,默认0为一直有效
bool set(const char* key, const char* value, time_t expiration = 0)
{
rc = memcached_set(memc, key, strlen(key), value, strlen(value), expiration, 0);
return rc == MEMCACHED_SUCCESS;
}
//删除数据 expiration为有效时间,默认0为立即生效
bool delete_k_v(const char* key, time_t expiration = 0)
{
rc = memcached_delete(memc, key, strlen(key), expiration);
return  rc == MEMCACHED_SUCCESS;
}
char *get(const char* key)
{
size_t value_len = 0;
uint32_t flag = 0;
char *ret = memcached_get(memc, key, strlen(key), &value_len, &flag, &rc);
if(ret == NULL)
{
return NULL;
}
memset(result_buff, 0, MAX_VALUE_LEN);
if(value_len < MAX_VALUE_LEN)
{
memcpy(result_buff, ret, value_len);
free(ret);
}
return rc == MEMCACHED_SUCCESS && value_len < MAX_VALUE_LEN  ? result_buff : NULL;
}
private:
memcached_server_st *servers;
memcached_st *memc;
memcached_return rc;
char *result_buff;
};
class mulit_memcached
{
public:
mulit_memcached()
{
memcache_servers.clear();
memcache_servers_id.clear();
}
virtual ~mulit_memcached()
{
}
bool init(const vector<memcache_info>& memcache_info_vec, hash_fun hash = rs_hash)
{
m_hash_fun = hash;
memcache_servers.resize(memcache_info_vec.size());
for(size_t i = 0; i < memcache_info_vec.size(); i++)
{
char value[1024] = {0};
snprintf(value, 1023, &quot;%s#%d&quot;, memcache_info_vec.host.c_str(), memcache_info_vec.port);
memcache_servers_id.insert(pair<unsigned int, string>(i, value));
if(!memcache_servers.init(memcache_info_vec.host.c_str(), memcache_info_vec.port))
{
return false;
}
}
return true;
}
bool set(const char* key, const char* value, time_t expiration = 0)
{
unsigned int index = m_hash_fun(key) % memcache_servers.size();
return memcache_servers[index].set(key, value, expiration);
}
bool delete_k_v(const char* key, time_t expiration = 0)
{
unsigned int index = m_hash_fun(key) % memcache_servers.size();
return memcache_servers[index].delete_k_v(key, expiration);
}
char *get(const char* key)
{
unsigned int index = m_hash_fun(key) % memcache_servers.size();
return memcache_servers[index].get(key);
}
string get_memcache_info(const char* key)
{
unsigned int index = m_hash_fun(key) % memcache_servers.size();
return memcache_servers_id[index];
}
private:
vector<single_memcached> memcache_servers;
map<unsigned int, string> memcache_servers_id;
hash_fun m_hash_fun;
};
#endif

  
  



//test  

#include <iostream>
#include <string>
#include &quot;memcache_api.h&quot;
using namespace std;
unsigned int user_define_hash(const char *str)  
{  
unsigned int b = 378551;  
unsigned int a = 63689;  
unsigned int hash = 0;      
while (*str)  
{  
hash = hash * a + (*str++);  
a *= b;  
}
hash += 1;
hash -= 1;
return (hash & 0x7FFFFFFF);  
}
int main(int argc, char *argv[])
{
single_memcached mc;
if(!mc.init(&quot;10.101.88.244&quot;, 11212))
{
cout<<&quot;mc init error&quot;<<endl;
}
char key[1024] = {0};
char value[1024] = {&quot;1&quot;};
if(!mc.set(key, value))
{
//cout<<&quot;set error&quot;<<endl;
}
for(int i = 0; i < 1000; i++)
{
sprintf(key, &quot;%d&quot;, i);
if(!mc.set(key, key)){cout<<&quot;error&quot;<<endl;}
if(mc.get(key))cout<<mc.get(key)<<endl;
mc.delete_k_v(key);
}
memcache_info host_port;
host_port.host = &quot;10.101.88.244&quot;;
host_port.port = 11211;
vector<memcache_info> servers;
servers.push_back(host_port);
host_port.port = 11212;
servers.push_back(host_port);
mulit_memcached mulit_memcached_servers;
if(!mulit_memcached_servers.init(servers))
//if(!mulit_memcached_servers.init(servers, user_define_hash))
{
cout<<&quot;init error&quot;<<endl;
}
for(int i = 0; i < 1000; i++)
{
char k[16] = {0};
sprintf(k, &quot;%d&quot;, i);
//cout<<k<<endl;
cout<<mulit_memcached_servers.set(k, k)<<endl;;
cout<<mulit_memcached_servers.set(k, k, 100)<<endl;;
if(mulit_memcached_servers.get(k))cout<<mulit_memcached_servers.get(k)<<endl;
cout<<mulit_memcached_servers.delete_k_v(k)<<endl;
cout<<mulit_memcached_servers.get_memcache_info(key)<<endl;//user for log
}
return 0;
}





  
  



版权声明:本文为博主原创文章,未经博主允许不得转载。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-140771-1-1.html 上篇帖子: memcached分布式部署 下篇帖子: 30分钟3300%性能提升——python+memcached网页优化小记
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表