[缓存] 开源项目 ThumbCached

转载:http://www.cnblogs.com/domslab/archive/2009/06/29/1513564.html
http://www.cnblogs.com/domslab/archive/2009/06/29/1513514.html
版本:1.1.0
协议:New BSD license
平台:.Net 2.0/Mono 2.0
系统:Windows/Linux/BSD
ThumbCached 是一个简单高效的用于小数据的分布式缓存及储存系统(用于开发Web网站)。适用于缓存及储存数量庞大、个体容量小、读取频繁、需要持久化、非关键性的数 据,例如网站中的缩略图、用户自定义头像、已格式化的页面文本等。ThumbCached 还可以内存缓存模式运行,作用相当于Memcached,在速度上可以达到 Memcached 的70%左右。在 1.1 版本中新增加了嵌入的运行方式,适用于以非服务的形式嵌入到一个Web应用程序。
功能特点:
* 使用一个文件来储存数据,可以避免过多的细小文件所造成磁盘空间浪费,同时方便数据的转移和备份。
* 服务程序和应用程序可以分布于不同的服务器,适用于分布式的网站。
* 数据的传输使用标准HTTP协议,方便多种程序语言(如ASP.NET,PHP等)访问。
* 能在一个服务实例中同时创建多个储存单元,以便于将不同类型的数据分开储存。

* 服务端使用高效的异步Socket技术。

下载地址:thumbcached.codeplex.com

 

Thumbcached 的程序结构图如下:

 

ThumbCached由HTTP Service、Cache item manager(上图中的 Buffer Pool)和StoreManager三部分组成,各部分的功能如下:
HTTP Service:接受及回答客户端的请求,传输数据;
Cache item manager:使用.Net的内存管理机制实现的缓冲,将被访问的cache项(以下称为“block”)缓存并加以管理,通过队列的方式将新增加或被更新的block项交给StoreManger;
StoreManager:持久化(储存)所有block的信息和二进制数据内容。

这样的设计能让读、写、更新数据的速度都比较快,因为常用的和新增加的缓存项都是放在pool里面的,而Store queue使用队列的方式将新增加的缓存项在后台持久化到文件。不过也是因为使用队列的原因,可能会导致pool的数据被删除而磁盘上的数据仍然存在的情 况,所以删除数据时是等待磁盘上的数据也删除完毕之后才返回的,因此删除操作比较慢。幸好在实际应用中很少删除操作。

在持久化(即储存)部分,使用了两个文件来配合实现,一个文件存block的信息,另外一个文件存block的数据。
block信息使用SQLite储存并对block的key作索引,这样查找block信息时速度很快,数据表设计如下:

 

第二个文件用于储存block数据,因为block数据是不定长的,所以第二个文件使用了自定义的数据结构,考虑到更新block数据时如果采用直 接丢弃旧的数据再新建一条记录这种方式会导致文件空间浪费,所以block数据的记录采用了覆盖旧记录加“链记录”的方式来实现。即每个记录都可以允许链 N块数据区域,这样能够最大限度地减少文件空间的浪费。下面是第二个文件的结构图:

 

储存数据之后,文件的内容会变成下图这样:

 

ThumbCached 使用HTTP协议跟应用程序通信,下面是协议的定义 :

 

添加缓存项:
—————————————————-
Request:
    POST /update/ITEM_KEY?expire=EXPIRATION_SECOND&abs=EXPIRATION_TYPE HTTP/1.1
    Host: HOSTNAME:PORT
    Content-Length: INTEGER
    Content-Type: THUMBCACHED_DATA_TYPE_NAME
    Last-Modified: GMT_DATE_TIME
    [\r\n]
    [BINARY_DATA]
    
ITEM_KEY: a string to name an item
EXPIRATION_SECOND: an integer number to specify the item expiration time (take effective in non-persistance mode only)
EXPIRATION_TYPE: a number '0' or '1', if it equal to '1' that means absolute expire.
THUMBCACHED_DATA_TYPE_NAME: combine with 'tcd/' and an integer number,
                enum DataTypeNumber
                {
                    Binary =0,
                    Object =1,
                    Boolean =3,
                    Int32 =9,
                    Int64 =11,
                    Single = 13,
                    Double = 14,
                    DateTime = 16,
                    String = 18,
                    EmptyByteArray = 256 + 6,
                    EmptyString = 256 + 18
                }
GMT_DATE_TIME: specify the item time, take effecive in persistance mode.
Response:
    HTTP/1.1 200 OK
    Content-Length: 0
    
获取一个缓存项:
—————————————————-
Request:
    GET /fetch/ITEM_KEY HTTP/1.1
    If-Modified_Since: GMT_DATE_TIME
    
GMT_DATE_TIME: specify one time to test the item last modified time, if the item
    does not modified since GMT_DATE_TIME, this request will return 304-Not Modified http status code.
Response:
    HTTP/1.1 200 OK
    Content-Type: THUMBCACHED_DATA_TYPE_NAME
    Content-Length: INTEGER
    Last-Modified: GMT_DATE_TIME
    [\r\n]
    [BINARY_DATA]
如果指定的key不存在相应的缓存项,则返回404 http代码。

一次获取多个缓存项:
—————————————————-
Request:
    GET /multifetch/?keys=KEY1,KEY2,KEY3… HTTP/1.1
Response:
    HTTP/1.1 200 OK
    Content-Length: INTEGER
    [\r\n]
    KEY1
    THUMBCACHED_DATA_TYPE_NAME
    GMT_DATE_TIME
    DATA_LENGTH
    [BINARY_DATA]
    [\r\n]
    KEY2
    THUMBCACHED_DATA_TYPE_NAME
    GMT_DATE_TIME
    DATA_LENGTH
    [BINARY_DATA]
    [\r\n]
    KEY3
    ……
    
如果指定的key当中有其中的一个或多个没有对应的缓存项,则不返回改key的数据。
删除一个缓存项:
—————————————————-
Request:
    GET /remove/ITEM_KEY HTTP/1.1
    
Response:
    HTTP/1.1 200 OK
    
获取服务器状态:
—————————————————-
Request:
    GET /status    HTTP/1.1
    
Response:
    HTTP/1.1 200 OK
    Content-Type: text/plain
    Content-Length: INTEGER
    [\r\n]
    Pool memory: INTEGER
    Used memory: INTEGER
    Item amount: INTEGER
    Item hits: INTEGER

赞(0) 打赏
分享到: 更多 (0)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