当前位置:文档之家› Memcached源码剖析笔记

Memcached源码剖析笔记

Memcached源码剖析笔记
Memcached源码剖析笔记

Memcached

源码剖析笔记

Xguru

Memcached是一个自由、源码开放、高性能、分布式

内存对象缓存系统,目的在于通过减轻数据库负载来使

动态Web应用程序提速。

目录

1.背景 (3)

2.memcached的安装 (4)

3.memcached的配置 (5)

4.memcached的使用 (6)

4.1.存储命令 (7)

4.2.读取命令 (8)

4.3.删除命令 (8)

4.4.高级命令 (9)

4.5.其他命令 (10)

5.Memcached内部工作机制 (11)

5.1.Memcached基本的数据结构 (11)

5.2.基本设计概念和处理流程 (12)

5.3.内部Hash机制 (15)

5.3.1.Hash函数及冲突解决 (15)

5.3.2.HashTable主要函数 (15)

5.4.slab内存处理机制 (17)

5.4.1.slab主要函数 (17)

5.4.2.slab机制中所采用的LRU算法 (19)

5.5.控制item各种函数 (20)

5.6.守护进程机制 (22)

5.7.Socket处理机制 (23)

1

5.7.1.Unix域协议 (23)

5.7.2.TCP/UDP协议 (24)

5.8.多线程处理机制 (25)

5.9.事件处理机制 (25)

6.未完善之处 (27)

7.参考文献 (28)

2

1.背景

Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提供动态、数据库驱动网站的速度。Memcached基于一个存储键/值对的hashmap。

Memcached是一个自由、源码开放、高性能、分布式内存对象缓存系统,目的在于通过减轻数据库负载来使动态Web应用程序提速。

Memcached是一个在内存中对任意的数据(比如字符串,对象等)所使用的key-value 存储。数据可以来自数据库调用,API调用,或者页面渲染的结果。

Memcached设计理念就是小而强大,它简单的设计促进了快速部署、易于开发,并解决面对大规模的数据缓存的许多难题。所开放的API能用于大部分流行的程序语言

3

2.memcached的安装

由于memcached采用libevent的事件处理机制,因此安装memcached之前需要先安装libevent。

Memcached: https://www.doczj.com/doc/3017404300.html,/

Libevent : https://www.doczj.com/doc/3017404300.html,/~provos/libevent/

在Ubuntu下可以使用sudo apt-get install libevent和sudo apt-get install memcached来安装

或者使用传统wget的方式

~$ wget https://www.doczj.com/doc/3017404300.html,/files/memcached-1.2.8.tar.gz.

tar.gz

~$ tar zxf memcached1.2.8.

tar.gz

~$ cd memcached1.2.8

~$ ./configure

~$ make

目前最新的版本为1.4.4

4

5

3. memcached 的配置

主要使用的命令

-d 以守护程序(daemon )方式运行 memcached ; -m 设置 memcached 可以使用的内存大小,单位为 M ;

-l 设置监听的 IP 地址,如果是本机的话,通常可以不设置此参数; -p 设置监听的端口,默认为 11211,所以也可以不设置此参数; -u 指定用户,如果当前为 root 的话,需要使用此参数指定用户。 -f 设置增长因子(调优时使用) -v/-vv 详细显示工作时各种参数

Memcached

采用典型的

getopt()函数获取各种配置 比如

6

./memcached -m 512 -p 11211 -vv

该例分配给memcached 的可用内存512M ,监听11211端口,显示详细的运行信息。

4. memcached 的使用

memcached 提供的API 可以在大多数的编程语言使用,在这里测试使用的是PuTTy 的telnet 方式,使用telnet 连接其11211端口。

Memcached 有4种类型的命令:

● 存储命令(set/add /replace/append/prepend )指示服务器储存一些由键值标识的

数据。客户端发送一行命令,后面跟着数据区块;然后,客户端等待接收服务器回传的命令行,指示成功与否。

读取命令(get/bget/gets )指示服务器返回与所给键值相符合的数据(一个请求中右

一个或多个键值)。客户端发送一行命令,包括所有请求的键值;服务器每找到一项内

容,都会发送回客户端一行关于这项内容的信息,紧跟着是对应的数据区块;直到服务器以一行“END”回应命令结束。

●状态命令(stat)被用于查询服务器的运行状态和其他内部数据。

●其他命令,如flush_all,version,quit等。

4.1.存储命令

命令格式:

命令解释:

存储命令区别

7

4.2.读取命令

get

可以表示一个或多个键值,由空格隔开的字串

4.3.删除命令

delete

删除键值为key的数据。

8

9

4.4. 高级命令

值得一提的是,新版本的memcached 加入了gets 和cas 命令

可以看到此处gets 比普通的get 多返回一个数字,这个数字可以用作检查数据是否发生改变。当key 对应的数据改变的时候,该数会发生改变,如图中红圈所示。

cas 就是check and set 之意,只有当最后一个参数与gets

所获取的参数匹配时才能

存储,否则返回“EXISTS ”。这种设计的意图是防止使用经过改变了的value/key 对。

4.5.其他命令

查看状态

其他更多的命令可以参看memcached的协议:

https://www.doczj.com/doc/3017404300.html,/svn/memcached/trunk/server/doc/protocol.txt。

了解了其基本工作方式以后再来看源代码发现清晰很多。

10

11

5. Memcached 内部工作机制

5.1. Memcached 基本的数据结构

item 为memcached 中的存储数据最小单位,其中还记录有数据和最近访问时间数据大小,桶的下一项等数据,每个不同slab 的元素内含有具有统一分配的尺寸的各个item 。可以这样理解,每个item 是存储在其对应大小的

slabclass_t 里的,同时又在hash 表中有记录。既可以使用自己的内存分配机制来减少操作系统在处理内存碎片,添加释放等多余的操作,又可以使用hash 表的性质对其进行快速的定位。

slabclass 是由(POWER_LARGEST + 1 )个slabclass_t 结构体构成的数组,每个slabclass_t 结构体的大小是根据增长因子递增的,增长因子可以由客户端来设定,1.28版本的默认值为2,合理的调优增长因子可以避免空间的浪费。

5.2.基本设计概念和处理流程

12

13

在这里值得注意的是,add/set/replace/cas这类存储命令在conn_read里的操作只是分配了item的空间,并没有对其进行存储工作,当conn_read结束后设置状态为conn_nread再做进一步的处理。

14

15

5.3. 内部Hash

机制

5.3.1. Hash 函数及冲突解决

memcached 采用的hash 函数是Bob Jenkins 先生在1996创立的一个算法,复杂度为O (6n+35),而且冲突率极低,该算法具体过程可以参阅这里。冲突处理的方法为开链法。

memcached 中实际有两个hash 表,一个是“主hash 表”(primary_hashtable ),另外一个是“原有hash 表”(old_hashtable )。每次操作的时候,先会检测表是否正处于扩展(expanding)状态,如果扩展还没完成时,先在原有hash 表中操作数据。 5.3.2. HashTable 主要函数 assoc_init()

初始化hash 表,为主hash 表分配空间。 assoc_find()

根据key 值来查找item ,如果有冲突存在,则不停往桶的下一个元素(h_next )里查找,直至找到为止,并返回其指针。 assoc_insert()

在hash 表中插入item ,如果装载因子大于1.5,则扩展哈希表

assoc_delete()

用_hashitem_befor()找键值为key的item之前的指针,改变其指向,数据实际上是没有被释放的,在这里只是从hash表中移除。

assoc_expend()

扩展hash表到2的下一次方,比如现在是hash表的大小2^16,扩展后大小则为2^17。再进行数据迁移,扩展时候不能再分配内存时,就保持原有的表不变。

do_assoc_move_next_bucket()

将下一个桶迁移到先前的我们扩充的哈希表中

_hashitem_before ()

(内部使用)返回该键值所对应的item的之前的指针。

16

5.4.slab内存处理机制

slab源于Jeff Bonwick 为SunOS 操作系统首次引入的一种内存处理机制,SLAB 的设计理念是基于对象缓冲的,基本想法是避免重复大量的初始化和清理操作。SLAB 主要可以用于频繁分配释放的内存对象。如果是采用系统自带的malloc/free话,反复地操作会造成大量内存碎片,操作系统将会花费大量的时间去查找连续的内存块来满足malloc的请求。

memcached中内存分配机制主要理念

1.先为分配相应的大块内存,再在上面进行无缝小对象填充

2.懒惰检测机制,Memcached不花过多的时间在检测各个item对象是否超时,当get

获取数据时,才检查item对象是否应该删除,你不访问,我就不处理。

3.懒惰删除机制,在memecached中删除一个item对象的时候,并不是从内存中释放,

而是单单的进行标记处理,再将其指针放入slot回收插糟,下次分配的时候直接使用。

5.4.1.slab主要函数

slabs_init()

slab初始化,如果配置时采用预分配机制(prealloc)则在先在这使用malloc分配所有内存。

再根据增长因子factor给每个slabclass分配容量。

slabs_clsid()

计算出哪个slabclass适合用来储存大小给定为size的item,如果返回值为0则存储的物件过大,无法进行存储。

do_slabs_alloc()

在这个函数里面,由宏定义来决定采用系统自带的malloc机制还是memcached的slab机制对内存进行分配,理所当然,在大多数情况下,系统的malloc会比slab慢上一个数量级。

分配时首先考虑slot内的空间(被回收的空间),再检查end_page_ptr指针指向的的空闲空间,还是没有的空间的话,再试试分配新的内存。如果所有空间都用尽的时候,则返回NULL表示目前资源已经枯竭了。

17

do_slabs_free()

首先检查当目前的插糟是否已经达到可用总插糟的总容量,如果达到就为其重新分配空间,再将该回收的item的指针插入对应当前id的slabclass的插糟(slots)之中。

do_slabs_stats()

将目前slab的状态填充至buf缓存中并将其返回。

do_slab_reassign()

清除在一个slab class里的所有的item,将其移动到另外一个class 。只有在处理”slab reassign”命令选择手动调整内存分配的时候才会使用,默认是禁止的。

18

5.4.2.slab机制中所采用的LRU算法

在memcached运行过程中,要把一个item调入内存,但内存已无空闲空间时,为了保证程序能正常运行,系统必须从内存中调出一部分数据,送磁盘的对换区中。但应将哪些数据调出,须根据一定的算法来确定。通常,把选择换出数据(页面)的算法称为页面置换算法(Page Replacement Algorithms)。 Memcached采用最近最久未使用(LRU)置换算法,是根据数据(页面)调入内存后的使用情况进行决策的。由于无法预测各页面将来的使用情况,只能利用“最近的过去”作为“最近的将来”的近似,因此,LRU 置换算法是选择最近最久未使用的页面予以淘汰。当内存不足时,memcached会从slab 各个class中的双向链表的尾部开始检测,即最近最久未使用的页面,往前一直寻找合适的item予以淘汰。所以该LRU算法为slab局部class淘汰的机制。但是在一些特定情形也会可能引起一些不必要的麻烦,可以在运行时加入”-M”参数禁止该算法。

19

侯捷stl源码剖析注释之42 sgi-stl-slist

完整列表 The Annotated STL Sources 1 G++ 2.91.57,cygnus\cygwin-b20\include\g++\stl_slist.h 完整列表 /* * Copyright (c) 1997 * Silicon Graphics Computer Systems, Inc. * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. Silicon Graphics makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. * */ /* NOTE: This is an internal header file, included by other STL headers. * You should not attempt to use it directly. */ #ifndef __SGI_STL_INTERNAL_SLIST_H #define __SGI_STL_INTERNAL_SLIST_H __STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1174 #endif // 單向串列的節點基本結構 struct __slist_node_base { __slist_node_base* next ; }; // 全域函式:已知某一節點,安插新節點於其後。 inline __slist_node_base* __slist_make_link (__slist_node_base* prev_node, __slist_node_base* new_node) { // 令 new 節點的下一節點為prev 節點的下一節點 new_node->next = prev_node->next; prev_node->next = new_node; // 令 prev 節點的下一節點指向new 節點 return new_node; } // 全域函式:找出某一節點的前一個節點。 inline __slist_node_base* __slist_previous (__slist_node_base* head, const __slist_node_base* node) {

Memcached源码剖析笔记

Memcached 源码剖析笔记 Xguru Memcached是一个自由、源码开放、高性能、分布式 内存对象缓存系统,目的在于通过减轻数据库负载来使 动态Web应用程序提速。

目录 1.背景 (3) 2.memcached的安装 (4) 3.memcached的配置 (5) 4.memcached的使用 (6) 4.1.存储命令 (7) 4.2.读取命令 (8) 4.3.删除命令 (8) 4.4.高级命令 (9) 4.5.其他命令 (10) 5.Memcached内部工作机制 (11) 5.1.Memcached基本的数据结构 (11) 5.2.基本设计概念和处理流程 (12) 5.3.内部Hash机制 (15) 5.3.1.Hash函数及冲突解决 (15) 5.3.2.HashTable主要函数 (15) 5.4.slab内存处理机制 (17) 5.4.1.slab主要函数 (17) 5.4.2.slab机制中所采用的LRU算法 (19) 5.5.控制item各种函数 (20) 5.6.守护进程机制 (22) 5.7.Socket处理机制 (23) 1

5.7.1.Unix域协议 (23) 5.7.2.TCP/UDP协议 (24) 5.8.多线程处理机制 (25) 5.9.事件处理机制 (25) 6.未完善之处 (27) 7.参考文献 (28) 2

1.背景 Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提供动态、数据库驱动网站的速度。Memcached基于一个存储键/值对的hashmap。 Memcached是一个自由、源码开放、高性能、分布式内存对象缓存系统,目的在于通过减轻数据库负载来使动态Web应用程序提速。 Memcached是一个在内存中对任意的数据(比如字符串,对象等)所使用的key-value 存储。数据可以来自数据库调用,API调用,或者页面渲染的结果。 Memcached设计理念就是小而强大,它简单的设计促进了快速部署、易于开发,并解决面对大规模的数据缓存的许多难题。所开放的API能用于大部分流行的程序语言 3

中华石杉顶尖互联网Java架构师就业班

目录 第一阶段、Spring Boot从入门到精通(10小时) (1) 第二阶段、小型电商网站开发+设计模式+架构设计+项目管理(20小时) (2) 第三阶段、Spring Cloud从入门到精通(20小时) (3) 第四阶段、电商网站的微服务架构(20小时) (3) 第五阶段、高并发大型电商网站架构(150小时) (4) 第六阶段、高可用大型电商网站架构(30小时) (6) 第七阶段、高性能大型电商架构(30小时) (7) 第八阶段、亿级流量的大型电商系统架构(150小时) (7) 第九阶段、自己动手做多租户SaaS云ERP系统 (8) 第十阶段、底层技术+微服务中间件(50小时) (9) 第十一阶段、自己动手写仿Storm的实时计算中间件 (10) 第十二阶段、开源框架源码阅读+定制化开发mvc/ioc/orm框架(50小时) (10) 第十三阶段、自己动手写工作流框架 (10) 授课方式说明 (10) 学习进度说明 (11) 就业指导说明 (12) 学习成果说明 (12) 2万费用说明 (13) 讲师课程质量以及是否会跑路 (14) 第一阶段、Spring Boot从入门到精通(10小时) 目前市面上所有的视频课程以及书籍,都只是简单介绍Spring Boot的基础知识,没有任何一套资料深入讲解这两个技术的。而如果你自己跟着官网慢慢看,全英文官网,估计大部分同学都很难看的懂,或者学习速度非常慢。 我会将Spring Boot的所有核心技术点以及高阶技术点,全部嚼烂咬碎,深度提炼,用最精炼的语言,给大家讲透,让大家在最短的时间内彻底掌握这个未来绝对主流的开发框架,为未来的高阶的项目打好扎实的基础。 强调一下,这块技术讲解,绝对不会采取拖延时间,以及碎碎念的方式,一点一点细节慢慢

STL源码剖析总结_第二章-空间配置器

2.空间配置器 2.1具备次配置力(sub-allocation)的SGI空间配置器 SGI含有两个空间配置器类,std::allocator内存分配类符合标准,但是仅仅是对operator new和operator delete简单封装一下而已;其次是SGI特殊的内存分配器std::alloc,其中实现采用了内存池,对于分配大量小容量的对象,可以大大减少内存碎片。 SGI标准的空间配置器std::allocator 这是对应的模板内联内存分配函数。实现起来也很简单,注意这里分配的内存仅仅是一块没有使用的空间而已,在上面并没有构造对象,后面讲解如何在上面构造对象。 模板内联内存释放函数,直接调用全局的operator delete释放对应的内存。

SGI特殊的空间配置器Std::alloc class Foo{…} Foo* pf = new Foo;//配置内存,然后构造对象delete pf;//将对象析构,然后释放内存 new的算是包含两个阶段:

1)调用::operator new 配置内存 2)调用Foo::Foo()构造对象内容 Delete算式也包含两个阶段 1)调用Foo::~Foo()将对象析构 2)调用::operator delete释放内存 为了精密分工,STL allocator将两个阶段的操作分开来,内存配置操作由alloc::allocate()负责,内存释放操作由alloc::deallocate()负责;对象构造由::construct()负责,对象析构由::destroy()负责。

2.stl_alloc.h 内存空间的分配和释放 内部使用malloc在堆中申请内存,其中制造了一个内存池,可以减少小型区块过多而造成的内存碎片问题。 SGI设计了双层级配置器,第一级配置器直接使用malloc()和free(),第二级配置器则视情况采用不同的策略:当配置区块超过128bytes时,采用第一级配置器,当配置区块小于128bytes时,采用第二级配置器,采用复杂的memory pool。它内存池实际上就是内部维护了16个自由链表,预先已经分配好了,当需要从内存池中取内存时候,直接从对应链表取出即可;当释放内存到内存池时候,直接将内存插入链表即可。每个链表中节点分别占用8、16、24、32、40、48、52、64、72、80、88、96、104、112、120、128字节。

边界网关协议BGP文档分析

《网络协议栈分析与设计》大作业 边界网关协议(BGP)RFC分析与设计Border Gateway Protocol 学生:吕卿网络1101班 201192334 2013/12/16

