Kiji - 基于Apache HBase构建实时的可扩展的数据应用
什么是 kiji :
个人总体感觉就是构建在hadoop/hbase上的一层Wrapper,使用Avro存储系列化的对象在HBase表中,基本上目的是让应用程序的编写者能更容易的用Hbase管理结构化的数据,而不是作为一个扁平的表使用。抛开Hadoop和HBase,其最核心的部分就是所谓的Kiji-Schema,基本上就是用Avro处理Schema,以及读写系列化数据。
kiji基本概念和与HBase的映射关系
kiji对HBase没有做什么改动,也没有使用Coprocessor之类对HBase的功能进行拓展增强,所以基本上就是架构在HBase的公共API上,借用HBase既有的能力实现所需的功能,这一点和Hive On Hbase 有些类似。与Hive不同的是,kiji表的Metadata信息也是以HBase表的形式存在的。所以kiji的概念基本上都可以最终落实映射到HBase上
Entity:个人理解因为kiji的出发点是企图强化对象概念,所以HBase表中Row的概念被弱化,每个对象都用一个Entity来表示,对象的所有信息都存储在一个Entity内部。实际上,Entityid对应于HBase的实现就是Row key。不过在存储的时候,Entity ID可以以Hash或裸数据或混合的形式存储。
Cell:kiji中的数据单位划分是Cell,是由 locality:family:key加上Timestamp来定位的,和HBase的Cell是同一个层次,但是为什么在定位中比HBase多了一层呢,实际上locality对应的是HBase的Family的概念,就是用来做同类数据的物理分组用途(改个名字难道是怕别人不理解HBase划分Family的用意?)。而kiji中的family只是一个逻辑数据划分的概念,并不对应HBase中的具体某个概念,可以理解为仅仅是把HBase的qualifier在命名的逻辑上分为两部分而已。
Layout:此外Kiji中还有Table Layout的概念,基本就是用来描述表的结构,Layout并没有存储在HTable的TableDescriptor中,而是在自己管理的meta表中存储,在HBase上表现为一个普通的HBaseTable(e.g. kiji.default.meta)
Schema:Kiji CellSchema对应的就是Avro的Schema,用来将扁平的HBase表格数据对象化。因为kiji的核心之一就是Schema,所以在Cell Schema方面还是做了一些功夫的,Cell的内容可以是裸的AvroRecord,Schema完全由MetaTable决定,也可以把Cell Schema和Avro Record合并存储。而存储的Schema为了节省空间,可以是Schema的Hash,也可以是Schema的ID。对应的Full Schema的映射关系存储在单独的表中(e.g. kiji.default.schema_hash kiji.default.schema_id)
Mapping of Kiji conception to Hbase summary:
Items | Kiji | HBase |
Entity related | Entity | All KeyValues belong to the same row |
| EntityID | Row key |
Column related | locality:family:key | Family:qualifier |
| locality | Family |
| Family:key | Qualifier |
Schema related | Table Layout | KijiMetaTable on Hbase. e.g. kiji.default.meta |
| Cell Schema | Avro Schema saved together with Avro serialized data in KV |
| Cell Schema mapping | Schema Table on Hbase e.g. kiji.default.schema_hash, keji.default.schema_id |
Table读写操作相关
kiji的基本操作包括KijiTable的创建修改,以及Entity数据的读写。其操作的流程步骤和HBase的比较相似,也有许多对应的概念对象如Configuration/Admin/Table等,个人理解是因为kiji对数据模型并没有本质的变革,只是封装了一层wrapper操作,所以不可能也不需要在操作流程上有太大的差异。
Entity读写
数据的读写以Entity为导向,实际上可以理解为就是以Row为导向。同样需要添加所操作的Family/column等。个人理解概念上的差异就是在对Entity的操作上时,Entity的所有完整内容都在一个对象内部,更接近面向对象的编程概念,也就是帮应用程序的作者做了一些封装的工作,简化开发者的工作量
Filter操作
Kiji提供了Row/column/value相关的几个Filter,这个可以说是Feature,也可以说是为了方便应用开发者的无奈之举,因为row/column都可能以Hash的形式存在,而cellvalue则是Avro编码过的,此外还可能附加有Schema,所以HBase相关的Filter无法简单的应用在Kiji table中工作。因此这些kiji Filter基本都是对HBase相关Filter的封装,对应的都会有一个toHBaseFilter方法,用来在服务器端创建对应的HBaseFilter。
其它
Layout evolving
Kiji的重点既然是在Schema和Layout,在Layout的动态调整中也花了不少功夫,比如Layout,就分为Concrete layout descriptors和Layout update descriptors。前者是作为基础,后者作为修改量用来修正基础Layout。这样做的目的号称是为了减少Layout更新过程的Racecondition。没有深入研究其Evolving的细节,有需要时再研究。
对官方Feature的理解
Kiji官方描述了Kiji的一些Feature和精妙之处,结合文档和API阅读,个人理解如下:
- Set-up HBase layouts using user-friendly tools including a DDL
kiji提供了schemashell工具帮助创建Kiji Table,支持DDL和JSON格式的输入
- Implement HBase best practices in table management :
所谓最佳实践,个人理解如下:
- Build in Row ID的Hash支持,这个通常是用来均衡负载HotSpot的
- Column name is shortened. Kiji中Family和 Column的名字是在Layout中保存的,而存储在Hbase Table中的都是映射过后的短名字,如 B:B:B,这可以减小数据量,HBase中也可以这么做,不过用户要么接受无意义的短名字,要么就需要自己构建映射关系。
- 强化Family的物理分区概念
其它还真没看出有哪些最佳实践
- Use evolving Avro schema management to serialize complex data
动态Schema和Avro序列化对象,这个是Kiji的出发点了
- Perform both short-request and batch processing on data in Hbase
这个没有什么特殊的,个人理解就是支持Hbase client的Get Scan等操作,同时也提供了KijiTableInputFormat,KijiTableOutputFormat这样的类来支持MapReduce操作,此外号称对HBase本身的HTableInputFormat,HTableOutputFormat类作了Bug Fix
- Import data from HDFS into structured HBase tables
结构化对象化,老生重谈
Why Kiji at all
总体感觉Kiji的Design Goal如其所言,provides a simple Java API for storing and managing typed data inHBase using Avro serialization。 基本上就是对HBase应用模式的一个封装,用Avro来承载对象化的数据,方便Schema的演化。从数据的角度加强面向对象编程的概念(相对Hbase Table)。面对的是希望能使用HBase存储数据,快速上手开发应用的用户。在性能或结构上没有本质的革新。可以做为一种HBase应用模式的参考,是否适用,应该还要看最终程序的需求。