InnoDB Cluster 如何高效加載數據

愛可生南區負責人兼技術服務總監,MySQL ACE,擅長數據庫架構規劃、故障診斷、性能優化分析,實踐經驗豐富,幫助各行業客戶解決 MySQL 技術問題,為金融、運營商、互聯網等行業客戶提供 MySQL 整體解決方案。


一行命令搞定 InnoDB Cluster 數據快速加載。

InnoDB Cluster 8.0 經過一系列的優化已足夠穩定,早期版本常因網絡延遲、閃斷等問題造成集群不穩定,也曾遇到客戶因網絡緩解問題導致節點頻繁被踢,可用性得不到保障,不得不使用外圍運維手段保障集群穩定性,也增加了運維工作的複雜性。現在通過參數優化已能得到有效解決,能夠容忍一定網絡波動。

解決了網絡問題,另一個使用 InnoDB Cluster 面臨問題就是大事務了,系統難免會遇到大的 DML,load data 操作。

在數據同步機制上 group replication 與 async replication、semi-sync replication 有很大差異。它是參考 paxos 協議實現了獨立的組通訊引擎 xcom 集成在 MySQL,xcom 負責節點間消息的發送與接收,並保證消息投遞的一致和有序,消息包括兩類事務寫集相關信息和心跳統計相關信息。

xcom 是單線程實例,在處理大事務必然會影響其他消息的處理,如果是來自其他節點的心跳消息無法回應,5s 無響應節點會被踢出集群。

group_replication_transaction_size_limit 參數限制了事務大小,超出限制事務回滾不會廣播。事務消息就是 writeset,其大小是由事務變更行數、行長度、唯一索引數量等因素決定。

為了增強對大事務的處理能力,8.0.16 支持了消息分片機制,通過 group_replication_communication_max_message_size 參數控制消息分片大小,若消息超過該限制會自動分包廣播,到達其他節點後自動合併起來,此參數不能大於 slave_max_allowed_packet 值,默認是 10MB,最大上限 1GB。


那有了消息分片機制是不是就完美支持大事務了?

我模擬了 load data 導入一個 185MB 的文件。

在 group_replication_transaction_size_limit 默認 147MB 配置下是無法導入的,超過限制事務被回滾。


技術分享 | InnoDB Cluster 如何高效加載數據


技術分享 | InnoDB Cluster 如何高效加載數據


技術分享 | InnoDB Cluster 如何高效加載數據

將 group_replication_transaction_size_limit 設置為 0 相當於取消限制,可以成功導入,且集群節點狀態全部正常,沒有節點被踢出集群。


技術分享 | InnoDB Cluster 如何高效加載數據


還能處理更大的事務嗎?

隨後測試中我將數據文件放大到 1G,group_replication_transaction_size_limit 保持為 0 不做事務限制,會發生節點失聯導入失敗。

因為超出了 xcom cache 限制,xcom cache 緩存了最近一段時間的消息信息,當節點失聯後加回集群,失聯期間的消息要通過 xcom cache 來恢復,如果緩存空間不夠,缺失的消息被淘汰了,節點就無法自動加回集群,只能手動加回集群通過異步複製通道恢復數據。

8.0.16 之前 xcom cache 是固定配置 50000 個 slot 或 1G 內存,超出限制按 LRU 策略回收內存空間,8.0.16 新增了 group_replication_message_cache_size 參數取消了固定限制,用戶可以結合實際情況調整,配合 group_replication_member_expel_timeout 調整能容忍更長網絡延遲。

xcom cache 使用情況在 memory_summary_global_by_event_name 觀測

<code>mysql> select * from  memory_summary_global_by_event_name where event_name like 'memory/group_rpl%'\\G*************************** 1. row ***************************                  EVENT_NAME: memory/group_rpl/GCS_XCom::xcom_cache                 COUNT_ALLOC: 2362                  COUNT_FREE: 2317   SUM_NUMBER_OF_BYTES_ALLOC: 5687428055    SUM_NUMBER_OF_BYTES_FREE: 3196560772              LOW_COUNT_USED: 0          CURRENT_COUNT_USED: 45             HIGH_COUNT_USED: 1176    LOW_NUMBER_OF_BYTES_USED: 0CURRENT_NUMBER_OF_BYTES_USED: 2490867283   HIGH_NUMBER_OF_BYTES_USED: 31952807581 row in set (0.0030 sec)/<code>
  • CURRENT_COUNT_USED xcom cache 當前已使用 slot 數量
  • CURRENT_NUMBER_OF_BYTES_USED xcom cache 當前已使用內存空間


如果將 xcom cache 設置足夠大,能處理更大的事務嗎?

group_replication_message_cache_size 上限是 16EB,cb_xcom_receive_data 函數接收消息的限制是 4G,有興趣可以試驗下加載一個 5G 數據文件會是什麼情況。

但大事務對內存和網絡的開銷,會影響集群整體性能,還是應儘量避免大事務。


瞭解了組複製對大事務的處理方式,如何快速的導入數據?

正確做法是拆分成小文件並行導入,mysql shell AdminAPI 早已集成了並行導入小工具,自動拆分並行處理,效率更高,開箱即用。

<code>mysqlsh root@localhost:4000 --ssl-mode=DISABLED -- util import-table /Users/hongbin/mysql-sandboxes/4000/mysql-files/sbtest --schema=test --table=sbtest2 --bytes-per-chunk=10M/<code>


技術分享 | InnoDB Cluster 如何高效加載數據


總結

1. 消息分片機制能在一定程度降低大事務造成節點被踢出集群的概率,但集群性能依然會受影響。

2. 大事務需要佔用更多 xcom cache 空間,xcom 要申請更多內存空間,也會有被 OOM 的風險。

3. 應儘量避免大事務,調整 group_replication_transaction_size_limit、group_replication_message_cache_size、group_replication_communication_max_message_size、group_replication_member_expel_timeout 參數只能緩解部分問題。生產環境也不建議設置 group_replication_transaction_size_limit 為 0。

4. 大文件數據加載應拆分後導入,推薦使用 mysql shell 的util.importTable。


分享到:


相關文章: