ThumbCached是自己项目中的一个小组件,本着共享交流相互学习的想法,现将它开源出来,希望各位大虾多多指教。这里先贴贴一篇文档,以后再贴组件的应用实例和原理。
ThumbCached
分布式细小二进制文件数据高速缓存及储存系统 (中文名:拇指缓存)
Version: 1.0.1
简介ThumbCached 是一个简单高效的用于小文件数据的分布式缓存及储存系统,系统适用于缓存及储存数量庞大、个体容量小、读取频繁、需要持久化、非关键性的二进制文件数据,例如网站大量图片的缩略图、用户的自定义头像等。
功能特点
- 使用两个大文件来储存大量细小文件的数据,可以节约过多的细小文件所浪费的磁盘空间,同时方便数据的转移和备份。
- 服务程序和应用程序可以分布于不同的服务器,并且多个应用程序可以同时访问同一个服务。
- 内置数据缓存机制,能提高热点数据的访问速度。
- 数据的传输使用标准HTTP协议,方便多种程序语言(如ASP.Net,PHP等)使用现有的组件访问服务端。
- 使用一个key来访问一个文件的信息和数据,不需记住文件的路径和文件名,能简化应用程序的编写。
- 能在一个服务中同时开启多个储存单元,以便于将不同类型的数据(如用户自定义头像和图片缩略图)分开储存。
- 服务端使用高效的异步Socket技术。
通信协议ThumbCached使用标准的HTTP协议与应用程序通信,主要的操作有:添加或更新、获取和删除。操作的对象是block(一个block包含有key、最后修改时间、二进制数据内容)。Block的key是一个由字母和数字组成的字符串,例如“item001”,“23A8F001C”。
1、添加或更新block使用HTTP POST方法,URL格式为:“/key”。
POST方法需要附上block的二进制内容。如果两次POST的Key一样,则会更新这个Key原先的内容。如果需要指定block的时间,可以在URL后附加指定时间,如“/key?20080815123000”,时间格式为“yyyyMMddHHmmss”。方法成功之后,服务端返回HTTP 200 OK状态码和空白内容。
2、获取block使用HTTP GET方法,URL格式为:“/key”。
如果方法成功,服务端返回指定block的内容,并且在HTTP response header的“Last-Modified”字段中返回该block的最后修改时间。如果指定的block不存在,服务端会返回HTTP 404 NotFound状态码和空白内容。
在获取block时还可以同时指定一个时间值,如“/key?20080815123000”,当block的最后修改时间比指定的时间要新的时候,服务端返回block的内容,否则返回HTTP 304 NotModified状态码和空白内容,并且在HTTP response header的“Last-Modified”字段中返回该block实际上的最后修改时间。使用这个方法可以减少不必要的数据传输量。
3、删除block使用HTTP GET方法,URL格式为:“/key/remove”.
方法返回HTTP 200 OK状态码和空白内容。
服务端的安装和使用
ThumbCached可以以控制台或者Windows服务的形式运行。先下载ThumbCached的源代码(需要用vs2008编译)或已编译版本,运行“ThumbCached.exe”即可以控制台的形式启动程序。若希望以Windows服务形式运行,则运行“InstallService.bat”批处理进行安装,要卸载此项服务,请运行“UninstallService.bat”。
服务端通过“ThumbCached.exe.config(控制台)”或“ThumbCachedService.exe.config(Windows服务)”进行配置,当配置内容更改后,需要重启服务才能让新配置生效。
示例的配置文件内容如下:
<thumbCached>
<cache>
<node id="tcd001">
<storeFile infoFilename="d:\tcd_avatar.db" dataFilename="d:\tcd_avatar.dat" />
<blockPool bufferPoolSize="128" activeTime="300" />
</node>
<node id="tcd002">
<storeFile infoFilename="d:\tcd_icon.db" dataFilename="d:\tcd_icon.dat" />
<blockPool bufferPoolSize="128" activeTime="300" />
</node>
<node id="tcd003">
<storeFile infoFilename="d:\tcd_thumbnail.db" dataFilename="d:\tcd_thumbnail.dat" />
<blockPool bufferPoolSize="128" activeTime="300" />
</node>
</cache>
</thumbCached>
<nbaseHttpd>
<binds>
<endpoint address="*" port="18500" nodeId="tcd001" />
<endpoint address="*" port="18501" nodeId="tcd002" />
<endpoint address="*" port="18502" nodeId="tcd003" />
</binds>
<connection keepAlive="true" timeout="180" connectionsLimit="5000"/>
</nbaseHttpd>

