77范文网 - 专业文章范例文档资料分享平台

memcached使用文档(4)

来源:网络收集 时间:2019-04-22 下载这篇文档 手机版
说明:文章内容仅供预览,部分内容可能不全,需要完整文档或者需要复制内容,请下载word后使用。下载word有问题请添加微信号:或QQ: 处理(尽可能给您提供完整文档),感谢您的支持与谅解。点击这里给我发消息

存储媒介,例如在SSO系统中保存系统单点登陆状态的数据就可以保存在 memcached中,被多个应用共享。

101. 需要注意的是,memcached使用内存管理数据,所以它是易失的,当服务器重启,或者memcached进程中止,数据便会丢失,所以 memcached不能用来持久保存数据。很多人的错误理解,memcached的性能非常好,好到了内存和硬盘的对比程度,其实memcached使用 内存并不会得到成百上千的读写速度提高,它的实际瓶颈在于网络连接,它和使用磁盘的数据库系统相比,好处在于它本身非常“轻”,因为没有过多的开销和直接 的读写方式,它可以轻松应付非常大的数据交换量,所以经常会出现两条千兆网络带宽都满负荷了,memcached进程本身并不占用多少CPU资源的情况。

102. ◎Memcached的工作方式

103. 以下的部分中,读者最好能准备一份memcached的源代码。 104. Memcached是传统的网络服务程序,如果启动的时候使用了-d参数,它会以守护进程的方式执行。创建守护进程由daemon.c完成,这个程序只有一个daemon函数,这个函数很简单(如无特殊说明,代码以1.2.1为准):

105. #include 106. #include 107. #include 108.

