(1)数据类型(Data Types)
使用数字(Numeric)类型(不是字符串)
l 尽可能避免字符串类型
l 字符串 => 更高的内存消耗、更多的存储空间、更慢的计算速度
Decimal vs Float / Double
l Decimal更容易使用
l 目前不能使用Decimal作为分区键或UDFs
只使用字符串的情况
l HBaseRowkey — String是推荐的类型!
l Timestamp— 可以使用String,但可以考虑使用数字(Numeric) !
(2)分区设计(Partition design)
有3个简单的规则
l 从使用实例或现有的SQL来确认访问模式。(Identifyaccess patterns from the use case or existing SQL)
在WHERE子句中常用的列作为分区键
可以有多个分区键!
例子:
select col_1 from store_sales where sold_data between ‘2014-01-31’and ‘2016-02-23’;
selectcount(revenue) from store_sales where store_group_id in (1, 5, 10);
partitionkeys => sold_date, store_group_id
l 估计的分区总数(最好是<100 k !)。
为每个分区键估计不同值的数量(NDV) ( Estimate the number ofdistinct values (NDV) for each partition key (for the required storageduration))
l 如果可以,尽量减少分区数。
删除一些“不重要”的分区键。如果一个分区键不经常使用,也不影响SLA。删除它!
创建分区“桶”。
使用月而不是日期。
Createartificial store_group to group individual stores.
技术:使用前缀或Hash
Hash(store_id) %store_group size => hash it to store_group
Substring(store_id,0,2) => 使用前两位作为store_group
(3)常见的问题(Common questions)
列的数量最多2k
不是硬限制;Impala和Parquet可以处理更多,但是……。
它会减缓Hive Metastore元数据更新和检索。
Timestamp
在Hive的Parquet仍然不支持时间戳。
使用长整型数字(更高效)或字符串(容易读)。
二进制大对象/字符大对象(BLOB/CLOB)—使用字符串。
没有明确的上限,但1MB还是OK的
更大的—大小的字符串可以使Impala死亡。
谨慎使用,整个1 MB字符串将无处不在。
(4)文件格式
Parquet/Snappy
long-term存储格式
读很好
写的非常缓慢(有报道称10倍低于Avro)
Snappy vs Gzip
Snappy通常在压缩比和CPU之间的权衡决策上是很好的压缩方式
但是,需要根据自己具体情况来选择
For write-once-read-once tmpETL table, 考虑 seq/snappy 因为:
写速度更快
Impala可以写
(5)块大小
块的数量定义了平行度:
适用于MapReduce和Impala
每一块由一个CPU核心处理
利用所有的CPU核跨集群, #blocks >=#core
更大的块大小
更好的IO吞吐量,但较少的块,可以减少并行
更小的块大小
更多的并行性,但可以减少IO吞吐量
Apache Parquet,300MB+是好的,不要超过1 GB。
不要低于64MB。
如果你真的想确认块大小,使用以下方程:
Block Size<= P * T * C / S
P – 磁盘扫描速度(100 mb/秒)
T – 想要查询的响应时间(秒)
C – 并发性
S – %of column selected