1.背景介绍 边界网关协议是用来连接网络上不同自治系统(AS)的路由选择协议。BGP是为了取代最初的外部网关协议EGP所设计的,也被认为是路径矢量协议。它通过维护IP路由表和前缀表来实现自治系统(AS)间的可达性。BGP的主要功能是和其他BGP系统交换网络可达性信息。必须要注意的是BGP是建立在可靠连接的基础之上的。 2.操作总结 在两个系统建立的连接中他们互相交互信息更改数据。初始数据流是整个BGP路由表。BGP不要求整个BGP路由表的周期性更新。保持存活信息定期的被发送以确保连接的存活。通知信息被发送来回馈错误通知和特殊情况。执行边际路由协议的主机不必是路由器。一个非路由器的主机可以和路由器经由EGP甚至内部路由协议进行交互。如果一个特殊的自治系统(AS)有多个BGP发言者,那么一定要注意在一个AS内要的几个发言者要有一致的路由视野。 3.信息格式 信息在可靠传输协议连接上发送。信息只有在被完全接收之后才能够被处理。最大的信息大小是4096字节。所有的实现必须支持这一最大信息规格。最小的数据规格要包含BGP头部不含数据部分。 3.1数据头格式 每个信息有个固定大小的头部。包括标识物·长度·类型。标识物:这16字节大小的领域包含信息接收方可以对信息进行确认的信息。长度:这2字节无符号整数表明这则信息的总长度。长度的值必须在19到4096之间类型:这一字节无符号整数表明这则信息的代码模式。共有四种类型: 1 - OPEN 2 - UPDATE 3 - NOTIFICATION 4 - KEEPALIVE

Memcached使用点滴

我对于Memcached的接触,还是在去年看了CSDN的一系列国外大型网站架构设计而开始的。最初的时候只是简单的封装了Memcached Java版的客户端,主要是对于配置的简化以及Memcached多点备份作了一些工作,然后就作为ASF的组件一部分提供给其他Team使用。其实看过Memcached Java客户端代码的人就会了解其实客户端的事情很简单,就是要有一套高性能的Socket通信框架以及对Memcached的私有协议实现的接口,自己去做这些事情也是很简单的,不过既然有可以满足自己需求的开源部分,那么就去实现自己需要的但没有实现的。这里我用的是Whalin的客户端版本,这里为什么还要提出来讲这个,后面会提到。 在对Java客户端作了简单封装和扩展以后,由于其他Team使用的没有什么特殊需求,也就没有再去做太多的修改,直到最近自己的服务集成平台需要做服务访问控制,才重新丰富了Cache组件,也就是这个过程中对于Memcached的一些特性和小的细节有了一些新的认识。 作为服务集成平台需要对服务有所监控,包括访问频率控制以及访问次数控制。频率控制其实很类似于硬件方面的频率控制,例如硬件可以对IP的高频率访问视为攻击,列入黑名单。而作为服务的访问,对于服务访问者的控制其实涉及到了业务参数,那么硬件就不是很适合去做这方面的控制,为此我也考虑了很久,最开始打算在Apache上做一个模块控制,但是最后觉得还是放在后面的业务框架上做这件事情。当然后面我说说的方案可能并不好,但是也算是一种想法。要把频繁的访问数据记录下来同时分析,那么数据库肯定是不行的,最简单的方式就是采用Cache,又因为是集群范围内的控制,那么集中式Cache就非Memcached莫数了(分布式的Cache传播本身损耗太大,集中式Cache本来的最大缺点就是单点,但作简单的备份操作就可以基本解决此类问题)。 作为解决这个问题的方法来说只需要实现两部分工作:访问计数器,定时任务。定时任务在我做日志分析框架的时候都是采用了Jdk5的Concurrent包里面的ScheduledExecutorService,这个作简单的循环任务足够用了,同时也是有很好的多线程异步支持,复杂一点么用Quartz。计数器就要靠Memcached来实现了,本来一般的Cache最大的问题就是高并发下的事务保证,如果采用Get+Set 来完成计数的话,那么高并发下计数器就会出现读写不一致性的问题,幸好Memcached提供了计数累加功能,让这种累加动作能够在服务端一次做好,服务端控制并发写入,保证数据的一致性。 下面就看看以下几个方法: boolean storeCounter(String key, long count):存储key的计数器,值为count。

STL源码剖析总结_第八章配接器

8 配接器 8.1 配接器之概观与分类 1、设计模式中对配接器的定义如下:将一个class的接口转换为另一个class的接口,使原本因接口不兼容而不能合作的classes可以一起运作。 2、容器配接器(应用于容器) stack和queue是两个容器配接器,底层默认由deque构成。stack封住了所有的deque对外接口,只开放符合stack原则的几个函数;queue封住了所有的deque 对外接口,只开放符合queue原则的几个函数。 3、迭代器配接器(应用于迭代器) 3.1 insert iterators 可以把一般迭代器的复制操作转变为插入操作。 insert iterators包括back_insert_iterator(专门负责尾端插入),front_insert_iterator (专门负责头端插入)和insert_iterator(可以负责任何位置执行插入)。主要观念是,每个insert iterators内部都维护有一个容器;容器有自己的迭代器,当客户端对insert iterators做赋值操作时,就在insert iterators中转为对该容器的迭代器做插入操作,其他的迭代器功能则被关闭。 3.2 reverse iterators reverse iterators将迭代器的行进方向逆转,使原本应该前进的operator++变成了后退操作,原本后退的operator—操作变成了前进操作。当迭代器被逆转,虽然实体位置不变,但逻辑位置必须改变,主要是为了配合迭代器区间的“前闭后开“习惯。

3.3 IOStream iterators IOStream iterators可以将迭代器绑定到某个iostream对象身上。绑定一个istream object(例如:std::cin),称为istream_iterator,拥有输入功能。绑定到ostream object (例如:std::cout),称为ostream_iteratpr,拥有输出功能。内部维护一个istream member,客户端对这个迭代器做的operator++操作,会被导引调用内部所含的那个istream member的输入操作。绑定一个ostream object,就是在ostream iterator内部维护一个ostream member,客户端对这个迭代器做的operator=操作,会被导引调用内部所含的那个ostream member的输出操作。 3.4 运用实例

