算力跟存储绑在一台机器上,这是绝大多数大数据集群最原始的形态。早期用Hadoop的时候,我们习惯性地把DataNode和NodeManager堆在同一批服务器上,美其名曰“数据本地性”,计算任务能直接读本机磁盘,速度确实快。但跑到后面你会发现一个问题:存储快满了、CPU却常年闲着,或者计算高峰期CPU打满、磁盘还有一大半空着。扩容?只能整机加,一加就是好几十台,钱花了,资源利用率该差还是差。
存算分离这几年被反复讨论,核心诉求其实特别朴素——把计算和存储从同一台机器里拆开,各自独立扩容、独立计费、独立运维。放在五年前这是架构上的“异端”,因为大家的共识是“计算要靠近数据”;但今天,对象存储、云端计算、弹性伸缩这些基础设施成熟之后,这套思路已经成了大数据平台降本增效的主流方案之一。
这篇文章就从我自己的实战视角出发,把存算分离这件事拆开讲透:它到底解决什么问题、技术栈怎么选、真实项目里怎么落地、性能账和成本账怎么算,以及那些文档里不会写的坑。适合正在做大数据平台规划、集群运维、数仓建设的朋友,也适合刚入门想搞懂大数据架构演进逻辑的同学。
1. 从架构演进看存算分离:为什么大家都在谈
1.1 大数据四层架构里,存和算原本是被焊死的
要理解存算分离,得先把大数据架构的基本盘过一遍。通常我们说大数据架构包括四个层次:数据采集层、存储层、计算层、应用层。采集层负责把业务数据、日志、埋点收上来;存储层负责把数据落盘管理;计算层跑批处理、流处理、即席查询;应用层出报表、出接口、出可视化大屏。
在传统Hadoop世代,这四个层次里最重的是存储和计算,而这两个层在物理上又是绑在一起的。一个典型的HDFS集群,每个节点上既有DataNode又有NodeManager,数据按块分布在各节点的本地磁盘上,计算框架在做任务调度时,优先把任务调度到数据所在的节点——这就是“数据本地性”。好处是网络IO省了,坏处是资源没法独立伸缩:你想加存储,必须连带着加CPU和内存;你想加计算,也必须连带着加磁盘。按需付费、弹性扩容这些词,在传统架构里基本是空谈。
这个问题的本质,是把存储的容量需求和计算的能力需求强行耦合了。而真实业务里,这两者的增长曲线根本不同步。以网约车平台为例,订单明细和轨迹数据每天都在涨,冷数据越积越多,这是存储的线性增长;但计算需求是随业务波动的,早晚高峰的实时指标计算、月末的财务报表批任务、运营活动的离线分析,都是明显的脉冲式压力。如果按峰值来买机器,低谷期全部闲置;如果按均值来买,高峰期又扛不住。存算分离就是冲着这个矛盾去的。
1.2 从“移动计算”到“移动数据”:底层逻辑的一次转折
Hadoop时代有一句经典口号:移动计算比移动数据更划算。因为网络带宽是稀缺资源,把计算任务下发到数据所在节点,比把TB级数据拉到计算节点要快得多。这句话放在机架内万兆网、磁盘顺序读的场景下完全成立。但今天,存储和计算之间那片“数据移动”的土壤已经变了。
第一,网络基础设施质变了。万兆、25G、100G网络在数据中心里已经普及,跨节点拉数据的成本比十年前低了两个数量级。第二,存储形态变了。对象存储(S3、OSS、COS这类)在海量数据场景下几乎是无限容量,吞吐可以按需扩展,价格比本地盘便宜得多。第三,计算资源开始容器化、Serverless化。Spark、Flink这些引擎都可以跑在K8s上,按业务峰谷自动伸缩。这个时候,“移动计算”的优势被大幅削弱,“移动数据”的代价也不再不可接受,存算分离自然成了更符合时代的选择。
当然,不是说数据本地性完全没用了。实际上在现在的存算分离架构里,我们依然会尽量做本地缓存、做Shuffle亲和性调度,努力让计算任务读到的数据尽量“靠近”。但这和以前那种“数据必须跟计算同一台机器”的强约束已经完全不同了。存算分离的本质,是把“引擎+资源”和“数据+元数据”拆成两个独立系统,用网络换取解耦的灵活性。牺牲一部分读性能,换来的是按需弹性、按量计费、多集群共享一份数据的能力。
1.3 网约车、实时指标、批量报表:真实场景驱动的必然
为什么说存算分离是被真实业务逼出来的?我拿一个典型的网约车大数据项目举例。数据链路大概是这样的:订单明细、司机轨迹、支付流水这些数据,通过Flume或者Kafka进到ODS层,然后Spark做清洗,Hive做离线分析出报表,最后用Flask+ECharts做可视化展示。日常跟大数据相关的就是这些,听着不算复杂。
但问题出在“跑批”和“查询”的资源需求完全不一样。清洗和跑批是重CPU、重内存、大吞吐的作业,跑一次全量清洗可能要几十台机器忙活半天;而即席查询和分析报表是延迟敏感型任务,希望集群时刻在线、随时响应。如果它们共享一套“存储+计算一体”的集群,相互之间必然抢资源。跑批高峰时,即席查询变得奇慢无比;查询被频繁调用时,跑批又一直被拖后腿。
存算分离的方案是把数据统一放到一个共享存储底座上,比如HDFS、对象存储或者云原生存储。批处理任务、流处理任务、即席查询任务分别使用独立的计算集群,哪个任务来了就拉起对应的计算资源,任务结束就释放。这样每个任务都拥有专属的CPU和内存资源,互不干扰,同时所有任务访问的是同一份数据,不用为每个计算集群各自复制一套数据。这就是这套架构最核心的价值——多计算引擎共享一份数据存储。
2. 存算分离技术栈选型:不是只有“上云”一条路
2.1 三种存储底座对比:HDFS、对象存储、云盘
做存算分离,第一个要决定的事情就是:底层用什么做存储底座。市面上的选择看起来五花八门,实际上主流的就是三条路。
| 存储底座 | 优点 | 缺点 | 适合场景 |
|---|---|---|---|
| 自建HDFS(纯HDFS节点) | 一致性体验好,兼容原生Hadoop生态,无网络计费 | 容量仍需自运维,元数据瓶颈仍在 | 已有大量Hadoop存量资产、有专业运维团队 |
| 对象存储(兼容S3协议) | 容量近乎无限,按量计费,无需自运维 | 访问延迟高、小文件性能差、需适配文件语义 | 冷热数据分层、长期归档、弹性计算配合 |
| 云盘/分布式块存储 | 延迟低,按容量购买,支持挂载给计算节点 | 吞吐扩展受限,价格比对象存储高 | 需要较高随机IO性能、中度弹性需求的场景 |
我自己的实际感受是:如果是中小团队、计算负载波动明显,直接走“对象存储+弹性计算”是最省心的路径。HDFS本身也可以存算分离——把HDFS单独部署在存储型节点上,计算节点只部署YARN或者Spark,通过不同机架、不同网络段来隔离。这种方式的好处是完全复用Hadoop生态,不用改代码,坏处是存储容量仍然受限于你买的服务器数量,本质上还是“自运维存储”。
如果你用的是云厂商的对象存储,记住一个关键点:让引擎尽量以“大数据读取”的方式访问对象存储,比如Spark里用s3a协议、Flink里用Hadoop FileSystem接口对接OSS/S3,不要用普通HTTP接口一条条拉文件,否则性能和成本都很难看。
2.2 计算引擎在分离架构下的适配:Spark、Hive、Flink
存储定了,计算引擎怎么接进来也要仔细想。存算分离不是说把Spark部署在另一批机器上就完事了,你得保证引擎跟存储之间读得高效、写得顺滑、失败能重试。这里有几个核心问题。
Hive。Hive本身是典型的“计算框架+元数据管理+存储上层的SQL引擎”,在存算分离架构下,Hive的适配点主要在Metastore和HDFS/对象存储之间。Metastore继续存表结构、分区信息、字段注释这些元数据,底层数据文件放到对象存储里。需要注意,Hive的ACID表、事务表在对象存储上支持得相对别扭,如果业务强依赖事务表,建议保留一小块HDFS给事务表专用,其余大表走对象存储。
Spark。Spark在存算分离下相对最省心。写代码时把路径从hdfs://...换成s3a://...或者oss://...,再加上spark.hadoop.fs.s3a.endpoint这类配置即可。但有个坑必须提醒:对象存储的“List操作”代价很高,如果你每天产生几万个小文件,Spark任务在启动Stage时拉取文件列表就可能卡很久。所以存算分离对文件组织方式要求极高,分区粒度、文件大小、目录层级都要重新设计。
Flink。流计算场景下,存算分离的适配重点是Checkpoint。Flink默认的Checkpoint存储可以是HDFS或对象存储,在分离架构下建议Checkpoint仍然放在延迟更低的HDFS或云盘上,最终结果数据再写对象存储。因为Checkpoint是高频低延迟的操作,对象存储在这种场景下表现不佳。
2.3 元数据服务与缓存层:容易被忽略的两块拼图
一提存算分离,很多人只盯着存储和计算两个组件,但真正容易翻车的是元数据和缓存。元数据服务(Hive Metastore、Iceberg Catalog、HDFS NameNode)是整套架构的大脑,计算引擎每次提交作业都要跟它交互,获取表的位置、分区路径、文件列表。如果元数据服务没有做高可用、性能没有调优,整个存算分离集群会表现为“作业提交慢、任务卡住、偶发失败”。
我在实际项目中见过最典型的问题:Metastore用默认的单机模式部署,跑十几个并发任务就开始出现锁等待,所有SQL任务排队。优化方法很直接——启用Metastore的独立服务模式、配置连接池和线程池、给Metastore数据库做索引优化,这些细节在单机一体架构下通常不会暴露,一旦上了存算分离,全都变成瓶颈。
缓存层是另一个重点。存算分离之后,每个计算任务启动时都要从远端存储拉数据,虽然网络快了,但延迟再怎么优化也比不上本地SSD。业内普遍的做法是引入一层本地缓存:计算节点的本地磁盘或内存中缓存热数据片段。比如Alluxio就是一个专门做这个的分布式缓存系统,Spark和Flink接入后,重复查询的数据可以直接命中缓存,性能可以恢复到接近本地读的水平。不想引入额外组件的话,也可以用HDFS的短路读、页缓存等特性,尽量让操作系统的文件缓存发挥作用。
3. 实操:从一个网约车数据项目看存算分离落地
3.1 项目背景与数据分层:ODS到ADS的四层设计
前面讲的都是理论,接下来用一个网约车数据分析项目来完整走一遍存算分离落地流程。这个项目我当时是在一套“对象存储+Hive Metastore+弹性Spark计算集群”的架构上做的,处理的数据量不大,但链路完整,很适合拿来说明设计思路。
数据分层是数仓的经典做法,也是存算分离架构下必须一开始就定好的事。整个项目分四层:
- ODS层:原始数据落地层,Kafka里的订单数据、日志数据原样存储,不加工,通常就是JSON或者CSV格式。
- DWD层:明细层,经过Spark清洗后的结构化数据,去掉脏数据、补齐字段、统一时间格式。
- ADS层:应用层,按业务维度聚合好的结果表,供报表和可视化直接使用。
- DIM层:维度表,比如城市维度、车型维度、司机等级维度。
在存算分离的架构里,ODS和DWD层我建议放对象存储,因为它们的访问模式是“写一次、读多次”,而且数据量大、冷热交替明显,对象存储成本优势很大。ADS层因为有高频查询需求,可以放在HDFS或者云盘上,配上本地缓存,保证查询响应速度。这样的分层存储策略,也是存算分离架构下降本增效的关键之一。
3.2 Spark清洗、Hive分析、Flask+ECharts展示的完整链路
链路的具体实现是这样的。数据采集阶段,Flume或者Kafka Connector把订单流写入Kafka,然后通过Canal或者直接消费落盘到ODS层。接下来用Spark做清洗,读ODS的原始JSON,做字段解析、去重、规范化,写出Parquet格式到DWD层。
// 存算分离下Spark清洗任务的路径配置示例 // 读取对象存储上的ODS原始数据 val rawDF = spark.read .json("s3a://netcar-bucket/ods/order_log/2024-11-01/") // 清洗逻辑:过滤掉test订单、支付金额为负、时间字段非法等脏数据 val cleanDF = rawDF .filter($"order_status" === "COMPLETED") .filter($"pay_amount" > 0) .withColumn("dt", to_date($"create_time")) .withColumn("city_id", $"city_id".cast("int")) .withColumn("pay_amount", $"pay_amount".cast("decimal(10,2)")) // 写出到DWD层,按dt和city_id分区 cleanDF .repartition(col("dt"), col("city_id")) .write .mode("overwrite") .partitionBy("dt", "city_id") .parquet("s3a://netcar-bucket/dwd/order_detail/")写完DWD层,就到了Hive分析的环节。Hive表的建表语句这时候只需要把location指向对象存储路径,Metastore负责管理元数据,计算引擎(可以是Hive on Spark,也可以是直接用SparkSQL)负责跑SQL。
-- 存算分离下Hive表指向对象存储 CREATE EXTERNAL TABLE dws_city_order_stats ( city_id STRING, city_name STRING, order_cnt BIGINT, total_amount DECIMAL(12, 2), avg_amount DECIMAL(10, 2) ) PARTITIONED BY (dt STRING) STORED AS PARQUET LOCATION 's3a://netcar-bucket/dws/city_order_stats/'; INSERT OVERWRITE TABLE dws_city_order_stats PARTITION (dt='2024-11-01') SELECT city_id, max(city_name) AS city_name, count(*) AS order_cnt, sum(pay_amount) AS total_amount, avg(pay_amount) AS avg_amount FROM dwd_order_detail WHERE dt = '2024-11-01' GROUP BY city_id;最后是可视化部分,Flask提供HTTP接口,查询ADS层数据,ECharts在前端渲染出订单趋势图、城市分布图、司机收入排行。这一层在存算分离架构下没有特殊之处,唯一要注意的是Flask接口不要直接去查询对象存储上的原始文件,一定要查预计算好的ADS层结果表,否则响应时间不可控。
3.3 任务调优:把“远程读”压到最低
存算分离任务调优的目标很简单:尽量减少从远端存储读取的数据量。同样是这个网约车项目,我从几个方向做了优化。
第一,分区裁剪做到位。所有查询、清洗任务必须带上分区过滤条件,比如WHERE dt = '2024-11-01'。很多第一次接触存算分离的人会忽略这一点,结果每次任务都把整张表的数据扫一遍——对象存储按请求次数收费,全表扫描的代价是让人肉疼的账单。我在项目里甚至专门写了检查规则,发现没有分区条件的SQL直接抛警告。
第二,文件尺寸控制。Parquet文件建议控制在256MB到1GB之间。太小了,对象存储的List请求会爆炸;太大了,并行度又不够。通过调整Spark的spark.sql.adaptive.coalescePartitions.enabled和shuffle分区数来控制输出文件个数,这是我在实际项目里验证过的最有效手段。
第三,中间数据不落远端。Shuffle产生的中间文件、临时表、Checkpoint数据,全部写到计算节点的本地磁盘,只有最终结果写到对象存储。Spark默认就是这样做的,但如果你配置了spark.local.dir指向网络存储,就会白白增加大量网络IO。
4. 成本账与性能账:这笔账必须算明白
4.1 成本模型对比:固定集群 vs 按需计算资源
存算分离最打动人的地方,其实是成本模型发生了变化。传统一体机的成本是“买机器”的成本,买了就得固定折旧,无论你用它跑没跑任务。存算分离之后的成本是“存储按量计费+计算按时长计费”的成本,存储花的是容量钱,计算花的是核小时钱。
我调了一个典型的项目预算:一个日活百万、每天产生2TB增量数据的业务,传统方式需要大约20台机器(每台32核、128GB内存、4TB磁盘),年成本粗算在80-100万左右,其中存储容量用到一半,CPU利用率平均不到30%。换成存算分离:存储底座用对象存储按量计费,一个月2TB增量、保留6个月冷热数据,存储成本大约在几千块一个月;计算资源按需申请,日常只有跑批和查询才有负载,月均计算费用大约是两到三万。整体算下来,年成本能省40%-50%。
这还只是直接成本。存算分离还有一笔隐性收益:业务上线周期变短了。传统方式下,一个新任务上线要先申请机器、部署环境、做容量评估,前前后后要一两周;存算分离下直接拉起计算集群,配置好依赖就能跑,半天搞定。这个账项目的CTO和架构师都看得懂,所以现在很多公司做大数据平台评估,第一个问的就是“支不支持存算分离”。
4.2 数据本地性损失:真正影响性能的是Shuffle与Scan
存算分离不可能只占便宜不吃亏,最大的损失就是数据本地性。在一体机架构里,Spark任务读取本机HDFS块,吞吐能到每秒几百MB甚至上GB;存算分离从对象存储拉数据,单连接吞吐通常只有几十MB每秒,要用多线程并发拉取才能把带宽跑满。这意味着,纯Scan型作业在存算分离下大概率会变慢。
但我做了这么多项目,发现一个规律:真正让作业慢到不能接受的,不是Scan,是Shuffle。Shuffle本身就是把数据从map端拉到reduce端,这个过程在存算分离下最容易垮掉——因为map端的中间数据要么写在本地,要么写在远端存储,一旦中间结果过大、远端读写频繁,整个作业就会陷入IO泥潭。解决方法是尽量在计算节点本地完成Shuffle,不要让中间数据落到远端。Spark的spark.shuffle.storagePath可以指定为本地目录,务必检查这个配置。
另外,对象存储的读性能是“并发友好”的,也就是说,通过100个并发去读100个文件,比1个并发读100个文件要快得多。所以优化思路不是靠单线程猛拉,而是提高任务并行度。把文件多、大小均匀的数据集让Spark用repartition或coalesce合理重分区,让每个task处理的数据量均衡,整个作业吞吐就会明显改善。
4.3 缓存层与读写优化:一个能回本的关键点
关于缓存,我多说一点。很多人上了存算分离之后发现“比原来慢了一倍”,第一反应是退回去。其实慢的场景大多出在重复读数据上——同一个报表任务每天跑一次,每天都要从对象存储拉几GB的维度数据,这当然慢。加一层分布式缓存,把这些数据固定在计算集群本地,第二次之后的访问延迟直接从秒级变成毫秒级。
Alluxio是我用得最多的方案。它的部署逻辑是在计算集群和存储之间插一层:计算任务先找Alluxio,命中了就直接读本地,没命中就去底层存储拉,同时缓存到本地。配置起来也不复杂,在Spark的SPARK_HOME/conf里加上几个配置项就能接入。
# Spark接入Alluxio缓存层的配置示例 spark.driver.extraClassPath /alluxio/client/alluxio-2.8.0-client.jar spark.executor.extraClassPath /alluxio/client/alluxio-2.8.0-client.jar spark.hadoop.fs.alluxio.impl alluxio.hadoop.FileSystem spark.sql.parquet.fs.optimized.commons.ignore true如果你不想引入额外组件,也有一个土办法:把热表的查询结果物化成聚合表,放在HDFS或者云盘上,应用只查聚合表,不查原始数据。这个“以预计算换查询性能”的思路在存算分离架构下特别管用,本质上是用存储分层来对冲性能损耗。
5. 常见问题与排查技巧实录
5.1 小文件导致的对象存储吞吐量剧烈下降
这是存算分离项目里碰到概率最高的问题,没有之一。对象存储的List操作性能很差,而Spark/Hive在作业规划阶段都需要做目录扫描、文件列举。一旦你的表里有几万个小文件,光列文件就能耗掉几分钟,任务还没开始跑就已经输在起跑线上了。
我遇到过最极端的一个案例:一张订单明细表因为上游flume按分钟落盘,一天产生了超过8万个JSON小文件。用Hive跑一个简单的count查询,从提交到出结果花了40分钟,其中35分钟都耗在文件列装上。排查的思路是先在Spark UI里看SQL的Physical Plan耗时,然后去对象存储控制台查目录的文件数量,确认是小文件问题。解决方案也很暴力:先写一个合并任务把这些小文件读出来,重分区后重新写成大的Parquet文件,原来8万个文件合并成了300个,同一个count查询从40分钟降到了不到3分钟。
经验法则:ODS层可以允许小文件存在(毕竟是原始数据),但DWD层和ADS层必须严格控制文件数量和大小。建议每天用一个小文件合并的定时任务做兜底。
5.2 元数据热点与目录热点:Rename操作的暗坑
存算分离架构下,元数据服务承担的压力会成倍增长。一体机架构里,NameNode或者Metastore主要服务一个集群的作业;存算分离后,多个计算集群、多个业务方共享同一份元数据,任何抖动都会被放大。
我遇到过的具体问题是:每天零点跑批高峰期,Metastore的连接数暴涨,出现大量Lock wait timeout exceeded报错。查了半天,发现是多个任务同时往同一个分区目录写数据,产生了元数据锁竞争。这类问题不是存储本身的问题,而是对共享元数据的访问设计不合理。
排查和解决建议:
- Metastore启用在线的HA模式,用负载均衡分发请求。
- 建表时避免使用“一个表一个分区一个目录”的极端设计,分区粒度要合理(比如按天分区,而不是按小时分区)。
- 任务写入时使用
INSERT OVERWRITE而不是INSERT INTO,减少元数据变更频率。 - 关注Metastore后端的数据库连接池和慢查询日志,这个层级的瓶颈通常不在Metastore服务本身,而在它的数据库。
5.3 数据质量检查框架在存算分离下的设计思路
说到大数据质量检查,很多团队在做存算分离的时候会忽略这一块,导致数据链路搬过去了,质量保障体系没跟上。我自己是把数据质量检查框架做成了独立于计算集群的一套任务,它本身也跑在弹性计算资源上,定期对Hive/Spark表做校验。
存算分离架构下,质量检查有几个不同的地方:
第一,检查任务要尽量轻量。不要用大查询全表扫描的方式校验,而是通过元数据统计信息(表行数、文件数、分区大小)做粗粒度校验,再抽样做细粒度校验。全表扫描产生的成本在对象存储计费模式下是实实在在的钱。
第二,对账逻辑要分层。ODS层检查数据量和上游源的一致性,DWD层检查主键唯一性、非空约束、枚举值合法性,ADS层检查指标波动范围和环比变化。每一层各司其职,避免把所有校验都压到最底层。
第三,异常要能自动定位到分区和文件。存算分离的数据路径往往是bucket/表名/分区/文件的层级,质量检查框架在发现异常时,要能输出具体的分区和文件路径,方便快速隔离问题数据、重跑对应分区任务。
我还建议在质量检查框架中内置一个“成本监控”模块,记录每次校验任务扫描了多少数据、消耗了多少对象存储请求。别小看这个模块,它能帮你发现那些“每天都在做全表扫描”的隐藏任务,这些往往是存算分离账单里最大的黑天鹅。
6. 什么场景适合存算分离,什么场景千万别跟风
6.1 适合的:弹性需求明显的分析负载、多云/混合云、降本诉求明确
讲了这么多,最后说点大实话。不是所有大数据平台都适合存算分离,但它确实在几类场景下特别有价值。
第一类,计算负载有明显峰谷差的分析型平台。比如BI报表、离线数仓、用户行为分析,白天高峰、夜间低谷,用弹性计算集群配合统一存储底座,是天然匹配的。
第二类,多云/混合云架构。数据放在一个公共存储桶里,多个云厂商的计算集群都能访问同一份数据。这样既避免了数据迁移的麻烦,又能充分利用各个云厂商的差异化算力价格。
第三类,降本诉求明确的成熟业务。老集群扩容成本越来越高、数据量还在涨,存算分离能把存储和计算的成本拆开,让每一分钱都花在刀刃上。如果CTO给你下的KPI就是“成本降30%”,优先考虑存算分离是合理的。
6.2 不适合的:实时高并发、强本地性依赖、小规模集群
也有一些场景,我个人不建议强行上存算分离。
实时高并发查询场景,比如数据服务层对外提供毫秒级API,存算分离的网络开销无法满足低延迟要求。这种场景老老实实用本地SSD+缓存,或者直接用OLAP引擎,别跟风。
强本地性依赖的场景,比如大量机器学习训练任务,需要反复迭代读取同一份数据集,每轮迭代都从远端拉数据,代价实在太高。除非你愿意在计算集群里配大容量本地盘做全量缓存,否则不建议分离。
还有就是小规模集群——一两台机器、几个GB数据量的场景。存算分离的存储底座至少需要一套基础设施支撑,小集群本身资源就紧张,再分出网络开销来,反而得不偿失。数据量没到一定规模,一体机依然是最务实的选择。
6.3 我踩过几次坑之后的真实体会
如果让我给一个做技术选型决策的人一句建议,那就是:存算分离不一定是性能更优的方案,但它在成本、弹性、治理这几个维度上的优势,值得每一个大数据团队认真评估。我的体会是,做存算分离最忌讳的就是“一刀切”——不是所有表、所有任务都要搬过去,而是要按数据温度分层、按业务场景区别对待。热数据留在高性能存储,冷数据放对象存储,计算资源按需拉起,这样才能真正吃到存算分离的红利。
对于正在规划大数据学习路线或者准备做技术方案选型的人来说,我的建议也很直接:不要只看存算分离这个概念本身,要上手去跑一个完整的项目,从数据采集、清洗、分析到可视化,完整走一遍,体会一下两种架构的差异。踩坑之后建立起来的判断力,比任何博客和文档都更有价值。