最近要使用memcacheq作为消息队列,想找下memcacheq的c的客户端库,后来一想,既然memcacheq本身是支持memcache协议的,使用memcached的客户端的库应该就可以了。
惭愧的是,真没用编写过c对memcached的操作,以前只是简简单单的使用下ruby程序对客户端操作而已,不过ruby下的memcache客户端实在是简介,昨天很快就用ruby实现了我的应用的初级模型,可惜后台开发,效率还是很重要的。接下来昨天到今天上午一直再看libmemcached的库写了几个小程序。话说ruby,python和perl,php也是使用该库编写的memcached客户端程序的。
发现libmemcached本身支持 memcached的分布式应用。
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <libmemcached/memcached.h> int fun(memcached_server_st *servers) { //return servers[0].count; } int main(int argc, char *argv[]) { memcached_st *memc; memcached_return rc; memcached_server_st *servers; char value[8191]; //connect multi server memc = memcached_create(NULL); // memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SORT_HOSTS, 1); memcached_behavior_set(memc,MEMCACHED_BEHAVIOR_DISTRIBUTION,MEMCACHED_DISTRIBUTION_CONSISTENT); servers = memcached_server_list_append(NULL, "localhost", 21202, &rc); // servers = memcached_server_list_append(servers, "localhost", 21201, &rc); servers = memcached_server_list_append(servers, "localhost", 11217, &rc); // servers = memcached_server_list_append(servers, "localhost",11216,&rc); rc = memcached_server_push(memc, servers); // int count = memcached_server_list_count(servers); int count2 = memcached_server_count(memc); fprintf(stdout, "server count is%d/n",memc->number_of_hosts); memcached_server_free(servers); //Save multi data size_t i; const char const *keys[]= {"key1", "key2", "key3","key4"}; const size_t key_length[]= {4, 4, 4, 4}; char *values[] = {"This is c first value", "This is c second value", "This is c third value"," this is c forth value"}; size_t val_length[]= {21, 22, 21, 21}; for (i=0; i < 4; i++) { rc = memcached_set(memc, keys[i], key_length[i], values[i], val_length[i], (time_t)180,(uint32_t)0); if (rc == MEMCACHED_SUCCESS) { printf("Save key:%s data:/"%s/" success./n", keys[i], values[i]); } } //Fetch multi data char return_key[MEMCACHED_MAX_KEY]; size_t return_key_length; char *return_value; size_t return_value_length; uint32_t flags; rc = memcached_mget(memc, keys, key_length, 4); while ((return_value = memcached_fetch(memc, return_key, &return_key_length, &return_value_length, &flags, &rc))) { if (rc == MEMCACHED_SUCCESS) { printf("Fetch key:%s data:%s/n", return_key, return_value); } } //Delete multi data for (i=0; i <4; i++) { rc = memcached_set(memc, keys[i], key_length[i], values[i], val_length[i], (time_t)180, (uint32_t)0); rc = memcached_delete(memc, keys[i], key_length[i], (time_t)0); if (rc == MEMCACHED_SUCCESS) { printf("Delete %s success/n", keys[i], values[i]); } } //free memcached_free(memc); return 0; }
另外还支持连接池的管理:
#include <assert.h> #include <stdio.h> #include <stdint.h> #include <stdlib.h> #include <string.h> #include <sys/time.h> #include <sys/types.h> #include <sys/stat.h> #include <signal.h> #include <unistd.h> #include <time.h> #include <libmemcached/memcached.h> #include <libmemcached/memcached_util.h> int main(void) { memcached_return_t rc; memcached_st *memc; memc = memcached_create(NULL); const char *keys[] = {"foo", "foo2"}; size_t lengths[] = {3,4}; const char *values[]= { "fjord", "41" }; memcached_server_st *servers; //servers= memcached_server_list_append(NULL, "localhost", 21201, &rc); servers = memcached_server_list_append_with_weight(NULL,"localhost",21201,0,&rc); assert (servers != NULL); memcached_server_push(memc,servers); memcached_pool_st *pool = memcached_pool_create(memc,5,10); // Set foo and foo2 int i; for ( i= 0; i < 2; i++) { rc= memcached_set(memc, keys[i], lengths[i], values[i], strlen(values[i]), (time_t)0, (uint32_t)0); assert(rc == MEMCACHED_SUCCESS); } char *string; size_t string_length; uint32_t flags; // retrieve both via mget rc= memcached_mget(memc, keys, lengths, 2); assert(rc == MEMCACHED_SUCCESS); char key[MEMCACHED_MAX_KEY]; size_t key_length; // this should get both for ( i = 0; i < 2; i++) { string= memcached_fetch(memc, key, &key_length, &string_length, &flags, &rc); assert(rc == MEMCACHED_SUCCESS); int val = 0; if (key_length == 4) val= 1; assert(string_length == strlen(values[val])); assert(strncmp(values[val], string, string_length) == 0); free(string); } // this should indicate end string= memcached_fetch(memc, key, &key_length, &string_length, &flags, &rc); assert(rc == MEMCACHED_END); // now get just one rc= memcached_mget(memc, keys, lengths, 1); assert(rc == MEMCACHED_SUCCESS); string= memcached_fetch(memc, key, &key_length, &string_length, &flags, &rc); assert(key_length == lengths[0]); assert(strncmp(keys[0], key, key_length) == 0); assert(string_length == strlen(values[0])); assert(strncmp(values[0], string, string_length) == 0); assert(rc == MEMCACHED_SUCCESS); free(string); // this should indicate end string= memcached_fetch(memc, key, &key_length, &string_length, &flags, &rc); assert(rc == MEMCACHED_END); memcached_free(memc); return 1; }
基本的api,libmemcached给出的examples比较少,建议看下他自带的tests目录下的测试函数,比较有帮助,libmemcached-api基本操作差不多了,下面估计要研究的是如何将memcacheq实现分布。初步是简单的通过一致性hash算法,将消息分布到不同的memcacheq中去。
接着需要研究下redis,等下周就开始动手上路了。