解析豆瓣的基础架构

豆瓣整个基础架构可以粗略的分为在线和离线两大块。在线的部分和大部分网站类似:前面用,用Nginx做反向代理,形成负载均衡的一层;应用层主要是做运算,将运算结果返回给前面的DAE平台是这两年建起来的,现在大部分豆瓣的应用基本都跑在DAE上面了;应用后面的基

以DPark能够大幅提升性能。另外,因为DPark的编写使用了函数式语言的特点,所以可以写的非常简洁: 到目前(2014年3月),DPark的集群规模和处理数据量已经比去年多了一倍左右,一天要处 理60~100T B左右的数据。 团队 当前,我所负责的豆瓣平台部一共包括四个部分:核心系统,这块也是由我直接带领的,共6名工程师;DAE,现在是彭宇负责,共4名工程师;DBA两人;SA两人。 平台部负责的项目大多是跟业务无关的东西,贴近应用层的主要在产品线团队做,这个分工跟豆瓣工程团队的发展历史有关。早期豆瓣工程师还不多的时候,就已经分为两种倾向,一种是偏业务的,就是去做用户能看得见的东西;另一种是支持性的,运行在业务层下面、不被用户所感知的东西。下面这一层就衍变成了平台部门。 在豆瓣,不管是做产品还是做平台的工程师,技术实力都比较强,一个项目应该从哪个部门发起,并不是看这个任务的难度,而是看它是公共的还是业务特有的。有些项目即使未来可能会成为公共的,但一开始只是一个产品线需要,那么它也会从产品线发起。比如豆瓣的短信服务,最开始是产品线有需求,所以这些服务都是由他们发起完成的,平台这边主要负责提供建设服务的架构,比如DoubanService,告诉他们一个服务怎样去写、怎样去部署、怎样去对用户开放。短信服务后来成为很多产品线都在使用的服务,同时这个系统本身也越来越成熟,那么它逐渐就被转移到SA团队来进行维护。

simple-spring-memcached统一缓存的使用实例

simple-spring-memcached统一缓存的使用 实例 如何在一个中型的Java应用中使用Memcached缓存数据不是个简单的问题。当某个缓存数据需要在多个系统间共享和失效时,必须要有统一的规划才能保证不出错。经过各种实践,目前系统在使用Memcached缓存数据全部采用Simple-Spring-Memcached框架来完成,并统一规划各系统Spring和Cache key的配置。 下面对在使用过程中需要注意的点做一个详细说明: Cache整体规划 目前我们系统中有两个不同的Memcached服务器: 1session memcached服务器:主要存储用户的session 2app memcached服务器: 主要用于缓存应用数据 由于应用所有的缓存数据都放在app缓存上,为避免各应用的缓存数据出现冲突,必须规划好它们的命名空间。所幸Simple-Spring-Memcached支持namespace的概念,因此对各应用的namespace前缀规定如下: 应用namespace前缀 goodscenter goodscenter trade trade uic uic 这个namespace在生成key时,将放在最前面,稍后会有例子详述。 同一个应用中存在许多需要缓存的对象,因此约定namespace前缀之后再加上缓存对象的类名。 例子如下: 应用缓存对象完整的namespace 最终生成的key trade TcRate (id为42) trade:TcRate trade:TcRate:12 goodscenter GoodsDo(id为 42) goodscenter:GoodsDo goodscenter:GoodsDo:1 2 key的生成规则 Simple-Spring-Memcached提供的针对单个对象的注解接口提供了两种key生成方式,详情见此文

完整社交APP需求分析原型设计整体架构前端后端架构

一个社交App需实现的功能 用户关注的常规社交功能、活动、地理位置、探索功能、新鲜事、视频照片分享等等,需要提供的功能不胜枚举,所以从技术角度来说,开发者需要解决的问题也是异常复杂的。 当一款社交App发布之初,用户访问量比较小,使用一台服务器就能够支撑全部的访问压力和数据存储需求,但是互联网应用具有病毒式的传播特点。一款App很可能会面临一夜爆红的现象,访问量和数据量在短时间内呈现爆发式增长,这时候会面临的局面是每天上亿PV、数百万新增用户和活跃用户、流量飙升至每秒数百兆。这些对于一个只部署了简单后端架构的应用来讲是无法支撑的,会直接导致服务器响应缓慢甚至超时,以及在高峰期时服务呈现瘫痪状态,使得后端的服务完全无法使用,用户体验急剧下降。本文将会通过一个真实的案例来分享一个社交应用如何构建一个具备高伸缩性的后端系统。 社交App最初部署的后端架构解析 社交App在最初的时候,后端架构相对比较简单,最初是部署在基础网络之上。最前面放置一台绑定了公网IP的nginx服务器作负载均衡,后面放置3台应用服务器来负责处理所有业务上的请求,最后面搭建一台MySQL Database数据库。 构建私有网络 随着产品的不断迭代、用户数的持续增长、数据量的积累,App就需要改进自己的后端架构,即开始构建私有网络。用户可以使用私有网络构建自己的网络拓扑——创建路由器和私有网络,将后续加入的用于运行内部服务的主机放置在私用网络中,可以有效地和云平台其他用户主机,在网络上实现100%二层隔离。主机对外开放的仅仅只有80端口,这样系统安全性上多了一层保障。

在上面的架构图中,最前面的是防火墙,后面接负载均衡器,然后接路由器和私有网络,很多互联网应用都存在读多写少的情况,这个比例有时可以达到8:2,所以我们首先通过引入缓存分摊数据库读压力。其次,引入负载均衡器,替换最初架构中的nginx proxy,负责均衡器在这里其主要用于分发请求到后端多台应用服务器,,当其中一台应用服务器挂掉,负载均衡器可以进行自动隔离。 业务分区与扩展 App随着并发访问量和数据量不断增大,首先想到横向扩容Web服务。水平扩容业务服务器的前提是要保证每台服务器都是无状态的,将session信息下放到缓存或数据库中存储,保证请求被负载到任何一台服务器可以正常处理。

如何成为一个程序员

