數據倉庫解決方案 - RedShift 入坑指南

最近工程師小謝遇到了一個難題, 就是手頭上有千萬級別的數據, 但是沒有一個快糙猛的解決方案。

提出問題

想直接看 RedShift 相關的, 請跳過前兩節瞎扯淡。 直接到第三節觀看。

不像少部分優秀的可以活在彼岸的人, 可以醉心於寫出完美的資料庫, 在須臾間學會所有的程序語言; 世上大部分程序員都活在此岸, 他們要解決一個個特定的業務問題。

工程師小謝就很煩惱, 上次產品經理小劉提了個老酷炫的IDEA:「現金牛」。 觀眾們很過癮, 但作為要實現功能的人, 小謝有點鬱悶。

具體來說,難點在下面幾個:

  1. 數據量很大。 公司是做菜品相關的,每天記錄的菜品數據非常多。 而且隨著公司業務發展,菜品增速增長率也很高。 (也就是「指數級上升」)
  2. 時間比較緊。 不像學校里的大作業,可以有一整個學期來實現到交付。 真正的需求是事情要儘可能早的完成,即使一開始不一定是完美的, 但是會更早得到外部反饋,正面/負面的評價有助於大家調整前進方向。
  3. 質量有要求。 基於「現金牛」的這個需求交付完成以後,又會有新的需求降臨到小謝的肩上。 所以這個此時的解決方案,也要解決彼時的問題。 隨著業務/數據量的增大,短時間內(比如說一年),解決方案得穩定靠譜。 長時間內(比如說三年),解決方案要能拓展,至少是便於重構的。

解決方案

上面的幾個現世問題, 其實跟萬千現世問題一樣, 都是一個問題:如何在有限的資源下,完成既定的目標? 解決方案也都是通用的:轉換資源、付出時間、更換目標。

當然,小謝明白,脫離實際例子的方法論都沒有意義。 所以小謝打算整一個數據倉庫 (Data Warehouse)

數據倉庫,跟資料庫 (DataBase) 很像, 就像軍械庫是放軍械的地方, 車庫是放車的地方, 數據倉庫/資料庫就是放數據的地方。 多了個倉是因為還放倉鼠

二者不同之處詳細來說, 就是因為要解決的問題不一樣: 資料庫是要給業務提供基礎保證, 數據倉庫則是給面向決策的數據分析提供便利; 所以二者的設計思想也不一樣: 資料庫遵守範式設計,強調數據約束、一致性,讀寫操作都有涉及, 數據倉庫則是存儲大量冗餘數據、統計數據,對讀的優化更多。

舉個栗子就是今天中午小謝去吃了四斤烤魚(真能吃), 「四斤烤魚」的數據存在了資料庫里,是用來買單算錢的。 但「今天中午,四斤,烤魚」這樣的統計數據就存在了數據倉庫里, 以用來之後的統計分析。

業界很多的數據倉庫都是基於 Hadoop/Spark/Storm 的一套 Java 系技術棧的。 比如拼多多,用的就是 Hadoop/Hive/HBase/Kafka 一套技術棧。 比如小紅書,用的也是 Hadoop/Hive/Spark/Kafka 一套技術棧。

但是問題來了: 這些小謝都不懂啊,很尷尬。 不過還好,小謝有錢, 他可以去招幾個懂的。 很可惜,招聘是個玄學問題, 他看上的看不上他, 看上他的他看不上。

於是小謝想來想去, 也只能自己動手, 最終選擇了:

RedShift, 亞馬遜雲服務全家桶 之 數據倉庫 管理助手

特點

作為一種數據倉庫的解決方案, RedShift 有幾個特點:

  • 省事,假如你也用了 AWS 的其它服務。 自帶監控,需要定製化的話還可以跟 AWS CloudWatch 結合; 往裡面插入數據推薦用的 COPY 命令是和 AWS S3 聯動的; 高可用、拓展性、備份等都是 AWS 保證的。
  • 提供全套 PostgreSQL 語法。 基本上兼容 PostgreSQL 的地方,換一下 DBDriver 就可以無痛使用了。 但是 RedShift 也只提供了一套 SQL 的標準, 假如要做 SQL 之外的(比如文件)數據存放, 就很吃力了。by design. wontfix
  • 貴,相對而言。 定價大概最便宜的實例類型 (dc1.large, 15GB Mem, 0.16TB SSD) 是一年一萬多人民幣, 不算人力價格的話,比自建數據倉庫肯定要貴。 不過算上人力價格的話……就另說了。