109. int daemon(nochdir, noclose) 110. { int nochdir, noclose; 111.

112. int fd; 113.

114. switch (fork()) { 115. case -1:

116. return (-1); 117. case 0: 118. break; 119. default:

120. _exit(0); 121. } 122.

123. if (setsid() == -1) 124. return (-1); 125.

126. if (!nochdir)

127. (void)chdir(\128.

129. if (!noclose && (fd = open(\{

130. (void)dup2(fd, STDIN_FILENO);

131. (void)dup2(fd, STDOUT_FILENO); 132. (void)dup2(fd, STDERR_FILENO); 133. if (fd > STDERR_FILENO) 134. (void)close(fd); 135. }

136. return (0); 137. }

138. 这个函数 fork 了整个进程之后,父进程就退出,接着重新定位 STDIN 、 STDOUT 、 STDERR 到空设备, daemon 就建立成功了。 139. Memcached 本身的启动过程,在 memcached.c 的 main 函数中顺序如下:

140. 1 、调用 settings_init() 设定初始化参数 2 、从启动命令中读取参数来设置 setting 值 3 、设定 LIMIT 参数

4 、开始网络 socket 监听(如果非 socketpath 存在)( 1.2 之后支持 UDP 方式)

5 、检查用户身份( Memcached 不允许 root 身份启动)

6 、如果有 socketpath 存在,开启 UNIX 本地连接(Sock 管道) 7 、如果以 -d 方式启动,创建守护进程(如上调用 daemon 函数) 8 、初始化 item 、 event 、状态信息、 hash 、连接、 slab 9 、如设置中 managed 生效,创建 bucket 数组 10 、检查是否需要锁定内存页 11 、初始化信号、连接、删除队列 12 、如果 daemon 方式,处理进程 ID

13 、event 开始,启动过程结束, main 函数进入循环。

141. 在 daemon 方式中,因为 stderr 已经被定向到黑洞,所以不会反馈执行中的可见错误信息。

142. memcached.c 的主循环函数是 drive_machine ,传入参数是指向当前的连接的结构指针,根据 state 成员的状态来决定动作。

143. Memcached 使用一套自定义的协议完成数据交换,它的 protocol 文档可以参考:

http://code.sixapart.com/svn/memcached/trunk/server/doc/protocol.txt

144. 在API中,换行符号统一为\\r\\n 145. ◎Memcached的内存管理方式

146. Memcached有一个很有特色的内存管理方式,为了提高效率,它使用预申请和分组的方式管理内存空间,而并不是每次需要写入数据的时候去malloc,删除数据的时候free一个指针。Memcached使用slab->chunk的组织方式管理内存。

147. 1.1和1.2的slabs.c中的slab空间划分算法有一些不同,后面会分别介绍。

148. Slab可以理解为一个内存块,一个slab是memcached一次申请内存的最小单位,在memcached中,一个slab的大小默 认为1048576字节(1MB),所以memcached都是整MB的使用内存。每一个slab被划分为

若干个chunk,每个chunk里保存一个 item,每个item同时包含了item结构体、key和value(注意在memcached中的value是只有字符串的)。slab按照自己的 id分别组成链表,这些链表又按id挂在一个slabclass数组上,整个结构看起来有点像二维数组。slabclass的长度在1.1中是21,在 1.2中是200。

149. slab有一个初始chunk大小,1.1中是1字节,1.2中是80字节,1.2中有一个factor值,默认为1.25

150. 在1.1中,chunk大小表示为初始大小*2^n,n为classid,即:id为0的slab,每chunk大小1字节,id为1的 slab,每chunk大小2字节,id为2的slab,每chunk大小4字节??id为20的slab,每chunk大小为1MB,就是说id为20 的slab里只有一个chunk: 151. void slabs_init(size_t limit) { 152. int i;

153. int size=1; 154.

155. mem_limit = limit;

156. for(i=0; i<=POWER_LARGEST; i++, size*=2) { 157. slabclass[i].size = size;

158. slabclass[i].perslab = POWER_BLOCK / size; 159. slabclass[i].slots = 0;

160. slabclass[i].sl_curr = slabclass[i].sl_total = slabclass[i].slabs = 0;

161. slabclass[i].end_page_ptr = 0; 162. slabclass[i].end_page_free = 0; 163. slabclass[i].slab_list = 0; 164. slabclass[i].list_size = 0; 165. slabclass[i].killing = 0; 166. } 167.

168. /* for the test suite: faking of how much we've already malloc'd */ 169. {

170. char *t_initial_malloc = getenv(\171. if (t_initial_malloc) { 172. mem_malloced =

atol(getenv(\173. } 174. } 175.

176. /* pre-allocate slabs by default, unless the environment variable

177. for testing is set to something non-zero */ 178. {

179. char *pre_alloc = getenv(\180. if (!pre_alloc || atoi(pre_alloc)) {

181. slabs_preallocate(limit / POWER_BLOCK); 182. } 183. } 184. }

185. 在1.2中,chunk大小表示为初始大小*f^n,f为factor,在

memcached.c中定义,n为classid,同时,201个头不 是全部都要初始化的,因为factor可变,初始化只循环到计算出的大小达到slab大小的一半为止,而且它是从id1开始的,即:id为1的slab, 每chunk大小80字节,id为2的slab,每chunk大小80*f,id为3的slab,每chunk大小80*f^2,初始化大小有一个修正值 CHUNK_ALIGN_BYTES,用来保证n-byte排列 (保证结果是CHUNK_ALIGN_BYTES的整倍数)。这样,在标准情况下,memcached1.2会初始化到id40,这个slab中每个 chunk大小为504692,每个slab中有两个chunk。最后,slab_init函数会在最后补足一个id41,它是整块的,也就是这个 slab中只有一个1MB大的chunk: 186. 187.

188. void slabs_init(size_t limit, double factor) { 189. int i = POWER_SMALLEST - 1;

190. unsigned int size = sizeof(item) + settings.chunk_size; 191.

192. /* Factor of 2.0 means use the default memcached behavior */ 193. if (factor == 2.0 && size < 128) 194. size = 128; 195.

196. mem_limit = limit;

197. memset(slabclass, 0, sizeof(slabclass)); 198.

199. while (++i < POWER_LARGEST && size <= POWER_BLOCK / 2) { 200. /* Make sure items are always n-byte aligned */ 201. if (size % CHUNK_ALIGN_BYTES)

202. size += CHUNK_ALIGN_BYTES - (size % CHUNK_ALIGN_BYTES); 203.

204. slabclass[i].size = size;

205. slabclass[i].perslab = POWER_BLOCK / slabclass[i].size; 206. size *= factor;

207. if (settings.verbose > 1) {

208. fprintf(stderr, \perslab ]\\n\

209. i, slabclass[i].size, slabclass[i].perslab);

210. } 211. } 212.

213. power_largest = i;

214. slabclass[power_largest].size = POWER_BLOCK; 215. slabclass[power_largest].perslab = 1; 216.

217. /* for the test suite: faking of how much we've already malloc'd */ 218. {

219. char *t_initial_malloc = getenv(\220. if (t_initial_malloc) { 221. mem_malloced =

atol(getenv(\222. } 223.

224. } 225.

226. #ifndef DONT_PREALLOC_SLABS 227. {

228. char *pre_alloc = getenv(\229. if (!pre_alloc || atoi(pre_alloc)) {

230. slabs_preallocate(limit / POWER_BLOCK); 231. } 232. } 233. #endif 234. }

235. 由上可以看出,memcached的内存分配是有冗余的,当一个slab不能被它所拥有的chunk大小整除时,slab尾部剩余的空间就被丢弃了,如id40中,两个chunk占用了1009384字节,这个slab一共有1MB,那么就有39192字节被浪费了。

236. Memcached使用这种方式来分配内存,是为了可以快速的通过item长度定位出slab的classid,有一点类似hash,因为 item的长度是可以计算的,比如一个item的长度是300字节,在1.2中就可以得到它应该保存在id7的slab中,因为按照上面的计算方 法,id6的chunk大小是252字节,id7的chunk大小是316字节,id8的chunk大小是396字节,表示所有252到316字节的 item都应该保存在id7中。同理,在1.1中,也可以计算得到它出于256和512之间,应该放在chunk_size为512的id9中(32位系 统)。

237. Memcached初始化的时候,会初始化slab(前面可以看到,在main函数中调用了slabs_init())。它会在 slabs_init()中检查一个常量DONT_PREALLOC_SLABS,如果这个没有被定义,说明使用预分配内存方式初始化slab,这样在所 有已经定义过的slabclass中,每一个id创建

百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说综合文库memcached使用文档(4)在线全文阅读。

memcached使用文档(4).doc 将本文的Word文档下载到电脑,方便复制、编辑、收藏和打印 下载失败或者文档不完整,请联系客服人员解决!
本文链接:https://www.77cn.com.cn/wenku/zonghe/614718.html(转载请注明文章来源)
Copyright © 2008-2022 免费范文网 版权所有
声明 :本网站尊重并保护知识产权,根据《信息网络传播权保护条例》,如果我们转载的作品侵犯了您的权利,请在一个月内通知我们,我们会及时删除。
客服QQ: 邮箱:tiandhx2@hotmail.com
苏ICP备16052595号-18
× 注册会员免费下载(下载后可以自由复制和排版)
注册会员下载
全站内容免费自由复制
注册会员下载
全站内容免费自由复制
注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: