數據庫架構設計與優化

數據庫架構設計與優化

一. 影響數據庫性能的原因

1.1 影響數據庫的因素

  1. SQL查詢速度
  2. 服務器硬件
  3. 網卡流量
  4. 磁盤IO

1.2 影響MYSQL性能的因素有哪些?

  1. 超高的QPS和TPS
    • 風險:效率低下的SQL(每運行一次SQL只能使用一個CPU,所以單個SQL效率低下影響CPU執行效率)

    QPS:每秒中的查詢量。 80%的事故都是因爲慢查詢造成的

  2. 大量的併發和超高的CPU使用率
    • 大量的併發:
      • 數據庫連接數被佔滿(max_connections默認100)
    • 超高的CPU使用率:
      • 因CPU資源耗盡出現宕機
  3. 磁盤IO
    1. 磁盤IO性能突然下降(使用更快的磁盤設備)
    2. 其他大量消耗磁盤性能的計劃任務(調整計劃任務,做好磁盤維護)
  4. 網卡流量:
    1. 網卡IO被佔滿
      1. 如何避免無法連接數據庫的情況:
        1. 減少從服務器的數量
        2. 進行分集緩存
        3. 避免使用 select * 進行查詢
        4. 分離業務網絡和服務器網絡
  5. 大表
    1. 什麼樣的表可以稱之爲大表
      1. 記錄行數巨大,單表超過千萬行
      2. 表數據文件巨大,表數據文件超過10G

      大表對查詢的影響: 慢查詢->很難在一定時間內過濾出所需要的數據

    2. 大表對DDL操作的影響:
      1. 建立索引需要很長時間
        1. MYSQL版本<5.5建立索引會鎖表
        2. MYSQL版本>=5.5 雖然不會鎖表但會引起主從延遲
        3. 修改表結構需要長時間鎖表
          1. 會造成長時間的主從延遲
          2. 影響正常的數據操作
      2. 如何處理數據庫中的大表:
        1. 分庫分表:
          1. 把一張大表分成多個小表

          難點: 分表主鍵的選擇 分表後跨分區數據的查詢和統計

        2. 大表的歷史數據歸檔
          1. 減少對前後端業務的影響

          歸檔時間點的選擇
          如何進行歸檔操作

