日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

MySql分区表性能测试及切换案例

發布時間:2023/12/20 编程问答 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 MySql分区表性能测试及切换案例 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

背景

互聯網公司的業務變化很快,數據庫表結構設計相對比較直接,很少會在前期設計的很完善。當業務存活并發展起來后,就需要在擴展性、安全性等方面進行改進。

比如,我們一張記錄用戶狀態的表,存儲在RDS for MySql(InnoDB存儲引擎)中。此業務表最近膨脹到1.5億條記錄,存儲占用30多G,且數據還在不斷增長。

雖然目前整體性能表現尚可,但部分操作耗時越來越長,鎖表沖突事件也開始出現??紤]到數據量的快速增長,以及數據庫本身的雪崩特點,我們認為這張表存在很大的性能風險,急需優化。

性能分析

下面我們深入分析MySql InnoDB表數據量大小對CRUD及DDL操作的性能影響:

  • 插入數據:由于使用自增列作為主鍵(大數據表比較推薦這種方式,索引占用存儲空間會大幅減少),增加業務數據的消耗時間為O(1)。但由于各索引數據需要排序,因此增加索引數據的消耗時間為O(logN);
  • 查詢數據:如果通過索引查詢,消耗時間為O(logN);如果不通過索引查詢,消耗時間為O(N);
  • 刪除數據:消耗時間與查詢數據表現一致,但需要特別注意鎖的問題。雖然我們經常說InnoDB是行鎖,但這種說法是針對MyISAM的表鎖而言。實際上,InnoDB的“行鎖”是“索引鍵鎖”,其鎖機制的實現是基于索引鍵實現的。如果刪除數據時沒有匹配到索引鍵,或即使匹配上索引鍵,但如果索引鍵匹配的數據記錄過多,依然會導致大范圍加鎖從而引起訪問沖突,極大的降低系統性能;
  • 更新數據:消耗時間和加鎖分析基本與刪除數據一致,只是多了個索引的重排序;
  • DDL操作:MySql 從5.6開始支持在線DDL操作。其原理是進行DDL操作前,將原始數據文件拷貝到新文件中,然后執行DDL操作。同時,將DML操作日志存儲到緩存中,待DDL執行完成后再執行到新的數據文件中。那么,當表數據量較大時,數據文件拷貝時間必然較長,如果這期間存在大量的DML操作,超過緩存上限,則DDL操作會失敗。
  • DML(Data Manipulation Language),數據操縱語言,包括UPDATE、INSERT、DELETE,表示對數據記錄層面的操作
  • DDL(Data Definition Language),數據定義語言,主要包括CREATE、ALTER、DROP等,表示對表結構層面的操作

優化方案

通過上面的分析,我們可以看出,InnoDB表數據量過大對各種操作都存在較大的性能影響。針對這些問題,有以下三種優化方案:

將此業務表切換到分布式數據庫產品中

此方案最簡單直接。但我們的業務中,只有此表數據量較大且需要查詢詳細單據。僅為了一張表就引入一種存儲機制,考慮到運維和經濟成本,總覺得不劃算。另外,此表還與其他表有一定的聯合查詢操作,分離出去后會增加應用層的復雜度;

對此業務表分庫分表

分庫分表是處理大數據表的利器。但我們數據庫系統的CPU和IO資源很富余(CPU僅10%,IOPS僅300多),完全沒有分庫的必要。而分表會使得應用層的修改工作量巨大,代碼的可讀性也會變差。如果為了業務層的邏輯清晰再引入中間件進行代理訪問,又有殺雞用牛刀之感;

使用MySql自帶的分區表

分區表是MySql 5.1引入的特性。根據官網alter-table-partition-operations的介紹,其本質是將分庫分表直接集成到MySql中。我們知道,傳統的分庫分表功能,存在業務層、中間件、數據庫三層:業務層通過調用中間件的API訪問數據庫,不知道具體的物理存儲細節;中間件將一張很大的邏輯表映射到數據庫中多張較小的物理表,并對業務層的訪問請求進行分解后分別放到對應物理庫中執行,再將執行結果在中間件合并后返回給業務層,從而對業務層屏蔽物理存儲細節;數據庫則提供實際的物理存儲。

而MySql的分區表,借助MySql本身的邏輯架構,將分庫分表功能進行了下沉。MySql邏輯架構中的客戶端即對應業務層,Server層對應中間件層,存儲引擎層對應物理存儲層。簡單的說,分庫表就是我們在數據庫層面看到是一張表,但物理上是分成多個文件獨立存儲。

邏輯上分析,分區表的優點很明顯:既能解決大數據量的性能問題,又能對應用層無縫切換。但是,其真實性能表現和穩定性到底怎么樣? 還是得通過測試來驗證。

分區表性能測試

