如果您有 OLTP 类型的查询,HBase 是一个合适的选择,即您的查询模式仅限于点获取或小范围查询。
Phoenix 只是 HBase 之上的一个 SQL 层,它为用户提供使用 SQL 结构查询 HBase 中数据的能力。
当您提交任何 SQL 查询时,Phoenix 将对其进行解析并创建一个执行计划,该计划可以根据您查询的内容将查询中断为全扫描、范围扫描或点获取。
Phoenix 使用 Predicate Push down 处理结果,因此 HBase 执行所有处理(扫描并从所有区域服务器获取必要的行),Phoenix 聚合/整理结果行并将它们返回给用户。
现在回答您的问题“phoenix 是否适合 ETL 和聚合?” - 否如果您需要执行大型操作,它不适合使用聚合进行扫描(全范围或大范围扫描),并期望在几秒或亚秒内处理结果。如果您的表占用空间很小(几百 GB),这些查询可能会正常工作,但随着表大小会随着时间的推移而增加,您最终会遇到严重的性能问题。
这是 OLAP 场景,您应该寻找其他替代方案。
我假设当您说将 Hive 与 HBase 结合使用时,您计划在 HBase 表之上创建一个 Hive 外部表,该表可以直接使用 HiveHBaseTableInputFormat 查询 HFile。
这将使用 MapReduce 来处理查询,您无法通过分区、分桶等真正利用性能优化。
我建议考虑对点获取和小范围查询使用 HBase + Phoenix 选项,对于大型聚合/ETL 类型的查询考虑使用 Spark,它会比 Hive 选项更好更快。
如果您的数据仅追加,您可以考虑使用一些替代的 OLAP 支持存储选项,例如 Tez 上的 Driud、Clickhouse 或 Hive、带 Impala 的 Hive 或 Presto 选项而不是 HBase。
根据评论更新 -
Spark 将比 Hive (MapReduce) 选项更快;仅将 Spark 用于使用大范围或全扫描然后聚合的查询。
虽然 Phoenix 利用协处理器和谓词下推到 HBase 区域,但可用资源的数量可能会成为限制,Phoenix 会将查询并行化为由 GUIDE_POSTS_WIDTH 决定的块,对于大型表,这很容易从几百个到 1000 秒并为 RPC 队列创建争用,同样在扫描期间,HFiles 将被读取并加载到 regionserver 堆中,如果扫描无法将结果放入分配的堆中,您可能会遇到 GC 或 OOM 问题。扫描器可能会受到 rpc 等待时间和可用内存的限制,从而导致超时。
您可以在一定程度上调整上述情况,但 HBase/Phoenix 不适用于 OLAP。使用 Spark,您可以直接读取 HFiles 并随后应用过滤器,这将消除超时问题。如果一次又一次查询相同的数据子集,您可以尝试将外部 rdd/dataframe 缓存到 Ignite。
我想补充一点,在寻找替代方案之前,您应该分析您在 HBase 中存储数据的方式是否与您的查询模式一致?如果您的查询计划正在创建全扫描,请重新访问您的行键设计,尝试重新设计行键或查询以避免全扫描?检查您的数据是否在所有地区分布良好?您的高写入率会影响您的读取性能吗?
如果您需要分析点击流类型的数据,请查看 Clickhouse,Yandex 为类似用例开发并开源了它,但它也适用于其他 OLAP 用例。
希望这有帮助。