一.PDNS库设计
根据前期调研及技术选型,基于第三方外部PDNS数据,开发导入程序,完成构建基于Hadoop HBASE的PDNS实时数据查询系统,系统平台采用8台4U服务器组成Hadoop集群。
- 服务器配置为:Xeon Silver 4110 @2.1Ghz,128G内存,24*2T硬盘。
- HDFS块大小:256MB
- Hbase Region大小:10GB
- 其他为默认配置。
库设计主要考虑点说明:
- 高并发。
无高并发需求,不存在该场景,HBASE的RowKey设计时不需要考虑Key值散列程度。 - 实时响应。
Hbase中正确使用Key值进行查询,可提供准实时级别响应。因此在使用Key进行查询时,为保证实时响应,只考虑使用以下两种走列索引的高效查询命令:
(1)基于key,查value。
(2)基于Key的STARTROW和ENDROW进行查询。 - 数据更新与备份
备份:可对第三方数据外部数据单独进行备份。
更新:可使用HBASE多版本特性,保留更新后的多版本数据。 - 其他
扩展性、健壮性可参考Hbase动态扩展、Hbase Master高可用方案。
1.1 PDNS数据业务字典及样例数据
1.1.1 业务字典
数据文件pdns.sample
每行一个record的json字符串,在序列化中先将meta字段的值进行了json序列化,然后进行整体record记录json序列化。
1.1.2 数据样例
第三方原始数据样例如下:
{
‘meta’: [[1572765040000, 1572765040000, 1, [‘virustotal’]]],
‘name’: ‘xzyx.mail.com-secure-auth-success-redirect-user.mailcommute.com’,
‘type’: ‘A’,
‘data’: ‘204.11.56.48’
}
1.1.3 数据规模
经统计,PDNS数据记录总规模在55亿条左右。
第三方原始数据文件大小为1.8T【非压缩文本】。
1.2 PDNS查询需求说明
根据调研,PDNS库查询需求主要有以下2种。
1.2.1 根据域名查询
查询输入:域名、起始时间、终止时间
查询输出:整条PDNS数据。
举例:
输入下面查询条件:
域名:xzyx.mail.com-secure-auth-success-redirect-user.mailcommute.com
起始时间:1572765040000
终止时间:1572765040000
查询输出数据为:
{
‘meta’: [[1572765040000, 1572765040000, 1, [‘virustotal’]]],
‘name’: ‘xzyx.mail.com-secure-auth-success-redirect-user.mailcommute.com’,
‘type’: ‘A’,
‘data’: ‘204.11.56.48’
}
1.2.2 根据IP地址查询
查询输入:IP地址、起始时间、终止时间
查询输出:整条PDNS数据。
举例:
IP地址:204.11.56.48
起始时间:1572765040000
终止时间:1572765040000
查询输出数据为:
{
‘meta’: [[1572765040000, 1572765040000, 1, [‘virustotal’]]],
‘name’: ‘xzyx.mail.com-secure-auth-success-redirect-user.mailcommute.com’,
‘type’: ‘A’,
‘data’: ‘204.11.56.48’
}
1.3 PDNS表设计
PDNS数据采用HBASE进行存储,Hbase是以Key作为查询条件,以Value输出的,半结构化的,面向列存储格式进行存储的海量实时查询数据库。
1.3.1 表设计思路
为满足1.2需求,根据Hbase只能使用单一Key作为查询条件的特点。对于“根据域名查询”及“根据IP地址查询”2种需求,采用2张表的设计方案,如下:
1.对于1.2.1需求,设计表PDNS,可满足直接使用域名、时间查询整条记录的需求。
2.对于1.2.2需求,设计索引表pdns_ip2domain_index,在查询时分两步实现:
(1)使用IP、时间在pdns_ip2domain_index索引表中查询域名。
(2)使用步骤(1)中返回的域名,以及时间,再去PDNS表中查询出完整记录。
1.3.2 PDNS表
PDNS表的ROWKEY为:域名_终止13位时间戳。
说明:
ROWKEY设计为:“域名_终止13位时间戳”即可满足查询1.2.1查询需求,查询逻辑如下。
当查询条件为域名、起始时间、终止时间时,可基于HBASE索引的特性,查询出匹配指定时间范围内的记录。
举例:
查询域名“–9n9xwk.grizlybigtit.com”在 时间 “1368662400000”的解析记录。
可通过命令:get ‘pdns’,’–9n9xwk.grizlybigtit.com_1368662’ 实现,因为基于HBASE索引默认按字典排序特性,上述命令查询了–9n9xwk.grizlybigtit.com域名在136866200000~ 136866299999时间范围内的所有解析记录。
PDNS表中记录查询:
1.3.3 pdns_ip2domain_index表
pdns_ip2domain_index表的ROWKEY为:IP_终止13位时间戳。
pdns_ip2domain_index表中记录样例如下:
说明:
基于pdns_ip2domain_index表的查询使用方法。
(1)根据用户输入的IP地址、时间范围,在pdns_ip2domain_index中查询索引记录。
scan ‘pdns_ip2domain_index’,{STARTROW => ‘174.128.255.229_146’,ENDROW => ‘174.128.255.229_147’}
(2)根据查询到的时间1467308336000,在PDNS表中做精确查询。
get ‘pdns’, '–1-.vicp.net_1467308336000 ',结果如下。
1.4 建表脚本
1.4.1 PDNS建表脚本
create ‘pdns’,{NAME =>‘meta’,COMPRESSION => ‘SNAPPY’}
其中,列簇为 meta;列为 syst,domain,ip,type,stt,edt,count,source。
经数据导入后,列名对应的列会自动填充到列簇中。
1.4.2 pdns_ip2domain_index建表脚本
create ‘pdns_ip2domain_index’,{NAME =>‘meta’,COMPRESSION => ‘SNAPPY’}
其中,列簇为 meta;列为 domain。
经数据导入后,列名对应的列会自动填充到列簇中。
1.4.3 关于数据导入
从原始文本数据导入到Hbase表中的导入脚本需要自行开发,在导入数据时,需要将对应列的数据填充到列族中。
1.5 REST API使用
1.5.1 开启HBASE REST API服务
Hbase自带 Rest服务,需要在Cloudera Manager页面中启动Hbase的 Rest服务。具体方案请安装Cloudera Hadoop后自行百度。默认端口20550
1.5.2 REST API使用例子
(1)单条记录查询
- REST命令:http://192.168.10.24:20550/pdns/—link.wmkg.info_1435499558000
返回结果:
<CellSet>
<Row key="LS0tbGluay53bWtnLmluZm9fMTQzNTQ5OTU1ODAwMA==">
<Cell column="bWV0YTpjb3VudA==" timestamp="1591560104172">MQ==</Cell>
<Cell column="bWV0YTpkb21haW4=" timestamp="1591560104172">LS0tbGluay53bWtnLmluZm8=</Cell>
<Cell column="bWV0YTplZHQ=" timestamp="1591560104172">MTQzNTQ5OTU1ODAwMA==</Cell>
<Cell column="bWV0YTppcA==" timestamp="1591560104172">NTAuODcuMTQ0LjE0</Cell>
<Cell column="bWV0YTpzb3VyY2U=" timestamp="1591560104172">XCJkbnNkYlwi</Cell>
<Cell column="bWV0YTpzdHQ=" timestamp="1591560104172">MTQzNTQ5OTU1ODAwMA==</Cell>
<Cell column="bWV0YTp0eXBl" timestamp="1591560104172">QQ==</Cell>
</Row>
</CellSet>
说明:XML标签中的column和value的值均为Base64编码,需要自行解码。
(2)跨时间范围查询
- REST命令:http://192.168.10.24:20550/pdns/*?startrow=—link.wmkg.info_1435499551000&endrow=—link.wmkg.info_1435499559000
返回结果:
<CellSet>
<Row key="LS0tbGluay53bWtnLmluZm9fMTQzNTQ5OTU1ODAwMA==">
<Cell column="bWV0YTpjb3VudA==" timestamp="1591560104172">MQ==</Cell>
<Cell column="bWV0YTpkb21haW4=" timestamp="1591560104172">LS0tbGluay53bWtnLmluZm8=</Cell>
<Cell column="bWV0YTplZHQ=" timestamp="1591560104172">MTQzNTQ5OTU1ODAwMA==</Cell>
<Cell column="bWV0YTppcA==" timestamp="1591560104172">NTAuODcuMTQ0LjE0</Cell>
<Cell column="bWV0YTpzb3VyY2U=" timestamp="1591560104172">XCJkbnNkYlwi</Cell>
<Cell column="bWV0YTpzdHQ=" timestamp="1591560104172">MTQzNTQ5OTU1ODAwMA==</Cell>
<Cell column="bWV0YTp0eXBl" timestamp="1591560104172">QQ==</Cell>
</Row>
</CellSet>
1.6 Hbase相关配置参考
1.6.1 Hbase查询超时配置
根据查询业务确定查询超时时间,如果发生慢查询,可直接超时返回,后续可对慢查询再做优化,建议参考配置参数如下:
hbase.rpc.timeout
hbase.client.operation.timeout
hbase.client.scanner.timeout.period
waitTime=60000
1.6.2 Hbase历史版本设定
Hbase自身支持多版本数据,可根据更新数据情况,设定保存版本的个数,命令为:
alter ‘test’,NAME=>‘meta’,VERSIONS=>‘10’ //保存表test最近10个版本的记录
每当新数据覆盖已有数据时,已有数据会自动保存到历史版本中。
查询历史版本数据命令:
get ‘test’,‘4’,{COLUMN=>[‘meta:domain’,‘meta:ipAdd’],VERSIONS=>2} //查询最近2个版本数据。