如何成为一个程序员:想成为一个游戏程序员需要有以下资料 疯狂代码 https://www.doczj.com/doc/3017404300.html,/ ?: http:/https://www.doczj.com/doc/3017404300.html,/GameDevelopment/Article36086.html 、书籍: 算法和数据结构: 数据结构(C语言版)——严蔚敏、吴伟民 清华出版社 我觉得其配套习题集甚至比原书更有价值每个较难题都值得做下 Introduction to Algorithms第 2版 中文名算法导论 有关算法标准学习教材和工程参考手册在去年CSDN网站WebSite上其翻译版竟然评为年度 2十大技术畅销书同时员杂志上开设了“算法擂台”栏目这些溯源固本举动不由得使人对中国现今浮躁不堪所谓“IT”业又产生了线希望这本厚厚书幸亏打折我才买得起虽然厚达千页但其英文通俗晓畅内容深入浅出可见经典的作往往比般水准书还耐读还能找到MIT视频教程第节课那个老教授嘻皮笑脸后面就是长发助教上课了 C语言名题精选百则 窍门技巧篇——冼镜光 机械工业出版社 作者花费年时间搜集了各种常见C段极具窍门技巧性编程法其内容都是大有来头而且给出了详细参考资料如个普通Fibonacci数就给出了非递归解、快速算法、扩充算法等步步深入直至几无油水可榨对于视速度如生命连个普通浮点数转化为整数都另辟蹊径以减少CPU cycle游戏员怎可不看? 计算机算法基础(第 2版)—— 佘祥宣等 华中科大出版社 我看到几个学校研究生拿它作教材(研究生才开算法太开玩笑了吧)这本书薄是薄了点用作者话来说倒也“精辟

”其实此书是Fundamentals of Computer Algorithms缩写版不过原书出版太久了反正我是没找到 The Art of Computer ProgrammingVolume 1-3 作者Donald E. Knuth是我心目中和冯.诺依曼、Dijkstra、Shannon并列 4位大师这本书作者从读大学本科时开始写直写到博士时十年磨剑足见其下足了功夫可作为计算机技术核心——算法和数据结构终极参考手册创新处也颇多譬如常见Shell排序他在书中提出可用(3i-1)/2间隔这使其稍快于O(n1. 5)当然这套书描述高度数学化为此恐怕般人(我?)最好还得先看本数学预备书Concrete Mathematics(直译为混凝土数学?^-^)再说可惜是这套书才出到第 3卷并没有覆盖全部常见算法内容不过好在对于游戏员来说越常见算法用得越多这也不算是什么要命损失 STL源码剖析—— 侯捷 华中科大出版社 侯捷不用介绍了华人技术作家中旗舰说其有世界级水准也不为过这本书我以为是C和数据结构葵花宝典(欲练此功必先自宫)也就是说不下几层地狱很难看懂它要求预备知识太多了如STL、数据结构、泛型编程、内存管理都要很扎实(为此是不是还要看看有内存管理设计模式的称Small Memory Software这本书呢?)但是旦看懂真会是所向披靡 Data Structures for Game Programmers 每个数据结构例程都是个小游戏还用SDL库实现了个算法演示系统虽然内容失的于浅但起码让人了解了数据结构在游戏中作用 其实游戏并不比其它特殊甚至要求基本功更加扎实所以花时间做些看似和实际应用不甚相干习题对今后工作是大有裨益而且有些应用很广算法如常被人津津乐道[Page]A*算法及其变种牵涉到图检索周游和分枝-限界法恐怕还得读些艰深论文才能充分明白运用如Donald E. KnuthAn analysis of alpha-beta cutoffs其实还有不少此类

PHP大型网站的架构实例分析

PHP大型网站的架构实例分析 Poppen.de是德国的一个社交网站,相对Facebook、Flickr来说是一个很小的网站,但它有一个很好的架构,融合了很多技术,如 Nigix、MySql、CouchDB、Erlang、Memcached、RabbitMQ、PHP、Graphite、Red5以及Tsung. 统计信息 200万注册用户数; 2万并发用户数; 每天20万条私有消息; 每天25万登录次数; 项目团队有11个开发人员,两个设计,两个系统管理员; 商业模式 该网站采用免费增值模式,用户可以免费使用下面任何服务: 搜索其他用户; 给好友发送消息; 上载图片和视频; 寻找好友; 视频聊天; 更多… 但如果用户想享受不受限制发送消息和上载图片,那么就得根据需要支付不同类型的会员服务,视频聊天及网站其他服务也采用同样的策略。 工具箱 Nginx Poppen.de 所有的服务都是基于Nginx服务上的。前端有两台Nginx服务器在高峰期提供每分钟15万次请求的负载,每个机器已经有四年寿命,并且只有一个CPU和3GB RAM.Poppen.de拥有三台独立的图像服务器,由三台Nginx服务器为*.bilder.poppen.de提供每分钟8万次请求服务。

Nginx架构中一个很酷的设计就是有很多请求是由Memcached处理的,因此请求从缓存中获取内容而不需要直接访问PHP机器。比如,用户信息页(user profile)是网站需要密集处理的内容,如果把用户信息页全部缓存到Memcached 上,那么请求直接从Memcached上获取内容。Poppen.de的Memcached每分钟可以处理8000次请求。 架构中有三个Nginx图像服务器提供本地图像缓存,用户上载图像到一个中央文件服务器。当向这三个Nginx之一中请求图像时,如果服务器本地中没有存在该图像,则从中央文件服务器下载到该服务器上作缓存并提供服务。这种负载均衡的分布式图像服务器架构设计可以减轻主要存储设备的负载。 PHP-FPM 该网站运行在PHP-FPM上。共有28台双CPU、6GB内存的PHP机器,每个机器上运行100个PHP-FPM的工作线程。使用启用了APC的PHP5.3.x. PHP5.3可以降低CPU和内存使用率的30%以上。 程序代码是基于Symfony1.2框架之上开发的。一是可以使用外部资源,二是能够提高项目开发进度,同时在一个著名的框架上可以让新开发人员更容易加入到团队中来。虽然没有任何事情都是十全十美的,但可以从Symfony框架中得到很多好处,让团队可以更多的精力放在Poppen.de的业务开发上去。 网站性能优化使用XHProf,这是Facebook开源出来的一个类库。这个框架非常容易个性化和配置,能够可以缓存大部分高代价的服务器计算。 MySQL MySQL是网站主要的RDBMS.网站又几个MySql服务器:一台4CPU、32GB的服务器存储用户相关信息,如基本信息、照片描述信息等。这台机器已经使用了4年,下一步计划会使用共享集群来替换它。目前仍基于这个系统上进行设计,以简化数据访问代码。根据用户ID进行数据分区,因为网站中大部分信息都是以用户为中心的,如照片、视频、消息等。 有三台服务器按主-从-从配置架构提供用户论坛服务。一台从服务器负责网站自定义消息存储,到现在有2.5亿条消息。另外四台机器为主-从配置关系。 另外由4台机器配置成NDB族群专门服务于密集型写操作数据,如用户访问统计信息。 数据表设计尽量避免关联操作,尽可能缓存最多的数据。当然,数据库的结构化规范已经完全被破坏掉了。因此,为了更容易搜索,数据库设计创建了数据挖掘表。 大部分表是MyISAM型表,可以提供快速查找。现在的问题是越来越多的表已经全表锁住了。Poppen.de正考虑往XtraDB存储引擎上迁移。

深入分析STL标准模板·vector

深入分析STL标准模板——vector ——计算机学院--马晶义 摘要:通过阅读c++的STL标准模板库中vector的源代码,分析STL 中的内部成员、接口、内存管理、封装等方面。Vector 是一种顺序性的容器,按照严格线性存储各种对象。它其实就是一种动态的数组,正如数组,vector有他们存储在存储单元相邻元素,这就意味着他们的元素可以被存取不只有使用迭代器还定期使用指针抵消元素。但是不像普通的数组,存储在向量自动处理,允许它的扩展和简约的需要。 关键字:STL、Vcector、内部成员函数、接口函数、封装 一、vector的声明及内部常用函数 1.vector的声明 vector c; 创建一个空的vector vector c1(c2); 创建一个vector c1,并用c2去初始化c1 vector c(n) ; 创建一个含有n个ElemType类型数据的vector; vector c(n,elem); 创建一个含有n个ElemType类型数据的vector,并全部初始化为elem; c.~vector(); 销毁所有数据,释放资源; 2.vector容器中常用的函数。(c为一个容器对象) c.push_back(elem); 在容器最后位置添加一个元素elem

c.pop_back(); 删除容器最后位置处的元素 c.at(index); 返回指定index位置处的元素 c.begin(); 返回指向容器最开始位置数据的指针 c.end(); 返回指向容器最后一个数据单元的指针+1 c.front(); 返回容器最开始单元数据的引用 c.back(); 返回容器最后一个数据的引用 c.max_size(); 返回容器的最大容量 c.size(); 返回当前容器中实际存放元素的个数 c.capacity(); 同c.size() c.resize(); 重新设置vector的容量 c.reserve(); 同c.resize() c.erase(p); 删除指针p指向位置的数据,返回下指向下一个数据位置的指针(迭代器) c.erase(begin,end) 删除begin,end区间的数据,返回指向下一个数 据位置的指针(迭代器) c.clear(); 清除所有数据 c.rbegin(); 将vector反转后的开始指针返回(其实就是原来的end-1) c.rend(); 将vector反转后的结束指针返回(其实就是原来的begin-1) c.empty(); 判断容器是否为空,若为空返回true,否则返回false

memcached代码分析详解

memcached分析详解

目录 1.文档目的 (1) 1.1.前言 (1) 2.memcached是什么 (2) 2.1. memcached的特征 (2) 3.memcached适合的场合 (4) 4.memcached的代码分析 (5) 4.1. main流程 (5) 4.2. memcached服务流程(TCP) (6) 4.3. memcached状态转换和通信协议处理 (7) 4.4. memcached核心数据结构 (7) 4.5. Slab Allocation机制:整理内存以便重复使用 (8) 5.memcached的使用优化 (10) 5.1. 命中率 (10) 5.2. 空间利用率 (11) 5.3. 加速比 (12) 5.4. 安全性能 (12) 6.memcached的测试分析 (13) 6.1. 读写memcache指令测试 (13) 6.2. 服务端系统负载 (13) 6.3. 空间分配,命中率 (14) 7.memcached的中间层客户端编写 (16) 8.libevent简介 (17) 9.memcached应用 (18) 10.结束语 (20)

1. 文档目的 1.1. 前言 文档就是简单的把memcached做一个代码走读和分析,起到一个抛砖引玉的作用; 目的就是让大家在使用memcached这个工具时,多一些对工具的了解,从而确定你的程序是否真的需要用memcached来实现不可; 短短2个小时也讲不了多少,主要是做一个学习探讨,如果大家感兴趣的话后期可以再做培训 牛人真多啊,向先行者致敬!

2. memcached是什么 memcached广泛应用在大负载高并发的网站上,是一种非常成熟的产品(称为一项技术也未尝不可)。像facebook,youtube,yahoo,sina,sohu,netease,豆瓣等网站均或多或少使用了该项产品。memcached在以用户为中心的网站上,表现尤其突出,例如sns,blog等web2.0应用的站点。这些站点一般来讲,特别注重用户体验,用户对服务器的响应速度要求很高,用户数据相对比较复杂、关连度比较高,需要经常对数据库进行更新和检索。 许多Web应用都将数据保存到RDBMS中,应用服务器从中读取数据并在浏览器中显示。但随着数据量的增大、访问的集中,就会出现RDBMS的负担加重、数据库响应恶化、网站显示延迟等重大影响。 这时就该memcached大显身手了。memcached是高性能的分布式内存缓存服务器。一般使用目的是,通过缓存数据库查询结果,减少数据库访问次数,以提高动态Web应用的速度、提高可扩展性。 2.1. memcached的特征 1)memcached的服务器客户端通信并不使用复杂的XML等格式,而使用简单的基于文本行的协议。因此,通过telnet 也能在memcached上保存数据、取得数据。下面是例子。 $ telnet localhost 8119 Trying 127.0.0.1... Connected to localhost.localdomain (127.0.0.1). Escape character is '^]'. set foo 0 0 3 (保存命令) bar (数据)

