ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Hive与Ceph整合实战:低成本分布式存储选型与调优指南

Hive与Ceph整合实战:低成本分布式存储选型与调优指南 做大数据平台的人几乎都经历过这种纠结业务量没多大但HDFS三副本机制硬生生把存储成本吃掉两倍想换对象存储省钱又担心Hive跑SQL时延迟扛不住。前阵子我正好在内部集群里完成了一套Hive和Ceph的整合方案整个过程踩了不少坑也沉淀了一些可复用的经验这里把完整的选型思路、落地步骤和调优过程分享出来给正在做分布式存储选型的朋友一个参考。这次整合的背景很简单我们已有的Hive数仓集群存储水位逼近85%扩容采购周期长而机房里有几台配置不错但磁盘闲置的机器加上Ceph集群本身就承载着部分业务数据。与其继续往HDFS里填盘不如把Ceph的分布式存储能力利用起来作为Hive的底层存储扩展。这套方案最终实现了Hive任务正常跑、存储成本下降、扩容灵活的目标整个过程从环境准备到生产上线大约花了两周时间。1. Hive和Ceph整合到底在解决什么真实问题1.1 从HDFS存储成本痛点说起Hive本身不是一个存储系统它只是把SQL翻译成MapReduce或Spark任务的计算框架底层数据还是落在HDFS上。HDFS为了保证数据可靠性采用多副本机制默认三副本意味着1TB的业务数据实际占用3TB物理空间这是业内公认的成本大头。很多中小团队的数据量撑死几十TB却被HDFS的副本策略搞得存储资源紧张。Ceph则完全是另一套思路。它底层通过CRUSH算法把数据打散到整个集群的OSD上靠副本或纠删码来保障可靠性。两者并非天然互斥但可以组合Ceph提供弹性可扩展的存储底座Hive继续提供SQL分析能力。这个组合最直接的价值就是可以把存储从计算节点中解耦出来——计算资源不够就加计算节点存储不够就扩Ceph OSD互不绑架。1.2 这套方案适合谁不适合谁先泼一盆冷水如果你们的Hive集群已经有完善的HDFS架构、日常任务对延迟极度敏感那没必要折腾Ceph整合。这个方案的典型适用场景有两个第一是存储成本压力大、希望利用通用硬件构建低成本存储层第二是业务数据量有较大增长预期希望存储层具备弹性扩容能力。另外团队最好具备一定的Linux系统管理能力和Ceph基础运维经验因为整合过程中涉及Ceph客户端配置、挂载、权限处理等一系列操作出问题要能自己排查。如果团队连Ceph都还没接触过建议先搭一套测试环境练手不要直接上生产。2. 三条技术路线的选型逻辑RBD、RGW、CephFS2.1 三种方式的原理与对比Hive和Ceph整合并不是只有一种做法根据数据访问路径的差异业内主流方案大致分三类。我画了张不太严谨的草图在脑子里过了很多遍这里直接用表格对比集成方式原理访问路径适合场景主要限制RBD块存储把Ceph的块设备挂载到Hive节点作为本地文件系统使用Hive - 本地文件系统 - RBD - Ceph集群离线数仓、跑批任务、对延迟不敏感的批处理挂载节点数量受限需要客户端支持RGW对象存储通过S3协议让Hive直接读写Ceph对象存储Hive - S3A连接器 - RGW - Ceph集群外部表、数据湖、归档冷数据S3协议有额外开销小文件性能差CephFS文件存储把CephFS挂载为Hive数据目录的共享文件系统Hive - CephFS挂载点 - MDS - Ceph集群多节点共享数据、迁移过渡期元数据性能受MDS限制海量小文件场景吃力2.2 我的选型判断我在这次整合中最先排除的是CephFS方案。原因是我们的Hive跑批任务会产生大量中间文件元数据操作非常频繁CephFS的元数据服务器在这种负载下容易成为瓶颈。虽然CephFS的NFS/CIFS导出能力很吸引人但对Hive这种高并发元数据操作的场景来说生产环境稳定性还有待验证。最终我选择了RBD和RGW双轨并行的方式热数据、频繁查询的库表放在RBD挂载的目录下冷数据、归档表通过S3协议放到RGW对象存储中。这个组合既保证了热数据的访问性能又让冷数据享受到对象存储的低成本优势算是一个比较务实的折中方案。3. Ceph集群准备与Pool配置细节3.1 环境规划与版本选择Ceph版本选的是Octopus15.2.x虽然已经不算最新但胜在稳定社区资料丰富。Hive用的是3.1.2Hadoop为3.2.1。这里有个版本搭配的细节如果打算走S3协议路线Hive所在节点的Hadoop版本必须带S3A文件系统支持建议Hadoop 3.x起步2.x虽然也能用但S3A兼容性差一些尤其是分片上传和多线程下载这块差距明显。集群环境我简单列一下参考配置你们可以按实际规模调整组件配置数量Ceph MON2C4G系统盘SSD3Ceph OSD4C16G3块HDD1块SSD(WAL)6Ceph RGW4C8G2Hive节点8C32G千兆网卡33.2 创建存储池和RBD镜像的完整操作Ceph集群装好后第一步是创建专门的存储池。这里很多人会忽略pool的pg_num设置直接默认值往上怼后面性能会很难看。我的做法是先估算数据量再根据OSD数量反推PG数量。经验公式是PG数除以OSD数结果落在100到200之间比较合理。# 创建存储池pg_num根据集群规模计算 ceph osd pool create hive_data_pool 128 128 ceph osd pool application enable hive_data_pool rbd # 创建RBD镜像size根据需要设置 rbd create hive-data-disk --size 2048 --pool hive_data_pool # 查看镜像信息 rbd info hive_data_pool/hive-data-diskRGW那边需要单独准备一个存放桶索引的pool我习惯把元数据池和数据池分开建避免对象数据和索引互相干扰ceph osd pool create rgw_buckets_data 256 256 ceph osd pool create rgw_buckets_index 64 64 ceph osd pool application enable rgw_buckets_data rgw ceph osd pool application enable rgw_buckets_index rgw创建好pool之后别忘了配置配额管理。生产环境中如果不设配额某个业务方误操作往桶里灌了几十TB数据你连回滚的机会都没有。给常用bucket设置配额是存储运维的基本素养。4. 用RBD为Hive DataNode扩容的落地步骤4.1 客户端安装与块设备映射Ceph RBD的方式本质上就是把Ceph的块设备当作一块远程硬盘挂载到Hive节点上然后在上面格式化文件系统。这个方式的优势是Hive完全感知不到Ceph的存在它只觉得自己的磁盘变大了。客户端机器上需要先安装ceph-common然后把Ceph集群的ceph.conf配置文件复制到客户端节点的/etc/ceph/目录下同时准备好认证keyring# 所有Hive节点上执行 yum install -y ceph-common # 拷贝配置和认证信息在Ceph管理节点执行 scp /etc/ceph/ceph.conf roothive-node1:/etc/ceph/ scp /etc/ceph/ceph.client.admin.keyring roothive-node1:/etc/ceph/ # 映射RBD设备 rbd map hive_data_pool/hive-data-disk --id admin映射成功后系统里会出现一个类似 /dev/rbd0 的块设备。这个过程我第一次操作时踩了个坑没有加载rbd内核模块导致map命令直接报错。需要先确认modprobe rbd lsmod | grep rbd4.2 文件系统格式化与自动挂载配置块设备映射成功后接下来的操作就跟普通物理硬盘完全一样了。格式化的文件系统我推荐XFS而非ext4原因很简单XFS对大数据量和高并发写入的支撑能力更强而且支持在线扩容以后RBD镜像扩大时不用卸载分区。# 格式化注意确认设备名别把系统盘格式化了 mkfs.xfs /dev/rbd0 # 手动挂载测试 mkdir -p /data/hive/warehouse mount /dev/rbd0 /data/hive/warehouse df -h | grep rbd0手动挂载测试没问题之后配置开机自动挂载。这里有个重要细节RBD设备在系统重启后名称可能变化直接写 /dev/rbd0 到fstab里是不安全的必须使用UUID或者写一个systemd的unit服务在ceph-rbd服务起来之后再执行挂载。我的处理方式是在rc.local里延迟执行cat /etc/rc.d/rc.local EOF sleep 10 rbd map hive_data_pool/hive-data-disk --id admin sleep 3 mount /dev/rbd0 /data/hive/warehouse EOF chmod x /etc/rc.d/rc.local4.3 Hive数据目录切换与验证目录挂载好之后把Hive的数据目录指过去。如果是从HDFS迁移要注意数据拷贝的完整性和权限保留如果是全新环境直接在core-site.xml和hive-site.xml里配置即可。# hive-site.xml中设置warehouse目录 # 注意这里指的是Hive在本地文件系统上的临时目录不代表HDFS数据目录 # 我们的做法是依然保留HDFS作为默认warehouse # 将RBD挂载目录作为Hive的临时执行目录 # 具体配置为 # hive.exec.scratchdir/data/hive/warehouse/tmp # hive.exec.local.scratchdir/data/hive/warehouse/tmp/local这里有个容易被误解的点需要说明Hive默认的warehouse还是在HDFS上RBD挂载目录更多是作为本地临时目录、中间结果存储和Spark Shuffle溢写目录。如果你指望把Hive数仓的表数据全部直接落在RBD上那等于放弃HDFS的数仓底座这个架构取舍需要团队达成一致。我们采用RBD作为临时目录后最明显的改善是跑大批量ETL任务时NameNode的压力显著下降了——大量临时文件的增删不再经过元数据节点。5. 用S3协议打通Hive与RGW对象存储5.1 RGW的S3兼容端点配置RBD虽然好用但它是块级别的跨集群、跨地域的共享能力不足。对象存储方案弥补了这个短板。Ceph的RGW组件对外提供S3兼容接口Hive可以通过Hadoop的S3A文件系统直接读写这些数据。RGW配置本身不复杂关键是正确设置region和endpoint。我遇到过最磨人的问题就是region不匹配导致S3A连接失败。Ceph默认的region叫us-east-1而Hadoop的S3A客户端如果指定了别的region握手就会失败。RGW服务启动后通过下面的命令创建S3访问密钥# 创建S3用户 radosgw-admin user create --uidhive_user --display-nameHive User # 输出中会有access_key和secret_key妥善保存5.2 Hive通过S3A读写外部表的配置拿到access_key和secret_key之后在Hive节点上配置S3A相关的core-site.xml项property namefs.s3a.endpoint/name valuehttp://rgw-server:7480/value /property property namefs.s3a.access.key/name value你的AK/value /property property namefs.s3a.secret.key/name value你的SK/value /property property namefs.s3a.path.style.access/name valuetrue/value /property property namefs.s3a.connection.ssl.enabled/name valuefalse/value /propertypath.style.access这个参数是关键。老牌对象存储如AWS S3默认用虚拟主机风格访问bucket但Ceph RGW通常需要path-style访问也就是endpoint后面直接跟bucket名而不做DNS解析。很多线上事故都是这个参数没设对导致的。配置完成后就可以在Hive里建外部表指向S3了CREATE EXTERNAL TABLE s3_test_logs ( log_time STRING, user_id STRING, action STRING ) ROW FORMAT DELIMITED FIELDS TERMINATED BY , LOCATION s3a://hive-bucket/logs/;5.3 典型查询验证与性能表现表建好之后跑一条简单的count查询验证连通性。首次查询如果发现特别慢不要急着怀疑Ceph性能先检查小文件数量。S3A客户端访问小文件的性能损耗非常大因为每个文件都要建立独立的HTTP连接。我的处理办法是先用Hive的INSERT OVERWRITE把分散的小文件合并成大文件INSERT OVERWRITE TABLE s3_test_logs SELECT * FROM s3_test_logs;这条SQL默认会产生一些临时文件但后续合并后的输出文件数会减少很多。实测下来RGW路径下1GB左右的文件单查询扫描时间在秒级到十几秒之间作为冷数据查询是合格的。6. 生产环境中的性能调优与故障复盘6.1 关键性能参数清单整合方案跑了一段时间后我总结了几个对性能影响最明显的参数按重要性排列如下参数推荐值作用fs.s3a.fast.upload.bufferdisk使用磁盘缓冲避免堆内存溢出fs.s3a.fast.upload.active.blocks8并发上传块数提高吞吐fs.s3a.multipart.size128M分片上传大小兼顾并发和开销fs.s3a.connection.maximum64最大HTTP连接数rbd cachetrueRBD客户端缓存提升读性能rbd cache size134217728缓存大小128MB按内存余量调pool pg_num按OSD数量计算打散均匀性直接影响IO分布有一点要提醒RBD的缓存是客户端内存缓存如果节点内存紧张建议调小甚至关闭。我们有次内存告警排查到最后就是RBD缓存加JVM堆内存加操作系统Page Cache凑一起把内存挤爆了。6.2 我在线上遇到的两个问题第一个是RBD映射的块设备偶尔出现IO卡住。排查发现是Ceph集群中有两个OSD down了数据处于降级状态但监控告警没触发。RBD的读写路径对OSD状态非常敏感一旦有OSD异常IO延迟立刻放大几倍。解决方式有两个层面一是把Ceph的监控告警做完善OSD down超过5分钟必须告警二是在Hive节点侧给RBD挂载目录调整IO超时时间避免因为单次IO卡死导致Spark任务整体失败。第二个是S3A路径下Hive查询偶发报错错误信息类似Connection pool shut down。这个问题的根源是RGW后端的空闲连接被回收了但客户端连接池不知道继续使用旧连接。在core-site.xml里设置连接空闲检查参数可以缓解property namefs.s3a.connection.ttl/name value30000/value /property这个问题的排查过程有点曲折最开始以为是网络抖动后来抓包发现是连接池里的连接已经失效但客户端没有感知。调整TTL后问题消失。6.3 日常运维监控建议整合方案上线后日常运维需要关注的指标比以前多了一圈。Ceph侧要盯OSD状态、PG分布、集群IO延迟Hive侧要关注临时目录磁盘使用率、S3A连接数、RBD挂载点的读写延迟。我的建议是至少配置以下几项监控告警Ceph集群health状态变化特别是PG变成inactive或degradedOSD down数量超过阈值比如大于等于2RBD挂载点的IO延迟突增超过基线3倍S3A接口的错误率对应RGW的访问日志做统计存储池容量使用率超过70%就要提前规划扩容监控工具有条件的用Prometheus加GrafanaCeph本身提供exporterHive节点上用node_exporter加自定义脚本采集RBD指标组合起来基本够用。没条件用脚本加crontab跑检查也行但告警延迟会高一些。这套Hive和Ceph的整合方案上线到现在存储成本降了接近40%因为冷数据全部走了对象存储热数据的临时文件也不再占用HDFS的副本空间。如果你所在的团队也在盘算给Hive找个合适的存储底座建议先拿非核心业务跑一段时间把监控、告警、容灾这些都梳理清楚再逐步扩大范围。存储架构的变化不像应用代码那样可以随时回滚谨慎一点不吃亏。
返回列表