部署

部署使用 RedShift 的主要步驟如下:

  1. 先別急著創建實例,先按照 AWS 的教程走一遍, 會對 COPY/Encoding/Cluster 有初步了解。 不喜歡讀英文文檔的同學,可以右上角切換成中文
  2. 創建合適的 AWS RedShift 實例。 恭喜你完成了_從無到有搭建數據倉庫_這個成就。
  3. 對接業務,比如選擇合適的 Driver。 我們用的是 django, 直接用 psycopg2 就可以連接了。 然後就是ETL、緩存、圖表等通用的業務操作了。

小心得

用了 RedShift 一陣子, 有幾點學到的地方:

  • SQL 語句不是直接執行,而是編譯後分發執行

不論我們執行任何語句,即使是 INSERT INTO 這種單條操作, RedShift 都要編譯後執行,耗時 500ms 起步_所以要用COPY來做數據導入_。 又比如我們部署了四個 RedShift 節點,那在 SELECT * FROM orders WHERE business_id = 100 編譯完成以後, RedShift 會把操作根據建表時選定的分區鍵 DISTKEY 把命令分發到各個節點操作。 所以合理的表結構也是查詢速度的關鍵_通用的廢話真理_。

  • 插入數據用 COPY 命令;更新數據 COPY 到臨時表以後,用 DELETE USING + INSERT INTO 來更新數據

因為每條 SQL 都要編譯,所以盡量做批量操作,單條操作是非常愚蠢的。 (就像我們最開始那麼愚蠢一樣=_=) RedShift COPY 命令支持 GZIP, JSON, From S3 等多種操作, 大部分情況下,載入速度和存儲效率都會比普通的 INSERT 要好。 同理,更新單條數據採用了先刪再增的方式。

  • 定時維護數據倉庫

RedShift 不會自動回收 DELETE/UPDATE 所釋放的空間, 需要用戶手動運行 VACUUM 命令來清理表。 VACUUM本身也是IO密集型操作, 所以最好是在空閑的時間(比如早上四點)定時跑。

  • 注意表的限制

在 RedShift 里, unique / primary key / foreign key都是展示信息, 沒有實質約束力。

還有 RedShift.varchar 存儲的是單位元組字元, 像 MySQL 的 utf8 默認是三位元組字元, 假如用了 utf8mb4 就是四位元組字元。 所以 MySQL 里的 varchar(50) 換算到 RedShift 里就應該是 varchar(200)。 被Emoji坑了的人留

總結

總的來說, RedShift 的最大的好處在於用錢換取生產力, 簡單易用,是 AWS 全家桶用戶對數據倉庫的一種解決方案。 具體用法多加註意,也沒有什麼特別之處。

不過最近好像是給亞馬遜交了不少錢, 他們都派工程師上門免費 support 了。

小謝心想。

課外閱讀

  • AWS - RedShift 官方教程 - http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/tutorial-tuning-tables.html
  • 酷殼 - 由12306.CN談談網站性能技術 - https://coolshell.cn/articles/6470.html
  • 維基百科 - 數據倉庫 - https://en.wikipedia.org/wiki/Data_warehouse
  • 全面了解mysql中utf8和utf8mb4的區別 - https://my.oschina.net/xsh1208/blog/1052781
  • 西喬 - 歷史悲劇 - http://blog.xiqiao.info/2013/01/14/1366
  • 拼多多的JD在飲水思源BBS找的,小紅書的JD在拉勾上找的

推薦閱讀:

Redshift The Irradiance Point Cloud GI Engine輻射點雲GI
Redshift System
Redshift for C4D中文說明——無限背景的製作
Redshift for C4D中文說明——材質混合的一些方法

TAG:数据仓库 | redshift | 后端技术 |