out......C语言

C++程序设计之四书五经(下篇) 荣耀/文我在上篇中“盘点”了TCPL和D&E以及入门教程、高效和健壮编程、模板和泛型编程等方面共十几本C++好书。冬去春来,让我们继续C++书籍精彩之旅。 标准库 当我还在研究院工作时,与同院另外两家研究所合作开发过一个大型水利枢纽调度集成项目。我们三家软件系统之间都要相互通信。在调试通讯模块时,细心的客户(一名好学的系统管理员)发现对于同一通信规约的解释代码,我的不超过30行,而对方的则超过了150行且很难看懂。这位系统管理员很纳闷,我说大家编程风格和习惯不一样,我使用了标准库,而他使用了传统C编程风格以及他所习惯的另外一些技术。 别误会!我绝无贬低这位合作伙伴的意思。事实上,我对那些真正有着深厚的C编程功力的程序员常常怀有钦佩之心。毕竟,C++能有今天的成功在很大程度上缘于它深深地植根于C。作为一名C++程序员,倘若不熟悉C++中的C,我往往会认为他的基本功是不扎实的,他的技术底气是不足的。 不过话又说回来,C++是一种多范型(paradigm)编程语言,具体采用哪种编程风格,专业程序员应该知道视具体情况而定。作为一名经常需要在现场做即兴开发的项目负责人,为了短平快地解决当务之急,我习惯尽量采用现有的库(和组件)。效率(以及强健性)久经验证的C++标准库已经摆在那儿了,何乐而不用呢? Nicolai M. Josuttis,《The C++ Standard Library: A Tutorial and Reference》原文版、中文版:《C++标准程序库:自修教程与参考手册》 这是一本百科全书式的C++标准库著作,是一本需要一再查阅的参考大全。它在完备性、细致性以及精确性方面都是无与伦比的。本书详细介绍了每一标准库组件的规格和用法,内

memcached完全剖析(1-5)整理

memcached全面剖析 作者:长野雅广(Masahiro Nagano) 作者:前坂徹(Toru Maesaka) 翻译:charlee 整理:yaykey 发表时间:2008/07/02‐2008/07/30 翻译时间:2008/07/10‐2008/07/31 整理时间:2010/11/09

原文链接: http://gihyo.jp/dev/feature/01/memcached/0001 http://gihyo.jp/dev/feature/01/memcached/0002 http://gihyo.jp/dev/feature/01/memcached/0003 http://gihyo.jp/dev/feature/01/memcached/0004 http://gihyo.jp/dev/feature/01/memcached/0005 译文地址: ?第1次:https://www.doczj.com/doc/3017404300.html,/2008/07/10/memcached‐001/ ?第2次:https://www.doczj.com/doc/3017404300.html,/2008/07/11/memcached‐002/ ?第3次:https://www.doczj.com/doc/3017404300.html,/2008/07/16/memcached‐003/ ?第4次:https://www.doczj.com/doc/3017404300.html,/2008/07/24/memcached‐004/ ?第5次:https://www.doczj.com/doc/3017404300.html,/2008/07/31/memcached‐005/ 2 / 81

目录 1. memcached完全剖析–1. memcached的基础 (5) 1.1. memcached是什么? (7) 1.2. memcached的特征 (9) 1.2.1. 协议简单 (9) 1.2.2. 基于libevent的事件处理 (9) 1.2.3. 内置内存存储方式 (10) 1.2.4. memcached不互相通信的分布式 (10) 1.3. 安装memcached (11) 1.3.1. memcached的安装 (11) 1.3.2. memcached的启动 (12) 1.4. 用客户端连接 (13) 1.5. 使用Cache::Memcached (15) 1.5.1. 使用Cache::Memcached连接memcached (16) 1.5.2. 保存数据 (17) 1.5.3. 获取数据 (17) 1.5.4. 删除数据 (17) 1.5.5. 增一和减一操作 (18) 1.6. 总结 (19) 2. memcached全面剖析–2.理解memcached的内存存储 (21) 2.1. Slab Allocation机制:整理内存以便重复使用 (23) 2.1.1. Slab Allocation的主要术语 (24) 2.1.1.1. Page (24) 2.1.1.2. Chunk (24) 2.1.1.3. Slab Class (24) 2.2. 在Slab中缓存记录的原理 (25) 2.3. Slab Allocator的缺点 (27) 2.4. 使用Growth Factor进行调优 (29) 2.5. 查看memcached的内部状态 (31) 2.6. 查看slabs的使用状况 (33) 2.7. 内存存储的总结 (35) 3. memcached全面剖析–3.memcached的删除机制和发展方向 (37) 3.1. memcached在数据删除方面有效利用资源 (39) 3.1.1. 数据不会真正从memcached中消失 (39) 3.1.2. Lazy Expiration (39) 3.2. LRU:从缓存中有效删除数据的原理 (41) 3.3. memcached的最新发展方向 (43) 3.3.1. 关于二进制协议 (43) 3.3.2. 二进制协议的格式 (43) 3.3.3. HEADER中引人注目的地方 (45) 3.4. 外部引擎支持 (47) 3 / 81

redis缓存技术学习

1 什么是redis redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)和zset(有序集合)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。 2 性能怎么样 Redis是一个高性能的key-value内存数据库。官方性能测试结果: set操作每秒110000次,get操作每秒81000次。 3 可不可以存对象 和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)和zset(有序集合)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作。 4 Redis与memcache的最大区别 Replication(树形) data types(String、Lists、Sorted Sets、Hashes) persistence (snapshot、aof) 很多开发者都认为Redis不可能比Memcached快,Memcached完全基于内存,而Redis 具有持久化保存特性,即使是异步的,Redis也不可能比Memcached快。但是测试结果基本是Redis占绝对优势。一直在思考这个原因,目前想到的原因有这几方面。 Libevent。和Memcached不同,Redis并没有选择libevent。Libevent为了迎合通用性造成代码庞大(目前Redis代码还不到libevent的1/3)及牺牲了在特定平台的不少性能。Redis 用libevent中两个文件修改实现了自己的epoll event loop(4)。业界不少开发者也建议Redis

相关主题
文本预览
相关文档 最新文档