為方便說明,我們將此業務表邏輯結構簡化為只包含以下4列:id(自增列),depart_id(部門ID),user_id(員工ID),mark(員工業績)。

  • 非分區表 table_no_par:物理包含以上4列,其中 id 為主鍵,depart_id+user_id存在唯一鍵索引,mark列上有索引;
  • 分區表 table_par:物理包含以上4列,其中id為索引,depart_id+user_id存在唯一鍵索引,mark列上有索引。分區表以depart_id作為分區鍵,hash水平分成100個區。
    • 分區表中id作為索引而不是主鍵,原因是由于MySql要求分區鍵必須包含主鍵和唯一鍵索引,但實際上id作為自增列并不具有業務意義,不適合作為分區鍵。同時為了保證分區表和非分區表邏輯結構一致,需要在分區表創建id列,并在其上創建索引及自增。
    • 盡管分區表的user_id字段在業務上不應為NULL, 但為了避免 depart_id+user_id 的唯一鍵索引被MySql用作聚簇索引,也需要將其設置可為NULL。這樣一方面可以減少分區表占用的存儲空間;另一方面可以避免數據在DML時頻繁的進行頁面分裂、合并、重組,優化寫入性能。

    下面分別針對 插入、查詢、DDL、存儲空間 等幾個關鍵性能指標進行測試(更新和刪除數據的性能表現與查詢數據比較一致,不單獨分析)。測試結果如下:

    操作類型記錄數非分區表分區表
    插入性能500萬2693 秒3084 秒
    插入性能1000萬5440 秒6277 秒
    插入性能2000萬12753 秒14175 秒
    查詢性能2000萬記錄,分區鍵索引,查詢100萬次126 秒90 秒
    查詢性能2000萬記錄,非分區鍵索引,查詢100萬次691 秒727 秒
    DDL性能新增索引66 秒56 秒
    存儲空間500萬(數據+索引)255+384 MB351+555 MB
    存儲空間1000萬(數據+索引)511+900 MB551+900 MB
    存儲空間2000萬(數據+索引)1000+1900 MB1000+2100 MB

    可以看出:

  • 分區表的插入性能較非分區表要差11%~15%,但這個差距隨著記錄數的增多而減少。也就是說,隨著數據量的增大,分區表和非分區表的插入性能越來越接近。
  • 查詢性能方面,如果按照分區鍵查詢,分區表比非分區表的性能要好20%,而且數據量越大性能差距越大;如果按照非分區鍵的索引查詢,非分區表的性能表現更好。
  • DDL性能,通過新增索引的執行時間來看分區表優于非分區表,這是由于分區表的索引是針對單個分區,排序的基數少。尤其是針對大數據量表,N條數據排序消耗時間為O(N·logN),大于100次N/100條數據排序100·O(N/100·logN/100)。至于DDL執行失敗的情況,測試環境未模擬出。但在實際生產環境中,確實是存在這個風險的。這一點分區表和非分區表是一致的。
  • 存儲空間方面,分區表會比非分區表占用多一些,但隨著數據量的增大,差距越來越小。一方面是由于每條記錄非分區表比分區表少6字節的聚簇索引;另一方面是由于在存儲引擎層面,分區表是100張表,在申請頁面時各自獨立申請,導致頁面空間中未分配空間要更多。但大數據表兩者差異不大。
  • 通過以上的分析,我們得到以下的結論:

    針對大數據表,分區表的插入性能、存儲空間與非分區表基本一致,查詢性能在分區鍵上比非分區鍵好,DDL執行時間比非分區表短。

    于是,我們認為可以通過將非分區表切換到分區表來降低該數據表存在的性能風險。

    分區表切換

    為了避免業務中斷,我們參考pt-online-schema-change的模式進行切換。

    MySql在5.5及以前的版本,對Online DDL支持不太好,會導致鎖表。因此,percona推出pt-online-schema-change,利用觸發器實現在DDL過程中不會造成讀寫阻塞。

    具體步驟如下:

  • 整改數據表的使用模式,所有操作均必須帶上擬作為分區鍵的字段;
  • 創建分區表,其邏輯結構與非分區表完全一致;
  • 在非分區表上對update、delete動作創建觸發器,將其update、delete動作在分區表也執行一次;
  • 根據自增列ID,將非分區表中的數據分批次順序拷貝到分區表中;
  • 最后一批次數據拷貝完成后,立即通過rename將分區表與非分區表的表名互換;
  • 刪除觸發器,切換完成。
  • 切換完成后,我們進行了一周的性能觀察:CPU維持在10%,IOPS有8%左右的下降,存儲空間有3%的上升。
    單純從整體的性能指標來看,切換前后變化并不是特別明顯。但之前耗時越來越長的操作,耗時穩定了下來,鎖表沖突事件也基本沒有再出現。通過PARTITIONS的分析,最大的一個分區也只有500萬行。即使數據量再擴大10倍,最大分區的數據量也才5000萬,對于單個存儲引擎文件來說,這完全無壓力,理論上性能表現也不會出現大幅下滑。但如果放到非分區表,估計業務高峰流量稍微一沖擊,或者硬件性能出現波動(在資源共享的云計算環境中,較為常見),就有崩潰的風險。

    目前,分區表已經穩定在生產環境運行了近一個月。

    總體來看,切換分區表比較好的解決了我們當前對于數據量快速增長的數據庫性能的擔憂,至少數據量再增長2、3倍應該是能扛住的。但它是否能如我們預期的在高并發下支持10倍數據量(即單表15億記錄)而性能表現依然穩定,仍有待實踐證明。

    總結

    以上是生活随笔為你收集整理的MySql分区表性能测试及切换案例的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。