Memcached 基础知识
来源:互联网 发布:淘宝夏季情侣装 编辑:程序博客网 时间:2024/06/06 14:13
1. 基本信息
memcached是一个高性能的内存缓存对象系统,其实质为一个键值对的hashmap.其事件处理和网络通信均是基于libevent.
基本特征:
协议简单:使用基于文本行的协议
基于内存存储:数据存储在内存中
事件处理:基于libevent开发
不互相通信的分布式:多台memcached服务器之间不互相通信,由客户端实现分布式算法
图1 memcached的分布式(转来的图)
1.1 内存管理机制
memcached采用名为slab allocator的内存管理机制,其基本原理是将预先规定的大小,将内存划分为特定长度的块。目的是要解决简单的malloc/free方式所造成的内存碎片。
Slab是memcached分配的基本单位,每个Slab对应多张Page(默认大小是1M),每张Page会被划分为多个chunk(每个chunk中都保存了一个item结构体、一对key和value)。
早期的版本中,每个Page一旦被分配给一个Slab,其后变一直如遇该Slab,但在较新的版本中,一个Page已经可以被重新分配给不同的Slab。
当客户端发来一条数据时,memcached根据数据的大小选择最为合适的Slab,将其存储在对应的Slab中。但是这也会带来新的问题,即内存的利用率会下降,例如,当一个100byte的数据到来,我们不得不为其分配一个128bytes的chunk,其多余的28字节就被浪费掉了。
为了尽量低的减少内存的浪费,memcached预先设定了40类Slab,通过在启动时加入-vv命令可以查看(两个v)
usr/local/memcached/bin/memcached -d -m 256 -l 127.0.0.1 -p 11212 -c 1024 -u root -vv
memcached默认的使用1.25作为增长因子,在使用memcached的过程中我们通过调整-f (成长因子、 -n(default size)等参数优化内存使用,计算公式如下(抄来的):
chunk size(class i) : (default_size+item_size)*f^(i-1)+ CHUNK_ALIGN_BYTES
当没有可用Page时,memcached开始对Slab执行LRU算法删除冷数据,这里必须明确一点即LRU执行的对象是 Slab不是全局。
2. 安装、配置及启动
首先,安装libevent:
wget http://monkey.org/~provos/libevent-1.4.13-stable.tar.gztar xzvf libevent-1.4.13-stable.tar.gzcd libevent-1.4.13-stable./configure && make && make install
然后,安装memcached
wget http://memcached.org/latesttar zxvf memcached-1.4.21.tar.gz && cd memcached-1.4.21./configure && make && make install
默认情况下程序会安装到 /usr/local/bin/memcached,接下来我们就可以启动memcached了,首先让我们来看一下启动参数,这里我们仅介绍一下常用的参数,更详细的参数列表可以通过man memcached查看:
-l 设置监听的ip地址,默认为 INADDR_ANY
-d 以守护进程模式运行memcached
-u 指定用户
-m 设置memcached可以使用的内存大小,单位为 M
-c 设置最大链接数,默认为1024
-R 设置一个客户端的最大连续请求数,默认为20
-p 设置TCP监听端口
-U 设置UDP监听端口
-P 设置memcached的Pid文件
/usr/local/bin/memcached -d -m 256 -l 127.0.0.1 -p 11211 -c 1024 -u root
3. telnet方式
连接memcached:
3.1 存储命令
<command name> <key> <flags> <expire> <bytes><value><command name>set/add/replace<key>索引值 <flags>标志信息<expire>过期时间,0表示永不过期<bytes>value的字节数<value>存储的数据块
set 命令:即可以添加新数据还可以更新已存在数据
add命令:仅在数据不存在时添加数据
replace命令:仅在数据存在时更新数据
3.2 清除命令
<command name> <key>
delete命令: 删除已存在的数据
flush_all命令:清空数据。实际上它是时此命令之前插入的数据,在读取时无效化,同时在新数据到来后清除老数据
3.3 读取命令
<command name> <key>get命令:读取指定key的值
gets命令:读取指定key的值,末尾比get命令多一个值,限制value否改变,该值变化说明value发生了变化.
cas命令:仅当最后一个参数与gets取得结果的最后一个参数匹配时才更新(应该算是添加数据命令,但放在这里比较好解释)
3.4 更新数据命令
append命令:在现有数据之后添加字符
prepend命令:在现有数据之前添加字符
incr/decr命令:对数值型value进行增减,支持64位无符号数,最后那个参数表示变更的范围
3.5 查询状态命令
stats命令:
stats item命令:查看条目状态
stats slabs命令:查看内存情况
还有stats sizes,stats reset等等使用也比较常见.
4. libmemcached
4.1 基本数据结构
memcached_st 结构:用于保存memcached连接对象
memcached_return_t结构: 用于保存memcached命令执行状态
memcached_server_st 结构:用于存储memcached服务器列表
4.2 创建和销毁一个memcached连接对象
memcached_st* memcached_create(memcached_st* ptr) 创建一个memcached_st对象,参数一般为NULL; memcached_st* memcached_clone(memcached_st* dest,memcached_st* src) 克隆一个memcached对象; void memcached_free(memcached_st* ptr) 释放memcached对象,断开连接时使用;
4.3 操作memcached_st中存储的server信息
memcached_return_t memcached_server_add(memcached_st *mem,const char *hostname, int port); //在服务器列表尾部添加一台servermemcached_server_st* memcached_server_list_append(memcached_server_st* ptr,const char* hostname,int port,memcached_return_t * return) ; // 在memcached_server_st中添加一台servermemcached_return_t memcached_server_push(memcached_st *mem,memcached_server_st* ptr); //在服务器列表尾部添加一个server数组,与memcached_server_list_append结合使用uint32_t memcached_server_count(memcached_st* mem); //计算当前server的个数void memcached_servers_reset(memcached_st* mem); //清空server列表void memcached_server_list_free(memcached_server_st* ptr); //释放memcached_server_st结构
4.4 操作memcached数据
增减数据值:
memcached_return_t memcached_increment(memcached_st *ptr, const char *key, size_t key_length, uint32_t offset, uint64_t *value)//将指定key的value值加1memcached_return_t memcached_decrement(memcached_st *ptr, const char *key, size_t key_length, uint32_t offset, uint64_t *value)//将指定key的value值减1
删除数据
memcached_return_t memcached_delete(memcached_st *ptr, const char *key, size_t key_length, time_t expiration)
检查key值是否存在
memcached_return_t memcached_exist(memcached_st *ptr, char *key, size_t *key_length)
memcached_return_t memcached_flush(memcached_st *ptr, time_t expiration)
获取数据
char * memcached_get(memcached_st *ptr, const char *key, size_t key_length, size_t *value_length, uint32_t *flags, memcached_return_t *error)//获取单个数据memcached_return_t memcached_mget(memcached_st *ptr, const char * const *keys, const size_t *key_length, size_t number_of_keys)//获取多个数据,需要注意的是,当使用多个server时mget无法通过一次条用返回不同存储在不同server上的数据char* memcached_fetch(memcached_st *ptr,char* keys, size_t *key_length,size_t* value_length,uint32_t* flags,memcached_return_t *error)//从上面函数的结果中提取数据
写入数据
memcached_return_t memcached_set(memcached_st *ptr, const char *key, size_t key_length, const char *value, size_t value_length, time_t expiration, uint32_t flags)//向memcached写入一条数据,存在即覆盖memcached_return_t memcached_add(memcached_st *ptr, const char *key, size_t key_length, const char *value, size_t value_length, time_t expiration, uint32_t flags)//不存在即插入,存在返回错误memcached_return_t memcached_replace(memcached_st *ptr, const char *key, size_t key_length, const char *value, size_t value_length, time_t expiration, uint32_t flags)//存在即覆盖,不存在返回错误memcached_set在非阻塞模式下只有当网络错误发生时才会返回错误
扩展字符串
memcached_return_t memcached_prepend(memcached_st *ptr, const char *key, size_t key_length, const char *value, size_t value_length, time_t expiration, uint32_t flags)//在原来的字符串之前添加内容memcached_return_t memcached_append(memcached_st *ptr, const char *key, size_t key_length, const char *value, size_t value_length, time_t expiration, uint32_t flags)//在原来的字符串末尾添加内容
上面这些接口仅用于TCP调用,libmemcached中对UDP和UNIX SOCKET也有相应的支持。
基本上,libmemcached提供了所有与命令行对应的功能接口,可以查询http://docs.libmemcached.org/
这里我们通过实例代码简要的说明一下存储和获取数据的接口
#include <libmemcached/memcached.h>int main(int argc, char* argv[]){ memcached_st *mem; memcached_return_t re; memcached_server_st *svr; //连接memcached mem = memcached_create(NULL); svr = memcached_server_list_append(NULL,"127.0.0.1",11211,&rc); rc = memcached_server_push(mem,srv); memcached_server_list_free(srv); //存储数据 char* value = "zhoushuaiyin"; rc = memcached_set(mem,"zhou",4,value,strlen(value),0,0); if(MEMCACHED_SUCCESS == rc){ //anything } //分别使用mgets+fetch和mget方式获取数据 char *return_value = NULL; size_t return_value_length; char* keys[]={"zhou"}; size_t keys_length[]={4}; uint32 flags; rc = memcached_mget(mem,keys,keys_length,1); return_value = memcached_fetch(mem,return_key,&return_key_length,&return_value_length,&flags,&rc); if(MEMCACHED_SUCCESS == rc){ printf("key:%s, value:%s",return_key,return_value); } char* val = memcached_get(mem,"zhou",4, &return_value_length,&flags,&rc);if(MEMCACHED_SUCCESS == rc){ printf("key:%s, value:%s",return_key,return_value); } //删除数据 rc = memcached_delete(mem,"zhou", 4 , (time_t)0); memcached_free(mem); retrun 0;}
再给出一段memcached一致性hash的代码,包括使用memcached_get_by_key函数(by_key结尾的函数都具有相同的意义),不是很规范,但应该可以说明问题:
#include<libmemcached/memcached.h>int main(int argc, char* argv[]){ memcached_st *mem; memcached_return_t rc; memcached_server_st* servers; mem = memcached_create(NULL); memcached_behavior_set(mem,MEMCACHED_BEHAVIOR_DISTRIBUTION,MEMCACHED_DISTRIBUTION_CONSISTENT); servers = memcached_server_list_append(NULL,"localhost",11211,&rc); servers = memcached_server_list_append(servers,"localhost",11210,&rc); rc = memcached_server_push(mem,servers); memcached_server_free(servers); printf("the server count is %d",memcached_server_count(mem)); const char* const keys[] = {"key1","key2","key3","key4"}; char* values[] = {"value1","value2","value3","value4"}; for(int i = 0 ; i < 4; i++){ memcached_set(mem,keys[i],strlen(keys[i]),values[i],strlen(values[i]),0,0); } size_t value_length[4]; uint32_t flag; for(int i = 0; i < 4; i++){ values[i] = memcached_get(mem,keys[i],strlen(keys[i]),&value_length[i],&flag,&rc); printf("the value is %s\n",values[i]); } char* value = "zhou"; size_t flag2; value = memcached_get_by_key(mem,keys[1],strlen(keys[1]),keys[1],strlen(keys[1]),&flag2,&flag,&rc); printf("the value is %s\n",value); memcached_free(mem); return 0;}
5. PHP与memcached通信
参阅:http://php.net/manual/zh/class.memcached.php
- Memcached 基础知识
- Memcached 基础知识
- memcached的基础知识
- 【Memcached】基础知识-Cache
- memcached基础知识和简单命令
- Memcached 缓存系统的基础知识
- memcached入门基础知识(2)
- memcached Java调用,注意点和基础知识
- memcached系列之1:memcached基础知识简介(为什么要使用memcached做缓存服务器)
- memcached系列之1:memcached基础知识简介(为什么要使用memcached做缓存服务器)
- memcached系列之1:memcached基础知识简介(为什么要使用memcached做缓存服务器)
- memcached缓存系统学习笔记之一:memcached缓存系统基础知识和环境搭建
- memcached缓存系统学习笔记之一:memcached缓存系统基础知识和环境搭建
- memcached缓存系统学习笔记之一:memcached缓存系统基础知识和环境搭建
- Memcached
- memcached
- Memcached
- memcached
- Linux IPCs - Semaphore
- 理解RESTful架构
- 67 俩个闲玩娱乐。 1.扑克牌的顺子
- 用JAVA写一个关于英寸和厘米之间的换算
- 复合类型
- Memcached 基础知识
- Java 字符串方法举例
- ZOJ 3822 Domination 概率DP
- This关键字细节
- 67 2.n个骰子的点数。
- 找工作--笔试面试--准备8
- bombing:cocos2d-x内存管理机制-侧重调用
- CodeForces-228A-Is your horseshoe on the other hoof?
- 基于C++的灰度值方图处理