产品概述产品介绍Egg是一个高性能、可扩展、并支持分布式存贮的非结构化数据库,同时也具备了部分非关系型数据库具备的结构化查询功能。
该类型的数据库被广泛应用于搜索引擎、海量信息检索系统、音频视频管理系统等领域,成为这些领域中必不可少的一个组成部分。
Egg是一个完全由C编写的,成熟的软件,并且是埃帕Cooling搜索引擎软件、Cooling云桌面平台软件、Cooling云输入法的重要组成部分,已经运用到了互联网、信息检索、数据挖掘、虚拟化等多个领域中。
行业背景随着互联网的不断发展,搜索、云计算、WEB 2.0等全新的应用模式不断涌现出来。
这些新应用都有着一些非常显著的特点,如:信息量巨大、信息结构化程度低、信息更新频度高、信息增长幅度大,并发访问频繁等。
传统的关系型数据库,虽然能够胜任企业级别的信息管理,但在处理互联网级别的应用时,往往无法满足于以上的特点,暴露出了很多问题。
海量数据的高效存贮与访问要求海量数据应用中最早,最典型的应用是搜索引擎;最有发展的是云计算;最流行的是WEB2.0中的SNS社区。
据CNNIC统计,截止2009年底,仅中国的网页数量就达到了336亿,较之2008年底,增长幅度接近100%。
搜索引擎不光要存贮这些网页的基本信息,同时又要解决平均每天几千万网页的增长量。
云计算、需要将原先用户端的应用、服务、数据移到服务端,利用服务端的计算、存贮、带宽、管理优势,提供相比传统桌面应用更有竞争力的服务方式。
WEB 2.0中最主流的SNS社区,每天都要产生大量的用户动态信息,以Facebook为例,每月用户动态记录就达到2.5亿条;另如一些Web 门户,都已经达到上亿帐户数量。
所有的此类应用中的存贮要求,都已经超过了关系型数据库可以容纳的范围。
Google是最早采用了廉价硬件(Commodity Hardware)建立分布式存贮的互联网公司;Amazon则在云计算平台中,采用了Yahoo与apache合作开发的分布式文件系统Hadoop;Facebook则为业界贡献了Cassandra,这一分布式的非关系型数据库。
高可用与可扩展性的要求关系型数据库具备一定的高可用性与可扩展性,但这是建立在企业级可预测数据的前提之下的。
而对互联网应用来说,没有任何人能预测下一年新增的网页数量、云计算平台的使用人数以及社区将拥有的用户数。
唯一可以肯定的就是,所有这些数据都会以一个相当快的速度增长。
当一种存贮方式,无法满足面对应用的增长而动态扩展,将对互联网业务的发展,产生严重的负面影响。
此外,互联网应用要求所有系统都要能够全天侯提供服务,即便系统升级、增加设备、出现故障。
而传统关系型数据库的扩展、维护都需要停止数据库实例,而无法实现实时维护,这也导致了传统的存贮方式,无法满足目前互联网发展的需求。
高并发访问的要求搜索引擎、云计算、WEB 2.0每天都要面对大量的用户访问。
2010年,Google与Facebook的访问量,占据了全美访问量的14%。
在如此大的并发下,存贮或数据库的负载将非常之高,将达到每秒上万次读写请求。
在如此大的读写压力之下,既便使用了Raid之类的技术,硬盘IO也已经无法承受,或是在有限的时间内完成读写操作。
非结构数据存贮的要求关系型数据库从设计准则上来看,是对具备明确结构信息的数据进行管理。
但目前、无论是在互联网应用,或是企业应用中,非结构化数据(网页、Office文档、文本、PDF、甚至音视频)都占据了总信息量的85%以上。
这些数据虽然能用关系型数据库进行存贮,但却无法进行有效的检索。
因为为些数据种类繁多,且都无法用结构化的方案(Schema)来描述。
在以上四个要求前,关系型数据库显得无能为力,但这并不是说关系型数据库就是一个失败的产品。
只能说,关系型数据库不适合不断扩展的海量数据应用。
关系型数据库本身具备强大的事务完整性控制实时读写能力结构化查询能力但是这些功能,在很多应用中并非必要、或者说可以通过其它的方式代替。
对于事务完整性,很多互联网应用都是强调用户交互性,操作往往很简单,或者说在设计之初,就尽可能的避免会造成复杂事务的设计。
而实时读写、搜索引擎虽然不断抓取数据,但供用户访问的索引,往往一天才更新一次,但这样的频度对用户来说已经足够。
结构化查询能力,最典型的特点是能够支持多表的关联操作,但实际上在设计超大规模系统的时候,即便使用关系型数据库,设计师也知道单表的设计虽然在结构上不优美,但确能提供最高的效率。
目前开始流行的非结构化、非关系型数据库的发展方向,就在于解决前4个需求,同时弱化并非主要的关系型数据的3个特点。
产品方案总体架构Egg从结构上可以分布两层,上层为数据存贮层,下层为分布式文件系统。
ClientIndexCacheSearchCacheIndex.MapId.MapPos.MapField.MapDoc.MapAnalysisSimilarityMaster NodeRack1Slave NodeBlockBlockBlockBlock Slave NodeBlockBlockBlockBlockRack1 Slave NodeBlockBlockBlockBlockSlave NodeBlockBlockBlockBlock数据存贮层Egg存储主要分为三层,分别是Cache缓存层,Mapping映射层以及文件存储层。
Cache缓存层Cache缓存层,是一个基于HashTable访问存储层。
每一块缓存数据都由一个关键字符串key标识,并可通过此关键字符串key访问到相对应的缓存数据。
它主要有两个特点:一、在索引过程中,可以减少系统I/O写频次,单元数据也便于集中存储入文件中;此外,对于多进程写数据,可以统一录入,减少文件锁频繁操作;为了避免过多使用系统内存,Cache缓存层可设置内存占用的上限。
二、在反向索引过程中,可以减少系统I/O读频次。
SearchCache中有个叫缓存命中的机制,提高检索效率,减缓系统I/O压力。
Mapping映射层Mapping映射层,是一个基于文件映射的存储层,与磁盘中的文件形成一对一的联系。
这一层中包含了:索引区(Index.Map)、文章区(Doc.Map)、字段区(Field.Map)、位信息区(Pos.Map)、ID区(Id.Map),它们分别对应着五个文件。
文件映射采取的是块读写,并对文件区域进行“格式化”划分,便于快速映射定位以及校验非法操作。
分词器接口Egg对外提供分词器的统一接口,无论是空格分词器、英文分词器,还是中文分词器,甚至更复杂的分词器,都可以为Egg挂载调用。
为了更为有效的存储入文件,Egg分词接口要求序列化分词结果,各个分词器应遵循接口规则,实现序列化方法。
相关度评分策略若检索是索引的反向操作,那么相关度评分则是分词的反向操作。
在分词过程中,记录每个被分词器划分出来的关键字的位置信息,关键字之间位置近远和耦合度直接影响到相关度评分。
若想获得较为精确的相关度分数,势必要将所有的位置信息一个不差的存储入文件中,这对文件的空间访问压力会很大;相反的,若想节省文件存储空间,相关度分数不能较为准确的反映用户所需要的查询结果。
Egg除了采用可变长整形类型VInt(VInt类型在文件存储上可以比Int类型至少减少3-4倍的空间),还有自己的评分策略。
从实际角度出发,通常某篇文章它的重点和概括性的语句都会出现在文章的前部,那么Egg分词器针对这个特点只需要记录中文章前部重要的信息。
换而言之,Egg不会记录全部的位置信息数据,但记录的数据肯定是最重要最有价值的。
此外,Egg通过用户查询数据的不断积累,形成了一套用户查询频次较多的关键字列表,在分词过程中针对频次较多的关键字,获得的不单单只是文章前部的信息,甚至是整篇大文章的信息,这样更利于评分的准确度,便于更好的反映查询结果。
索引方式策略Egg索引采用的是B-Tree结构,并且支持变长关键字符串读写访问。
B-Tree相对于其他存储结构的优势在于快速有效检索以及实时数据更新,它并不像HashTable每次数据新增或者更新需要重新建表。
索引树上的每个结点都是固定大小(32Bytes),用于存储关键字。
若访问的关键字超出了结点大小,此关键字被存放在其他数据块中而不是树结点上,而树结点中存放是此关键字的偏移地址。
基于数据采样的特性和实际情况,树结点的固定大小是可以设置变化的。
例如:关键字都是单字或者英文单词,那么固定大小可以设置偏小一点。
文件数据块存储策略Egg在文件中存放数据时,会事先扩展比被存储的数据大小更大的容量。
一般来说,Egg会将文件扩大32M-64M。
这样做完全是为了能让Mapping映射操作更为快速有效,因为频繁的文件I/O读写是Mapping不利的。
一次性扩大大空间也会减缓I/O访问的频繁度。
为了便于维护管理,Egg对此扩展空间进行“格式化”,类似于malloc/free内存管理和资源回收。
“格式化”中记录已用空间、未使用空间。
每次有新数据要录入时,空间会检查剩余空间是否满足新数据的要求,若空间不足则会请求文件扩展磁盘空间。
Egg的分布式文件系统Egg的分布式文件系统,称为Cooling File System(简称CFS)是一个典型的Master/Slave架构。
CFS系统的集群,包含一台主节点(Master Node)与多个子节点(Slave Node)。
主节点负责管理整个文件系统中的所有子节点,并提供对客户端提供文件读写的服务。
所有的子节点都管理一片独立的存贮空间,实现最终的读写操作。
CFS在存贮一个文件时,会将文件分成若干固定大小的块,这些块将被分配到不同的子节点,由子节点来最终保存这些块。
主节点记录存贮在文件系统中的文件,并为每一个文件块分配一个唯一的id号做为标识。
子节点接受主节点发来的命令,实现对文件块的读、写、复制等操作。
CFS主节点对客户端来说,就象是一个文件系统,并通过类似POSIX IO的API去管理这些数据。
支持的操作有:open, close, read, write, pread, pwrite, seek, rename, remove。
CFS是一套独立的软件,使用GNU GCC编译器编译,遵循POSIX规范,能够运行于各类Linux操作系统之上,具备良好的迁移性。
文件系统结构CFS在Egg中的目的,主要是为了服务于上层的存贮结构,因此CFS 中存贮的文件都会非常巨大,至少是G级别,同时不会有非常复杂的目录层次要求。
因此CFS中只有文件,而没有目录的概念,同时也不支持链接。
在将来的Roadmap中,这些功能也不会被加入进来。
主节点维护整个文件系统,所有的文件操作,以及基本配置信息都位于主节点上。