1.3 事務

  1. 什麼是事務?
    • 事務是數據庫系統區別於其他一切文件系統的重要特性之一。
    • 事務是一組具有原子性的SQL語句,或是一個獨立的工作單元。
  2. 事務符合哪些特性?
    1. 事務的原子性

      • 定義:一個事務必須被視爲一個不可分割的最小工作單元,整個事務中的所有操作要麼全部提交成功,要麼全部失敗,對於一個事務來說,不可能只執行其中的一部分操作;
    2. 事務的一致性

      • 定義:一致性是指事務將從數據庫從一種一致性狀態轉換到另外一種一致性住哪個臺,在事務開始之前和事務結束後數據庫中數據的完整性沒有被破壞;
    3. 事務的隔離性:

      • 定義:隔離性要求一個事務對數據庫中數據的修改,在未提交完成前對於其他事務是不可見的。
      • SQL標準中定義的四種隔離級別:
        • 未提交讀(READ UNCOMMITED)
        • 已提交度(READ COMMITED)
        • 可重複讀(REPEATABLE READ)
        • 可串行化(SERIALIZABLE)

        併發性由高到低,隔離性能由低到高

    4. 事務的持久性:

      • 定義: 一旦事務提交,則其所作的修改就會永久保存到數據庫中。此時即使系統崩潰,已經提交的修改數據也不會丟失。
  3. 什麼是大事務?
    1. 定義:運行時間比較長,操作的數據比較多的事務;
    2. 風險:
      1. 鎖定太多的數據,造成大量的阻塞和鎖超時;
      2. 回滾時所需時間比較長
      3. 執行時間長,容易造成主從延遲
    3. 如何處理大事務:
      1. 避免一次處理太多數據
      2. 移除不必要在事務中的SELECT(讓事務中只有寫入或者修改操作,select可以不用在事務中完成

二. 什麼影響了MYSQL性能

2.1 影響性能的幾個方面

  1. 服務器硬件
  2. 服務器系統
  3. 數據庫存儲引擎的選擇
    1. MyISAM:不支持事務,表級鎖;
    2. InnoDB:事務級存儲引擎,完美支持行級鎖,事務ACID特性;
  4. 數據庫參數配置
  5. 數據庫結構設計和SQL語句

2.2 CPU資源和可用內存大小

  1. 如何選擇CPU?

    1. 買單核性能更好的CPU。 因爲MYSQL不支持多CPU對同一SQL併發處理,所以我們買多核對其幫助不大,更應該考慮單CPU性能更高的CPU
    2. 要考慮MYSQL版本。因爲新版本對多核的支持更加好。要根據自己的版本進行選擇
    3. 選擇64位的CPU。因爲MYSQL單線程的,使用32位對其有極大的限制。所以用64位更好。

    mysql不支持多cpu對同一SQL併發處理

  2. 如何選擇內存?

    1. 要選擇主板支持的最大內存頻率;(頻率越高,速度越快)
    2. 購買要點:
      1. 組成購買升級
      2. 每個通道的內存:相同品牌、顆粒
      3. 頻率、電壓、校驗技術和型號
      4. 單條容量要儘可能大
    3. 根據數據庫大小選擇內存;
  3. 磁盤的配置和選擇:

    1. 常見的磁盤種類:
      1. 傳統機器磁盤
      2. 使用RAID增強傳統機器硬盤的性能
      3. 使用固態存儲SSD和PCIe卡
      4. 使用網絡存儲NAS和SAN
    2. 傳統機器硬盤:
      1. 特點:最常見,使用最多,價格低,存儲空間大,讀、寫較慢;
      2. 傳統磁盤讀取過程:
        1. 移動磁頭到磁盤表面上的正確位置;
        2. 等待磁盤旋轉,使的所需的數據在磁頭之下;
        3. 等待磁盤旋轉過去,所有所需的數據都被磁頭讀出;
      3. 如何選擇傳統機器硬盤
        1. 存儲容量
        2. 傳輸速度
        3. 訪問時間
        4. 主軸轉速
        5. 物理尺寸(越大,存儲空間越大)
  4. 常用MySQL存儲引擎:

    1. MyISAM:
      在這裏插入圖片描述
      2.InnoDB: 在這裏插入圖片描述

2.3 使用RAID增加傳統機器硬盤的性能

2.3.1 什麼是RAID?

  • RAID是磁盤冗餘隊列的簡稱(Redundant Arrays of Independent Disks)簡單來說RAID的作用就是可以把多個容量較小的餐盤組成一組容量更大的磁盤,並提供數據冗餘來保證數據完整性的技術。

2.3.2 RAID 0

  • RAID 0 是最早出現的RAID模式,也稱之爲數據條帶。是組建磁盤陣列中最簡單的一種形式,只需要2塊以上的硬盤即可,成本低,可以提高整個磁盤的性能和吞吐量。RAID 0 沒有提供冗餘或錯誤修復能力,但是實現成本是最低的。
  • 如圖所示:
    在這裏插入圖片描述

2.3.3 RAID 1

  • RAID 1 又稱磁盤鏡像,原理是把一個磁盤的數據鏡像到另一個磁盤上,也就是說數據在寫入一塊磁盤的同時,會在另一塊閒置的磁盤上生成鏡像文件,在不影響性能情況下最大限度的保證系統的可靠性和可修復性。
  • 如圖所示:
    在這裏插入圖片描述

2.3.4 RAID 5

  • RAID 5又稱之爲分佈式奇偶校驗磁盤陣列
    • 通過分佈式奇偶校驗塊把數據分散到多個磁盤上,這樣如果任何一個盤數據失效,都可以從奇偶校驗塊中重建。但是如果兩塊磁盤失效,則整個卷的數據都無法恢復。
  • 如圖所示:
    在這裏插入圖片描述

    使用在從服務器上,適合讀。

2.3.5 RAID 10 又稱分片的鏡像

  • 它是對磁盤先做RAID 1 之後對兩組RAID 1的磁盤再做RAID 0 ,所以對讀寫都有良好的性能,相對於RAID 5 重建起來更簡單,速度也更快。
  • 如圖所示:
    在這裏插入圖片描述

2.3.6 對常用RAID的解析

  • 常用RAID如圖:
    在這裏插入圖片描述
  • RAID級別的選擇:
    在這裏插入圖片描述

2.4 使用固態存儲或PCle卡

  • 固態存儲相比於機械磁盤的特點:

    • 相比機械磁盤,固態磁盤有更好的隨機讀寫性能(優點)
    • 相比機械磁盤,固態磁盤能更好的支持併發(優點)
    • 相比機械磁盤固態磁盤更容易損壞(缺點)
  • 固態硬盤的特點:

    • 使用SATA接口,可以替換傳統磁盤而不需任何改變
    • SATA接口的SSD同樣支持RAID技術

    由於使用SATA 接口,而STATA 有3.0 和2.0 ,如果連接的是2.0接口,則會本身的速度受到限制。

  • PCIe卡圖示:
    在這裏插入圖片描述

  • 固態存儲PCIe卡的特點

    • 無法使用SATA接口,需要獨特的驅動和配置
    • 價格相對於SSD要貴,但是性能比SSD更好

    不建議使用RAID,成本較高; PCIe卡會消耗內存;

  • 固態存儲的使用場景:

    • 適用於存在大量隨機I/O的場景
    • 使用於解決單線程負載的I/O瓶頸

2.5 網絡存儲SAN和NAS

  • 概述:SAN(Storage Area Network) 和 NAS(Network-Attached Storage)是兩種外部文件存儲設備加載到服務器上的方法。

  • SAN:

    • 圖示:
      在這裏插入圖片描述
    • SAN設備通過光纖連接到服務器,設備通過塊接口訪問,服務器可以將其當做硬盤使用。
    • 特點:
      • 大量順序讀寫
      • 讀寫I/O
      • 緩存
      • I/O合併
      • 隨機讀寫/慢
      • 不如本地RAID磁盤
  • NAS:

    • NAS設備使用網絡連接,通過基於文件的協議如NFS或SMB來訪問。
  • 網絡存儲適用的場景:

    • 數據庫備份
  • 網絡對性能的影響:

    • 網絡帶寬對性能的影響
    • 網絡質量對性能的影響
  • 建議:

    • 採用高性能和高帶寬的網絡接口設備和交換機
    • 對多個網卡進行綁定,增強可用性和帶寬
    • 儘可能的進行網絡隔離

    mysql 的性能瓶頸一般是在隨機讀寫上,而網絡存儲的優勢在於順序讀寫,而不是隨機讀寫,所以並不太適用於做爲Mysql存儲;

2.6 服務器硬件對性能的影響

  • CPU:

    • 64位的CPU一定要工作在64位的系統下
    • 對於併發比較高的場景CPU的數量比頻率重要
    • 對於CPU密集性場景和複雜SQL則頻率越高越好
  • 內存:

    • 選擇主板能使用的最高頻率的內存。
    • 內存的大小對性能很重要,所以儘可能的要大。
  • I/O子系統:

    • PCIe-> SSD->RAID10->磁盤->SAN

2.7 操作系統對性能的參數優化

  • MYSQL適合的操作系統

    • Windows FreeBSD Solaris Linux

    本文章的演示都是在Centos上進行演示的,也建議使用Linux系統;

  • 內核相關參數(/etc/sysct.conf)

    • 網絡相關的參數:
      • net.core.somaxconn=65535
      • net.core.netdev_max_backlog=65535
      • net.ipv4.tcp_max_syn_backlog=65535

      根據需要調整

    • 加快tcp回收速度,連接時間
      • net.ipv4.tcp_fin_timeout=10
      • net.ipv4.tcp_tw_reuse=1
      • net.ipv4.tcp_tw_recycle=1
    • tcp 接收和發送的緩衝區默認值:
      在這裏插入圖片描述
      • 用於失效連接減少tcp資源佔用數量,
        在這裏插入圖片描述
  • 內存優化:

    kernel.shmmax=4294967295
    
    1. 這個參數應該設置的足夠大,以便能在一個共享內存段下容納下整個的InnoDB緩衝池的大小。 2. 這個值的大小對於64位Linux系統,可取的最大值爲物理內存置-1byte,建議值爲大於物理內存的一般,一般取值大於Innodb緩衝池的大小即可,可以取物理內存-1byte
    vm.swappiness=0
    
    • 就是告訴Linux內核,除非虛擬內存完全滿了,否則不要使用交換區;
    • 當操作系統因爲沒有足夠的內存時就會將一些虛擬內存寫到磁盤的交換區中這樣就會發生內存交換。
    • 使用交換分區後,mysql的性能會大幅下降,可能會導致一些災難性的後果。所以在Mysql服務器上是否要使用交換分區有一些爭議:在MySQL服務所在的Linux系統上完全禁用交換分區。
    • 帶來的風險:
      1. 降低操作系統的性能
      2. 容易造成內存溢出、崩潰、或都被操作系統Kill掉。
    • 結論:
      • 在MySQL服務器上保留交換區還是很必要的,但是要控制何時使用交換分區。
  • 其他優化:

    1. 增加資源限制:
      在這裏插入圖片描述

    結論: 把可打開的文件數量增加到了65535個以保證可以打開足夠多的文件句柄。 注意: 這個文件的修改需要重啓系統纔可以生效。

    1. 磁盤調度策略:
      在這裏插入圖片描述
      在這裏插入圖片描述
      在這裏插入圖片描述
      在這裏插入圖片描述
      在這裏插入圖片描述

2.8 文件系統對性能的影響

  • 各個系統支持的文件系統格式:
    在這裏插入圖片描述
  • EXT3/4系統的掛載參數(/etc/fstab)
    data= writeback | ordered | journal
    noatime, nodiratime
    /dev/sda1/ext4 noatime,nodiratime,data=writeback 11

2.9 Mysql體系結構

  1. 插件式存儲引擎
    1. 客戶端:PHP ,JAVA,C API, .Net以及ODBC, JDBC等
    2. 查詢流程圖示:
      在這裏插入圖片描述
      • select:要查詢的數據,這個具體的實現的方式則是由下一層存儲引擎層來實現。

2.10 Mysql常用存儲引擎之MyISAM

  • Mysql 5.5 之前版本默認存儲引擎;它也是系統表和臨時表的默認存儲引擎;

  • 臨時表:

    • 在排序、分組等操作中,當數量超過一定的大小之後,由查詢優化器建立的臨時表。
    • MyISAM存儲引擎表由MYD和MYI組成
  • 特性:
    - 併發性與鎖級別
    - 表損壞修復
    ~~~java
    check table tablename
    repair table tablename
    ~~~
    - MyISAM表支持的索引類型
    - MyISAM表支持數據壓縮
    - 命令行: myisampack

  • 限制:

    • 版本 < Mysql 5.0 時默認表大小爲4G
    • 如存儲大表則要修改MAX_Rows和AVG_ROW_LENGTH
    • 版本> MySQL 5.0 時默認支持爲256TB
  • 適用場景:

    • 非事務型應用
    • 只讀類應用
    • 空間類應用

2.11 MySQL常用存儲引擎之InnoDB

  • MySQL 5.5 及之後版本默認存儲引擎: InnoDb表

    • innodb_file_per_table
    • ON:獨立表空間:tablename.ibd
    • OFF:系統表空間:ibdataX
  • 系統表空間和獨立表空間要如何選擇:
    -[ ] 收縮方面:
    - 系統表空間無法簡單的收縮文件大小
    - 獨立表空間可以通過optimize table 命令收縮系統文件

    • IO方面
      • 系統表空間會產生IO瓶頸
      • 獨立表空間
  • 建議:

    • 對InnoDB使用獨立表空間
  • 步驟:[把原來存在於系統表空間中的錶轉移到獨立表空間中的方法]

    1. 使用mysqldump導出所有數據庫表數據
    2. 停止MySQL服務,修改參數,並刪除Innodb相關文件
    3. 重啓MySQL服務,重建Innodb系統表空間
    4. 重新導入數據
  • 系統表空間和獨立表空間要如何選擇

    • Innodb數據字典信息
    • Undo 回滾段
  • Innodb存儲引擎的特性

    • Innodb是一種事務性存儲引擎

    • 完全支持事務的ACID特性

    • Redo Log 和Undo Log

    • Innodb支持行級鎖

    • 行級鎖可以最大程度的支持併發

    • 行級鎖是由存儲引擎層實現的

  • 什麼是鎖?

    • 鎖對主要作用是管理共享資源的併發訪問
    • 鎖用於實現事務的隔離性
  • 鎖的類型:

    • 共享鎖(也成讀鎖)
    • 獨佔鎖(也成寫鎖)
    • 圖示:
      在這裏插入圖片描述
  • 鎖的粒度:

    • 表級鎖
    • 行級鎖
  • 阻塞和死鎖

    • 什麼是阻塞?
      • 一個鎖鎖上了,其他的請求無法對此資源進行訪問,則爲阻塞;相當於一個屋子外被鎖上了,其他人不能進入這個屋子;

      會導致堆積,佔用大量資源;

    • 什麼是死鎖?
      • 指的是兩個或者兩個以上的事務相互佔用對方的鎖而導致異常。

      死鎖的發生後,系統能自動發現並處理。但是大量的死鎖出現,我們就需要警惕了。

  • Innodb狀態檢查

    • show engine innodb status
  • 適用場景:

    • Innodb適合於大多數OLTP應用

2.12 MySQL常用存儲引擎之CSV

  • 文件系統存儲特點

    • 數據以文本方式存儲在文件中
    • .CSV文件存儲表內容
    • .CSM文件存儲表內容
    • .CSM文件存儲表的元數據如表狀態和數據量
    • .frm文件存儲表結構信息
  • 特點:

    • 以CSV格式進行數據存儲
    • 所有列必須都是不能爲NULL的
    • 不支持索引 -> 不支持大表,不適合在線處理
    • 可以對數據文件直接編輯
  • 適用場景:

    • 適合作爲數據交換的中間表
    • 圖示:
      • 在這裏插入圖片描述

      • 在這裏插入圖片描述

2.13 MySQL常用存儲引擎之Archive

  • 文件系統存儲特點:

    • 以zlib對錶數據進行壓縮,磁盤I/O更少
    • 數據存儲在ARZ爲後綴的文件中
  • Archive存儲引擎的特點

    • 只支持insert和select操作
    • 只允許在自增ID列上加索引
  • 使用場景:

    • 日誌和數據採集類應用

2.14 MySQL常用存儲引擎之Memory

  • 文件系統存儲特點:

    • 也稱HEAP存儲引擎,所以數據保存在內存彙總
  • 功能特點:

    • 支持HASH索引和BTree索引(等值查找使用HASH,範圍查找使用BTree)
    • 所有字段都會固定長度varchar(10)=char(10)
    • 不支持BLOG和TEXT等大字段
    • Memory存儲引擎使用表級鎖;
    • 最大大小由 max_heap_table_size參數決定
  • 容易混淆的概念

    • 圖示:
      在這裏插入圖片描述
  • 使用場景

    • 用於查找或者是映射表,例如郵編和地區的對應表
    • 用於保存數據分析中產生的中間表
    • 用於緩存週期性聚合數據的結果表

    Memory數據易丟失,所以要求數據可再生。

2.15 MySQL常用存儲引擎之Federated

  • 特點:

    • 提供了訪問遠程MySQL服務器上表的方法
    • 本地不存儲數據,數據全部放到遠程服務器上
    • 本地需要保存表結構和遠程服務器的連接信息
  • 如何使用:

    • 默認禁止,啓動需要在啓動時增加federated參數
    mysql://user_name[:password]@host_name[:port_num]/db_name/tbl_name
    
  • 使用場景:

    • 偶爾的統計分析及手工查詢

2.16 如何選擇存儲引擎?

  • 概述: 大部分的話我們使用Innodb存儲引擎即可,除非是一些Innodb引擎不支持的功能,則可以使用其他的引擎;

  • 參考條件:

    • 事務;
    • 備份;
    • 崩潰恢復
    • 存儲引擎的特有特性

2.17 服務器參數介紹

  • 大部分的服務器參數使用默認即可,小部分的可以根據服務器配置來進行調整;

  • MySQL獲取配置信息路徑:

    • 命令行參數:
      mysqld_safe --datadir=/data/sql_data
      
    • 配置文件
      mysqld --help --verbose | grep -A 1 'Default options' 
      
      /etc/my.cnf/etc/mysql/my.cnf/home/mysql/my.cnf~/.my.cnf
      
    • MySQL配置參數的作用域:
      • 全局參數:
        在這裏插入圖片描述

2.18 內存配置相關參數

  • 要點:

    • 確定可以使用的內存的上限
    • 確定MySQL的每個鏈接使用的內存
      • 如圖:
        在這裏插入圖片描述
  • 內存配置相關參數:

    • 確定需要爲操作系統保留多少內存
    • 如何爲緩存池分配內存:
      • Innodb_buffer_pool_size

      總內存-(每個線程所需要的內存*鏈接數)- 系統保留內存

      • key_buffer_size
        在這裏插入圖片描述
    • 常用相關命令:
      • 日誌相關:
        在這裏插入圖片描述
      • Innodb_flush_log_at_trx_commit
        • 0:每秒進行一次log寫入cache,並flush log到磁盤
        • 1[默認]:在每次事務提交執行log寫入cache,並flush log到磁盤
        • 2[建議]:每次事務提交,執行log數據寫入到cache,每秒執行一次flush log到磁盤;
      • Innodb_flush_method=O_DIRECT
        • // 刷新方式,決定了如何寫和如何刷。關閉讀寫,避免雙重緩存,建議Linux使用
      • Innodb_file_per_table=1
        • // 建議使用,爲每個表建立表空間
      • Innodb_doublewrite=1
        • 啓用雙寫緩存,增強數據安全性
      • delay_key_write
        • OFF:每次寫操作後刷新鍵緩衝中的髒塊到磁盤
        • ON:只對在鍵表時指定了delay_key_write選項的表使用延遲刷新
        • ALL:對所有MYISAM表都使用延遲鍵寫入;
      • 安全相關配置參數:
        • expire_logs_days 指定自動清理binlog的天數
        • max_allowed_packet 控制MySQL可以接收包的大小
        • skip_name_resolve 禁用DNS查找
        • sysdate_is_now 確保sysdate()返回確定性日期
        • read_only 禁止非super權限的用戶寫權限
        • skip_slave_start 禁用Slave自動恢復
      • sql_mode 設置MySQL所使用的SQL模式
        • strict_trans_tables
        • no_engine_subtitution
        • no_zero_date
        • no_zero_in_date
        • only_full_group_by

      不要輕易改動,以免生產環境出錯

2.19 其他常用參數

  • sync_binlog 控制MYSQL如何向磁盤刷新binlog
  • tmp_table_size 和 max_heap_table_size 控制內存臨時表大小
  • max_connections 控制允許的最大連接數

2.20 數據庫設計對性能的影響

  • 數據庫設計對設計的影響

    • 過分的反範式話爲表建立太多的列
    • 過分的範式化造成太多的表關聯
    • 在OLTP環境中使用不恰當的分區表
    • 使用外鍵保證數據的完整性
  • 性能優化順序

    • 數據庫結構設計和SQL語句
    • 數據庫存儲引擎的選擇和參數配置
    • 系統選擇及優化
    • 硬件升級

三. 基準測試

3.1 什麼是基準測試

  • 定義:基準測試是一種測量和評估軟件性能指標的活動用於建立某個時刻的性能基準,以便當系統發生軟硬件變化時重新進行基準測試以評估變化對性能的影響

    總結來說,基準測試是針對系統設置的一種壓力測試

  • 基準測試與壓力測試的對比:
    • 基準測試:直接、簡單、易於比較,用於評估服務器的處理能力
    • 壓力測試:對真實的業務數據進行測試,獲得真實系統所能承受的壓力

    壓力測試需要針對不同主題,所使用的數據和查詢也是真實用到的;基準測試可能不關心業務邏輯,所使用的查詢和業務的真實性可以和業務環境沒關係。

3.2 如何進行基準測試

  • 基準測試的目的:
    • 建立MySQL服務器的性能基準線

      確定當前MySQL服務器運行情況

    • 模擬比當前系統更高的負載,以找出系統的擴展瓶頸

      增加數據庫併發,觀察QPS,TPS變化,確定併發量與性能最優的關係

    • 測試不同的硬件、軟件和操作系統配置
    • 證明新的硬件設備是否配置正確
  • 如何進行基準測試:
    • 對整個系統進行基準測試
      • 從系統入口進行測試(如網站Web前端,手機APP前端)
      • 優缺點:
        • 優點:
          • 能夠測試整個系統的性能,包括web服務器緩存、數據庫等。
          • 能反映出系統中各個組件接口間的性能問題體現真實性能狀況
        • 缺點:
          • 測試設計複雜,消耗時間長
    • 單獨對MySQL進行基準測試:
      • 優點:
        • 測試設計簡單,所需耗費時間短
      • 缺點:
        • 無法全面瞭解整個系統的性能基線

3.3 MySQL基準測試的常見指標

  • 單位時間所處理的事務數(TPS)
  • 單位時間內所處理的查詢數(QPS)
  • 響應時間
  • 併發量: 同時處理查詢請求的數量

    正在工作中的併發的操作數或同時工作的數量

3.4 基準測試的步驟

  • 計劃和設計基準測試
    • 對整個系統還是某一組件
    • 使用什麼樣的數據
    • 準備基準測試及數據收集腳本
      • CPU使用率、IO、網絡流量、狀態與計數器等
      • Get_Test_info.sh
    • 運行基準測試:
      • 使用生產環境數據時只使用了部分數據
      • 在多用戶場景中,只做單用戶的測試

      推薦多線程併發測試

3.5 基準測試中容易忽略的問題

  • 使用生產環境數據時只使用了部分數據

    推薦: 使用數據庫完全備份來測試

  • 在多用戶場景中,只做單用戶的測試

    推薦:使用多線程併發測試

  • 在單服務器上測試分佈式應用

    推薦:使用相同架構進行測試

  • 反覆執行同一查詢

    容易緩存命中,無法反應查詢真實性能

3.6 常用的基準測試工具介紹

  • MySQL基準測試工作之 mysqlslap

    • 下載及安裝:

      • MySQL服務器自帶的基準測試工具,隨MySQL一起安裝
    • 特點:

      • 可以模擬服務器負載,並輸出相關統計信息
      • 可以指定也可以自動生成查詢語句
    • 常用參數說明:

      • –auto-generate-sql 由系統自動生成SQL腳本進行測試
      • –auto-generate-sql-add-autoincrement 在生成的表中增加自增ID
      • –auto-generate-sql-load-type 指定測試中使用的查詢類型
      • –auto-generate-sql-write-number 指定初始化數據數據時生成的數據量
      • –concurrency 指定併發線程的數量
      • –engine 指定要測試表的存儲引擎,可以用逗號分隔多個存儲引擎
      • –no-drop指定不清理測試數據
      • –iterations 指定測試運行的次數
      • –number-of-queries 指定每一個線程執行查詢的查詢數量
      • –debug-info 指定輸出額外的內存及CPU統計信息
      • –number-int-cols 指定測試表中包含的INT類型列的數量
      • –number-char-cols 指定測試表中包含的varchar類型的數量
      • –create-schema 指定了用於執行測試的數據庫的名字
      • –query 用於指定自定義SQL的腳本
      • –only-print 並不運行測試腳本,而是把生成的腳本打印出來

      基準測試的原理就是,通過調用基準測試的相關方法和參數,然後生成表和具體的數據,然後進行測試性能;這一系列的過程是通過設置好參數後會生成一個腳本,而這個腳本就是基準測試的關鍵;

    • 測試示例:

      1. 檢驗是否安裝了mysqllap工具:
        mysqlslap --help
        
      2. 編寫測試代碼:
        mysqlslap --concurrency=1,50,100,200 --iterations=3 --number-int-clos=5 --number-char-clos=5 --auto-generate-sql --auto-generate-sql-add-autoincrement --engine=mvisam.innodb --number-of-queries=10 --create-schema=sbtest
        

      注意: --only-print 並不運行測試腳本,而是把生成的腳本打印出來。 在測試過程中,它會模擬一些數據去進行插入,查詢等方式去測試性能;

  • MySQL基準測試工作之 sysbench

    • 多線程測試工具,它的範圍更廣,更爲靈活,並且較爲常用的測試工具;需要下載安裝後才能進行測試。

    • 安裝說明:

      https://github.com/akopytov/sysbench/archive/0.5.zip
      
      unzip sysbench-0.5.zip
      
      cd sysbench
      
      ./autogen.sh
      
      ./configure --with-mysql-includes=/usr/local/mysql/include/ \--with-mysql-libs=/usr/local/mysql/lib/
      
      make && make install
      
    • 實戰安裝操作:

      1. 假定已經下載好了。並且已經進入下載目錄;
      2. 解壓:
        unzip sysbench-0.5.zip
        
      3. 進入目錄:
        cd sysbench-0.5
        
      4. 執行命令:
        ./autogen.sh
        
      5. 配置安裝目錄(根據自己的安裝目錄而定):
        ./configure --with-mysql-includes=/usr/local/mysql/include/ --with-mysql-libs=/usr/local/mysql/lib
        
      6. 輸入執行命令:
        make
        
      7. 輸入執行命令:
        make install
        
    • 常用參數:

      • test 用於指定所要執行的測試類型,支持以下參數:
        • Fileio 文件系統I/O性能測試
        • cou cou性能測試
        • memory 內存性能測試
        • Oltp 測試要指定具體的lua腳本

          Lua腳本位於sysbench-0.5/sysbench/tests/db

        • –mysql-db用於指定執行基準測試的數據庫名
        • –mysql-table-engine 用於指定所使用的存儲引擎
        • –oltp-tables-count 執行測試的表的數量
        • –oltp-table-size 指定每個表中的數據行數
        • –num-threads 指定測試的併發線程數量
        • –max-time 指定最大的測試時間
        • –report-interval 指定間隔多長時間輸出一次統計信息
        • –mysql-user 指定執行測試的MySQL用戶
        • –mysql-password指定執行測試的MySQL用戶的密碼
        • prepare 用於準備測試行數據
        • run 用於實際進行測試
        • cleanup 用於清理測試數據
    • 實戰操作命令:

      sysbench --test=./oltp.lua --mysql-table-engine=innodb --oltp-table-size=10000 --mysql-db=表名 --mysql-user=sfbest --mysql-password=123456 --oltp-tables-count=10 --mysql-socket=/usr/local/mysql/data/mysql.sock prepare
      
  • sysbench演示測試示例

    • CPU測試:
      sysbench --test=cpu --cpu-max-prime=10000 run
      
    • 磁盤IO測試:
      1. 首先查看內存大小:
        1. df -lh
      2. 生成大於磁盤大小的測試文件
        sysbench --test=fileio --file-total-size=1G prepare
        
      3. 進行測試:
        sysbench --test=fileio --num-threads=8 --init-rng=on --file-total-size=1G --file-test-mode=rndrw --report-interval=1 run
        

        每隔一秒就會生成一個結果;

      4. 注意: 進行測試的語句請根據實際情況來;

四. 數據庫結構優化

4.1 優化介紹

  • 數據庫結構優化的目的:
    • 減少數據冗餘(必要的數據冗餘可以忽略)
    • 儘量避免數據維護中出現更新,插入和刪除異常;
      • 插入異常:如果表中的某個實體隨着另一個實體的存在而存在;
      • 更新異常:如果更改表中的某個實體的單獨屬性時,需要對多行進行更新;(比如一個用戶得分表,將總分從100分提升至150時,需要對每個用戶的得分進行更新;)
      • 刪除異常:如果刪除表中的某一實體則會導致其他實體的消息;

      使用範式化,能儘量少的減少這些問題的產生;

    • 節約數據存儲空間
    • 提高查詢效率;

4.2 數據庫結構設計(邏輯設計)

  • 數據庫結構設計的步驟

    • 需求分析: 全面瞭解產品設計的存儲需求,存儲需求,數據處理需求,數據的安全性和完整性;
    • 設計數據的邏輯存儲結構: 數據實體之間的邏輯關係,解決數據冗餘
    • 物理設計: 根據所使用的數據庫特點進行表結構設計
      • 關係型數據庫: orcale,sqlServer,mysql,postgresSQL
      • 非關係型數據庫:mongoDB,Redis,Hadoop
      • 存儲引擎:InnoDB
    • 維護優化: 根據實際情況對索引、存儲結構等進行優化;
  • 數據庫設計範式:

    • 數據庫設計的第一範式:
      • 數據庫表中的所有字段都只具有單一屬性
      • 單一屬性的列是由基本的數據類型所構成的
      • 設計出來的表都是簡單的二維表
    • 數據庫設計的第二範式:
      • 要求一個表中只具有一個業務主鍵,也就是說符合第二範式的表中不能存在非主鍵列對只對部分主鍵的依賴關係;
    • 數據庫設計的第三範式:
      • 指每一個非主屬性既不部分依賴於也不傳遞依賴於業務主鍵,也就是在第二範式的基礎上消除了非主屬性對主鍵的傳遞依賴;

    範式後面的範式,必須同時滿足之前的範式;設計時也要考慮實際情況;

  • 反範式化設計:

    • 反範式化是針對範式化而言的,在前面介紹了數據庫設計的範式,所謂的範式,所謂的反範式化就是爲了性能和讀取效率的考慮而適當的對數據庫設計範式的要求進行違反,而允許存在少量的數據冗餘,換句話來說反範式化就是使用空間換取時間;
    • 我們在設計表的過程中不能完全按照範式化的要求進行設計,要考慮以後如何使用表;有的時候,範式化設計需要關聯幾個表才能查詢到需要的數據;但是進行反範式化設計時能一張表就能查詢到所需要的數據,極大的節省了性能;
  • 範式化設計的優缺點

    • 優點:

      • 可以儘量的減少數據冗餘,數據表更新快,體積小;
      • 範式化的更新操作比反範式化更快;
      • 範式化的表通常比反範式化更小;
    • 缺點:

      • 對於 查詢需要對多個表進行關聯
      • 更難進行索引優化;
  • 反範式化的優缺點

    • 優點:

      • 可以減少表的關聯
      • 可以更好的進行索引優化
    • 缺點:

      • 存在數據冗餘及數據維護異常;
      • 對數據的修改需要更多的成本;(比如一條記錄更新了,但是其他地方也有此字段,也需要進行整體更新;)

4.3 物理設計

  • 物理設計涉及的內容

    1. 定義數據庫、表ji字段的命名規範
    2. 選擇合適的存儲引擎
    3. 爲表中的字段選擇合適的數據類型
    4. 建立數據庫結構;
  • 定義數據庫、表及字段的命名規範

    1. 數據庫、表及字段的命名要遵守可讀性規則;
    2. 數據庫、表及字段的命名要遵守表意性原則
    3. 數據庫、表及字段的命名要遵守長名原則;
  • 選擇合適的存儲引擎

存儲引擎 事務 鎖粒度 主要應用 忌用
MyISAM 不支持 支持併發插入的表級鎖 SELECT,INSERT 讀寫操作頻繁
MRG 不支持 支持併發插入的表級鎖 分段歸檔,數據倉庫 全局查找過多的場景
Innodb 支持 支持MVCC的行級鎖 事務處理
Archive 不支持 行級鎖 日誌記錄,只支持insert,select 需要隨機讀取,更新,刪除
Ndb cluster 支持 行級鎖 高可用性 大部分應用;

4.4 數據類型的選擇

  • 爲表中的字段選擇合適的數字類型
  • 當一個列可以選擇多種數據
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章