Overview
话说之前挖了一套Naive-Qie的坑,然而Naive-PageDB
的坑还没填好呢,我就在脑海里重构了一遍。主要问题在于系统用于生产环境时,随着数据量的增长,就必然会面临单机服务能力有限的问题,虽然数据拆分倒是不难,但是有现成的轮子,自己造一套未免太麻烦。最近正好在学习hadoop的一些上层工具,而且在前厂离职前,也在做数据处理(html/xml等)迁移至hadoop的相关调研。HBase是hadoop上的一套类key-value存储服务,比较适合网页库的场景,所以考虑采用HBase做存储。当然,用上了复杂系统之后,复杂度上去了,可控性降低了,实际上并不是简单可依赖。
当初知识储备不足,第一个相当的是直接在HDFS上存文件,再用Hadoop Streaming做处理。但其实Hadoop Streaming多以行为单位进行处理,如果强行用于网页的话,还需要自己定义分割程序,有些麻烦。HBase毕竟还是基于key-value的,对于url-content这样类型的数据处理,肯定要比HDFS支持的好。
以下文章并无工程背景,完全基于作者YY,如果错误,还请帮忙指出。
HBase基本知识
HBase是Google BigTable的一个开源实现,正好之前看过一些源码的leveldb实际上也是一个BigTable的屌丝版实现,所以在了解HBase的过程中,有一些概念还是比较熟悉的。
数据模型
表(Table)
HBase里的表给人的概念其实是RDBMS里的库,但是表相当于库里相同主键的数据join到一起了,因此一个表里包含若干row,每个row就是一条数据记录,也就是KV中的key。
行(Row)
Row就是一条数据,一个Row包括了RowKey和一个或者多个Column。RowKey是按字典序进行排序的,因此对于key的设计有助于把相关联的数据保存在一起,一种经典的key设计方式就是使用域名的倒序,例如com.odinliu.hbase
和com.odinliu.hadoop
,可以把这些数据存在一起,便于批量查询。
列(Column)
Column由<Column Family>:<Column Qualifier>
组成,有点像RDBMS中的列。
列族(Column Family)
CF有点像RDBMS的表的概念,一个CF中包括了若干Column以及它们的值,CF通常是存储在一起的(HBase是一个面向列的KV存储)。每一个CF都可以设置自己的存储配置,例如是否需要内存缓存、数据如何压缩等等,一个Table中的Row均有相同的若干CF,尽管它们可以为空值,空值不占存储空间。
Column Qualifier
也就是通常意义上的列,每个列族中的CQ不一定完全一样。
Cell
RowKey, Column Family, Column Qualifier, Value, Timestamp唯一确定的某一个版本的值。
Timestamp
由于区分版本,可以是数据写入到RegionServer的时间,也可以是用户指定的时间。
网页库设计
上面的内容是N久前挖的坑了,后面网页库这部分,目前生产系统也在用,因为量不大,所以暂时也没啥问题。之前挖的大型坑系列,本来是有一篇pagedb的,而且都挖了一点了,不过暂时不打算填了,以这篇代替吧。
pagedb
考虑到相同模板的网页可能会批量处理,而HBase的rowkey是按字典序的,因此rowkey的设计是http://www.example.com/list?id=123
的rowkey为com.example.www@/list@id=123
。column family两个,mt
存储一些网页基本信息,如url
, content-type
等,dt
存储页面内容。即mt:url
, mt:cnty
, dt:cont
三个字段。