“存算分離”(Decoupled Storage and Compute)是一種在現代數據系統中被廣泛采用的架構設計。它將計算和存儲解耦,使二者可以獨立擴展,提升資源利用率并降低運維成本。StarRocks 從 3.0 版本開始支持這一架構,允許用戶將數據存儲從計算節點中剝離,實現更靈活、彈性的系統部署。
在這種架構中,計算層由數據庫引擎負責,存儲則交由對象存儲系統承擔。對象存儲的實現方式有很多,包括各大公有云廠商提供的服務以及一些開源方案。我們在本文中選擇 MinIO 作為示例,是因為它開源、高性能、支持 S3 協議,并且非常適合用于本地測試或私有部署。
MinIO 和 StarRocks 的組合正是存算分離架構的一個實踐案例。MinIO 提供可靠的對象存儲能力,StarRocks 專注于查詢加速與計算優化,二者結合,在實時和離線分析場景下都能提供良好的性能表現與靈活性。
此外,兩者都支持 Kubernetes 原生部署,可以輕松集成到現代云原生平臺中。用戶無需綁定特定云廠商,也可以通過簡單的 YAML 文件,在本地或云上快速搭建和演進整個數據平臺。這種部署模式對于開發測試、混合云、邊緣計算等場景尤其友好。
下面我們將提供一份實踐教程,介紹如何使用 MinIO 作為主存儲,配合 StarRocks 構建起一套完整的數據分析環境。如需詳細的配置說明,可參考文末鏈接至 StarRocks 官方文檔。
存算分離架構的優勢
在引入存算分離架構的同時,StarRocks 也提供了本地緩存機制,用于降低遠程對象存儲訪問頻次,從而提高數據讀取性能,緩解網絡瓶頸。整體優勢包括:
-
成本控制:計算和存儲資源可獨立擴展,按需配置,避免資源浪費;
-
部署靈活:可根據業務場景自由組合不同的計算與存儲系統;
-
彈性擴展:適配動態負載需求,計算與存儲節點可分別擴容;
-
查詢性能優化:結合本地緩存機制,提升對熱點數據的訪問效率;
-
可維護性更高:工作負載可在不同資源池之間遷移,方便運維管理;
-
資源隔離更清晰:適用于多租戶、不同業務線的資源劃分需求。
快速開始
接下來你將學到如何在 Docker 容器中運行 StarRocks 和 MinIO,配置 StarRocks 以使用共享存儲,加載兩個公開數據集,并使用 SQL 進行數據探索。
前置條件
你需要安裝:
-
curl:用于下載 YAML 和數據文件;
-
Docker Compose:推薦直接安裝 Docker Desktop,它包含了 Docker Engine 和 Compose;
-
驗證安裝情況:
docker compose version
-
SQL 客戶端:比如 DBeaver 或 MySQL CLI。
本教程中的 MySQL 實例可以通過 MySQL CLI 訪問,因此不需要額外依賴。當然,你也可以下載 DBeaver 或 MySQL Workbench 來獲得更好的使用體驗。
開始使用
-
創建工作目錄并下載 Docker Compose 文件:
mkdir sr-quickstart
cd sr-quickstart
curl -O https://raw.githubusercontent.com/StarRocks/demo/master/documentation-samples/quickstart/docker-compose.yml
-
使用以下命令讓 Docker Compose 在后臺啟動
docker-compose.yml
文件中定義的所有容器:
docker compose up -d
MinIO 設置
你可以通過 MinIO 控制臺或使用 mc
來操作 MinIO。以下截圖和說明基于 MinIO 控制臺。
打開瀏覽器訪問:http://localhost:9001/access-keys。用戶名和密碼在 Docker Compose 文件中已配置,默認是 minioadmin:minioadmin
。
點擊 “Create access key +”,然后點擊 “Create”。
連接 SQL 客戶端(以 DBeaver 為例)
你需要連接到一個 SQL 客戶端來操作數據。你可以選擇使用 DBeaver。在 DBeaver 中創建一個新的數據庫連接,然后選擇 MySQL 數據庫驅動:
-
端口:9030
-
地址:localhost
-
用戶名:root
測試連接成功后點擊 Finish。
或者你更習慣使用命令行,也可以在 starrocks-fe
容器中使用 MySQL CLI。要連接到 StarRocks,請進入包含 docker-compose.yml
的目錄,并運行以下命令:
docker compose exec starrocks-fe \
mysql -P9030 -h127.0.0.1 -uroot --prompt="StarRocks > "
創建 Bucket
在你的 SQL 客戶端中運行以下命令,確保使用你之前在 MinIO 控制臺中創建的 Access Key 和 Secret:
CREATE STORAGE VOLUME shared
TYPE = S3
LOCATIONS = ("s3://starrocks/shared/")
PROPERTIES
("enabled" = "true","aws.s3.endpoint" = "http://minio:9000","aws.s3.use_aws_sdk_default_behavior" = "false","aws.s3.enable_ssl" = "false","aws.s3.use_instance_profile" = "false","aws.s3.access_key" = "{你的 Access Key}","aws.s3.secret_key"= "{你的 Secret Key}"
);
SET shared AS DEFAULT STORAGE VOLUME;
訪問 http://localhost:9001/buckets,確認名為 starrocks
的 bucket 是否已成功創建。
下載數據
在終端中運行以下命令,打開 starrocks-fe
容器中的 Bash shell,這樣你就可以訪問容器的文件系統并在其中執行命令:
docker compose exec starrocks-fe bash
運行以下命令,在容器內創建一個 quickstart
目錄:
mkdir quickstart
cd quickstart
接著運行以下命令,將兩個數據集下載到剛剛創建的文件夾中:
curl -O https://raw.githubusercontent.com/StarRocks/demo/master/documentation-samples/quickstart/datasets/NYPD_Crash_Data.csv
curl -O https://raw.githubusercontent.com/StarRocks/demo/master/documentation-samples/quickstart/datasets/72505394728.csv
創建數據庫與表
在使用 SQL 客戶端連接到 StarRocks 的終端窗口中,看到 StarRocks >
提示符后,運行以下命令。
CREATE DATABASE IF NOT EXISTS quickstart;
USE quickstart;
你的終端應該類似如下所示:
StarRocks > CREATE DATABASE IF NOT EXISTS quickstart;
Query OK, 0 rows affected (0.02 sec)
StarRocks > USE quickstart;
Database changed
StarRocks >
在 SQL 客戶端中創建表
返回 DBeaver 或你選擇的其他 SQL 客戶端,執行以下命令為數據創建表:
USE quickstart;
CREATE TABLE IF NOT EXISTS crashdata (CRASH_DATE DATETIME,BOROUGH STRING,ZIP_CODE STRING,LATITUDE INT,LONGITUDE INT,LOCATION STRING,ON_STREET_NAME STRING,CROSS_STREET_NAME STRING,OFF_STREET_NAME STRING,CONTRIBUTING_FACTOR_VEHICLE_1 STRING,CONTRIBUTING_FACTOR_VEHICLE_2 STRING,COLLISION_ID INT,VEHICLE_TYPE_CODE_1 STRING,VEHICLE_TYPE_CODE_2 STRING
);
CREATE TABLE IF NOT EXISTS weatherdata (DATE DATETIME,NAME STRING,HourlyDewPointTemperature STRING,HourlyDryBulbTemperature STRING,HourlyPrecipitation STRING,HourlyPresentWeatherType STRING,HourlyPressureChange STRING,HourlyPressureTendency STRING,HourlyRelativeHumidity STRING,HourlySkyConditions STRING,HourlyVisibility STRING,HourlyWetBulbTemperature STRING,HourlyWindDirection STRING,HourlyWindGustSpeed STRING,HourlyWindSpeed STRING
);
加載數據
切換到你之前下載數據集的終端,在 starrocks-fe
容器中的 shell 中執行以下 curl
命令。當提示輸入密碼時,直接按回車鍵即可。
curl --location-trusted -u root \-T ./NYPD_Crash_Data.csv \-H "label:crashdata-0" \-H "column_separator:," \-H "skip_header:1" \-H "enclose:\"" \-H "max_filter_ratio:1" \-H "columns:tmp_CRASH_DATE, tmp_CRASH_TIME, CRASH_DATE=str_to_date(concat_ws(' ', tmp_CRASH_DATE, tmp_CRASH_TIME), '%m/%d/%Y %H:%i'),BOROUGH,ZIP_CODE,LATITUDE,LONGITUDE,LOCATION,ON_STREET_NAME,CROSS_STREET_NAME,OFF_STREET_NAME,NUMBER_OF_PERSONS_INJURED,NUMBER_OF_PERSONS_KILLED,NUMBER_OF_PEDESTRIANS_INJURED,NUMBER_OF_PEDESTRIANS_KILLED,NUMBER_OF_CYCLIST_INJURED,NUMBER_OF_CYCLIST_KILLED,NUMBER_OF_MOTORIST_INJURED,NUMBER_OF_MOTORIST_KILLED,CONTRIBUTING_FACTOR_VEHICLE_1,CONTRIBUTING_FACTOR_VEHICLE_2,CONTRIBUTING_FACTOR_VEHICLE_3,CONTRIBUTING_FACTOR_VEHICLE_4,CONTRIBUTING_FACTOR_VEHICLE_5,COLLISION_ID,VEHICLE_TYPE_CODE_1,VEHICLE_TYPE_CODE_2,VEHICLE_TYPE_CODE_3,VEHICLE_TYPE_CODE_4,VEHICLE_TYPE_CODE_5" \-XPUT http://localhost:8030/api/quickstart/crashdata/_stream_load
curl --location-trusted -u root \-T ./72505394728.csv \-H "label:weather-0" \-H "column_separator:," \-H "skip_header:1" \-H "enclose:\"" \-H "max_filter_ratio:1" \-H "columns: STATION, DATE, LATITUDE, LONGITUDE, ELEVATION, NAME, REPORT_TYPE, SOURCE, HourlyAltimeterSetting, HourlyDewPointTemperature, HourlyDryBulbTemperature, HourlyPrecipitation, HourlyPresentWeatherType, HourlyPressureChange, HourlyPressureTendency, HourlyRelativeHumidity, HourlySkyConditions, HourlySeaLevelPressure, HourlyStationPressure, HourlyVisibility, HourlyWetBulbTemperature, HourlyWindDirection, HourlyWindGustSpeed, HourlyWindSpeed, Sunrise, Sunset, DailyAverageDewPointTemperature, DailyAverageDryBulbTemperature, DailyAverageRelativeHumidity, DailyAverageSeaLevelPressure, DailyAverageStationPressure, DailyAverageWetBulbTemperature, DailyAverageWindSpeed, DailyCoolingDegreeDays, DailyDepartureFromNormalAverageTemperature, DailyHeatingDegreeDays, DailyMaximumDryBulbTemperature, DailyMinimumDryBulbTemperature, DailyPeakWindDirection, DailyPeakWindSpeed, DailyPrecipitation, DailySnowDepth, DailySnowfall, DailySustainedWindDirection, DailySustainedWindSpeed, DailyWeather, MonthlyAverageRH, MonthlyDaysWithGT001Precip, MonthlyDaysWithGT010Precip, MonthlyDaysWithGT32Temp, MonthlyDaysWithGT90Temp, MonthlyDaysWithLT0Temp, MonthlyDaysWithLT32Temp, MonthlyDepartureFromNormalAverageTemperature, MonthlyDepartureFromNormalCoolingDegreeDays, MonthlyDepartureFromNormalHeatingDegreeDays, MonthlyDepartureFromNormalMaximumTemperature, MonthlyDepartureFromNormalMinimumTemperature, MonthlyDepartureFromNormalPrecipitation, MonthlyDewpointTemperature, MonthlyGreatestPrecip, MonthlyGreatestPrecipDate, MonthlyGreatestSnowDepth, MonthlyGreatestSnowDepthDate, MonthlyGreatestSnowfall, MonthlyGreatestSnowfallDate, MonthlyMaxSeaLevelPressureValue, MonthlyMaxSeaLevelPressureValueDate, MonthlyMaxSeaLevelPressureValueTime, MonthlyMaximumTemperature, MonthlyMeanTemperature, MonthlyMinSeaLevelPressureValue, MonthlyMinSeaLevelPressureValueDate, MonthlyMinSeaLevelPressureValueTime, MonthlyMinimumTemperature, MonthlySeaLevelPressure, MonthlyStationPressure, MonthlyTotalLiquidPrecipitation, MonthlyTotalSnowfall, MonthlyWetBulb, AWND, CDSD, CLDD, DSNW, HDSD, HTDD, NormalsCoolingDegreeDay, NormalsHeatingDegreeDay, ShortDurationEndDate005, ShortDurationEndDate010, ShortDurationEndDate015, ShortDurationEndDate020, ShortDurationEndDate030, ShortDurationEndDate045, ShortDurationEndDate060, ShortDurationEndDate080, ShortDurationEndDate100, ShortDurationEndDate120, ShortDurationEndDate150, ShortDurationEndDate180, ShortDurationPrecipitationValue005, ShortDurationPrecipitationValue010, ShortDurationPrecipitationValue015, ShortDurationPrecipitationValue020, ShortDurationPrecipitationValue030, ShortDurationPrecipitationValue045, ShortDurationPrecipitationValue060, ShortDurationPrecipitationValue080, ShortDurationPrecipitationValue100, ShortDurationPrecipitationValue120, ShortDurationPrecipitationValue150, ShortDurationPrecipitationValue180, REM, BackupDirection, BackupDistance, BackupDistanceUnit, BackupElements, BackupElevation, BackupEquipment, BackupLatitude, BackupLongitude, BackupName, WindEquipmentChangeDate" \-XPUT http://localhost:8030/api/quickstart/weatherdata/_stream_load
完成后,返回瀏覽器訪問 http://localhost:9001,確認數據是否已成功上傳到 MinIO。
查詢數據
回到你的 SQL 客戶端,我們來對剛才加載的數據運行一些查詢。首先,我們通過查詢來了解降水、交通事故與星期幾/時間之間的關系:
SELECT COUNT(DISTINCT c.COLLISION_ID) AS Crashes,TRUNCATE(AVG(w.HourlyDryBulbTemperature), 1) AS Temp_F,MAX(w.HourlyPrecipitation) AS Precipitation,DATE_FORMAT(c.CRASH_DATE, '%d %b %Y %H:00') AS Hour
FROM crashdata c
LEFT JOIN weatherdata w
ON DATE_FORMAT(c.CRASH_DATE, '%Y-%m-%d %H:00:00') = DATE_FORMAT(w.DATE, '%Y-%m-%d %H:00:00')
WHERE DAYOFWEEK(c.CRASH_DATE) BETWEEN 2 AND 6
GROUP BY Hour
ORDER BY Crashes DESC
LIMIT 200;
開放表格式+對象存儲實踐
最后,我們再放上 StarRocks x Apache Iceberg/Hudi x MinIO 的視頻 demo,只要短短幾分鐘就可以完成數據入湖到可視化:
-
Apache Iceberg:https://www.bilibili.com/video/BV1ET42167TY/
-
Apache Hudi:https://www.bilibili.com/video/BV1G45PzHEuF/