千萬級資料優化記錄

2022-01-15 14:18:31 字數 1571 閱讀 4416

每個動作都會生產一條動態資料,如今已經生成了一千多萬條資料,而且正以每天好幾萬的速度迅速增長,頻繁的讀寫導致 rds 資料庫例項壓力非常大,該庫還有核心業務的資料,為了避免對核心資料的影響,決定將其分出來。

結合其業務特點,決定使用 mongdb,那麼第乙個問題就是如何同步這些資料了。

不能停止服務,還不能影響業務,所以選擇通過 sql server 的 cdc 功能進行同步,先不用更改運算元據的**,繼續往 sql server 中寫入,再將資料同步到 mongodb,然後把查詢的改用 mongodb, 最後把運算元據的業務改用 mongodb,如此即可實現資料的無縫遷移。當萬事俱備的時候,發現阿里雲的 rds 例項需要 sa 許可權才能開啟 cdc, 而使用者是沒有 sa 許可權的,因此不得已只好放棄這個方案。

為了實現高速換輪胎,我們找到了另乙個解決方案,通過給每行記錄datemodified時間,但是這樣就需要先更改業務**,在每次增刪改中記錄操作時間,這個工作量是有難度的,因為有兩個版本的 api 在不同的環境中執行的,修改**不難,難的是需要在不同的環境中測試,保證線上業務不能崩潰,這個成本是比較高的。就在游移不定的時候,發現了 sql server 的timestamp型別,它是乙個連續的數字,在增改的時候自動更新值,如此就不用更改業務**了,直接在表中增加乙個timestamp型別的字段即可,然後按照該欄位datemodified進行同步資料即可。

嘗試使用了 alibaba 開源的 datax,結果發現對guid型別的支援不是很好,無法滿足我們的需求,因此果斷放棄,還是自己來寫**實現。

大概思路如下,同步程式只需要從 sql server 中select出來,同步到 mongodb 中,記錄一下這次同步的最大timestamp,隔一分鐘後繼續重複,即使遇到異常,也只要記錄一下,不能中斷程式。 最好不要通過datareader去讀,因為資料量大會長時間占用資料庫鏈結。

當然,還要對datemodified欄位建索引,否則同步速度會很慢。索引要在訪問量低谷的時候建,不能影響線上效能。

使用geneichost方式的控制台程式,命名為feeds.syncer,部署在 mongodb 所在的伺服器,只能跑乙個例項,防止多個同步出現衝突。

當資料同步完成之後,就可以逐步將資料操作轉移到 mongodb 了,這一步不著急,可以慢慢來。

接下來最重要的是將查詢業務改成從 mongodb 查詢,業務邏輯都改完之後,發現查詢速度比 sql server 還慢,原來 mongodb 也是需要建索引的,而且索引功能非常強大,從官方文件中可以看到它支援各種索引,復合的,條件的,聯合的等等,分別針對不同的場景。

針對我們的業務場景準備好要建的索引,mongodb 提供了方法來判斷查詢是否用到了索引,和 sql server 的查詢計畫有點類似,據此可以判斷索引是否建對了。直接建立索引可能會對效能產生影響,所以要分而治之,依次對 mongodb 集群中的例項停止,獨立執行,建立索引,停止,新增到集群中執行。

有了索引加持後,果然查詢速度就有了明顯的改善。

oracle千萬級資料查詢優化

需求 組合查詢,按條件統計某幾個欄位取前100條記錄 問題 沒建索引導致查詢結果耗時5秒多,不能忍受。解決方法 建索引,在哪個欄位建?在這裡先提下oracle的sql語句的執行。oracle在執行sql語句之前會用優化器optimizer對sql語句進行解析,解析出最優的執行計畫再執行,這樣所花費的...

千萬級 百萬級資料刪除優化

在mysql上面刪除大量資料 千萬級 由於不是清空資料,故不能使用truncate 語句 有個truncate可參考 mysql delete語句與truncate table語句 在正常delete下,刪除十分緩慢 由於索引的原因,每次刪除都要相應的更新索引,越往後索引碎片越多,即越往後越慢 完整...

千萬級 百萬級資料刪除優化

在mysql上面刪除大量資料 千萬級 由於不是清空資料,故不能使用truncate 語句 有個truncate可參考 mysql delete語句與truncate table語句 在正常delete下,刪除十分緩慢 由於索引的原因,每次刪除都要相應的更新索引,越往後索引碎片越多,即越往後越慢 完整...