图1
这个示例共创建了3个储存单元。
<thumbCached>段定义储存单元,主要的属性及作用如下:
- infoFilename和dataFilename:数据文件的路径和文件名,需要注意的是FAT32格式的磁盘分区对单个文件的最大容量只支持到4GB,所以最好把数据文件存放在NTFS的分区;
- bufferPoolSize:block缓冲池的大小,默认是128MB,根据实际应用情况来设定此属性;
- activeTime:block缓冲项的最大活动时间,默认是300秒,当一个block缓冲项超过这个时间都没有被访问过时,它就会从缓冲池中被清除;
- id:每个储存单元需要定义一个不重复的id,用于跟下面的网络监听节点绑定。
<nbaseHttpd>段定义服务的网络监听节点,主要的属性及作用如下:
- address和port:监听的IP地址和端口,如果想监听某个端口的所有IP地址(假如服务器有多张网卡或多个IP的话),可以使用星号(*)代表所有IP地址;
- nodeId:跟上面的储存单元对应的id;
- keepAlive:设置服务端与客户端之间的网络连接是否保持长连接,默认值是true;
- timeout:保持长连接的最大时间长度,默认是180秒;
- connectionsLimit:服务端最大允许的同时连接数量。
使用客户端组件—TCClientTCClient是ThumbCached客户端的C#的一个实现,可以用于ASP.Net或其他基于.Net框架的应用程序。
1、主要的方法及作用组件主要包含了 ThumbBlock 和 TCClient 两个类。
ThumbBlock :block对应的实体类,含有三个属性:
- public string Key:block的key
- public DateTime LastModifyTime:block的最后修改时间
- public byte[] Data:block的二进制内容
TCClient:有如下几个方法:
- public void Add(string key, byte[] data)
添加或更新一个block
- public void Add(string key, byte[] data, DateTime lastModifyTime)
添加或更新一个block,并指定block的最后修改时间
- public ThumbBlock Get(string key)
获取指定的block
- public ThumbBlock Get(string serverid, string key, DateTime ifModifySince)
根据key和指定时间来获取一个block
- public void Remove(string key)
删除指定的block
2、客户端配置文件使用客户端组件之前,需要在应用程序的配置文件(web.config或app.config)中添加如下示例的段落:
<configSections>
<section name="tcclient" type="Doms.TCClient.Configuration.TCClientConfigSection, TCClient, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</configSections>
<tcclient>
<serverNodes defaultServer="icon01">
<server id="icon01" address="127.0.0.1" port="18500" />
<server id="icon02" address="127.0.0.1" port="18501" />
<server id="icon03" address="127.0.0.1" port="18502" />
</serverNodes>
</tcclient>
图 2
这个示例演示了一个TCClient同时连接3个ThumbCached储存单元。需要注意的是 <configSections> 标签在原配置文件可能已经存在,不要重复添加。<tcclient>段主要的属性及作用如下:
- address和port:储存单元的网络服务IP地址和端口。
- id:为任意的一个字段串,用于代表一个储存单元的网络节点,在程序中将会使用这个id来决定程序访问的储存单元。
3、使用示例首先需要将TCClient.Dll添加至应用程序的引用,如果你获取的是TCClient的源代码,必须先用vs2008将源代码编译成TCClient.Dll。
下面的代码演示了使用TCClient向ThumbCached添加、获取和删除一个block。
private static void Test()


{
TCClient client = new TCClient("icon02");
//add block

byte[] data = new byte[]
{ 1, 2, 3, 4, 5 };
DateTime time = DateTime.Now;
client.Add("item001", data, time);
try

{
//get block
ThumbBlock block = client.Get("item001", time.AddDays(1));
Console.WriteLine("block content length:{0}", block.Data.Length);
}
catch (BlockNotFoundException)

{
Console.WriteLine("block not found");
}
catch (BlockNotModifyException ex)

{
Console.WriteLine("block actually last modified time is: {0}", ex.LastModifyTime);
Console.WriteLine("block content does not modify since: {0}", time.AddDays(1));
}
//remove block
client.Remove("item001");
}

速度测试 下面使用单一线程的客户端测试ThumbCached每秒钟能完成的请求次数。
需要说明的是:这里的测试数据是不严谨且不完全的,实际的性能会因为不同的运行环境而有所不同,所以这里的数据仅供参考。测试的硬件配置如下:
CPU:Athlon64 X2 4200+
RAM:2G DDR2
网络:100M base
测试使用大小为
10KB 的数据作为每次请求的block,共做了如下6种请求:
1、 添加block
2、 更新block
3、 删除block
4、 读取block
5、 在关闭服务端缓存的情况下添加block,模拟缓存用完的情况
6、 在关闭服务端缓存的情况下读取block,模拟缓存用完的情况
首先在运行ThumbCached程序的本机上测试(即不通过实际网络传输数据),测试结果如下:

图 4
说明:纵坐标的数值是每秒完成的请求次数。
然后测试程序通过网络连接ThumbCached服务程序,测试结果如下:

图 5
网上资源及意见反馈
ThumbCached及TCClient可以在 http://sourceforge.net/projects/thumbcached 上找到最新的源代码和文档。如果有问题想要讨论,或者有任何意见、建议或者发现bugs,可以访问位于google的讨论组: http://groups.google.com/group/thumbcached
后记:最近在国内访问不了sourceforge.net,所以可以到这里:http://www.domstorage.com/DownloadPage.ashx 下载服务端和客户端的源代码和已编译版本以及文档。