博客 / 詳情

返回

數據庫性能實測:Docker 開銷、連接方式、MySQL vs PostgreSQL 全面對比

本文通過多組對照實驗,測試 Docker 容器化開銷、網絡連接方式、數據庫版本、MySQL 與 PostgreSQL 性能差異,揭示影響數據庫性能的真正因素。

測試背景

網上關於數據庫性能的説法眾説紛紜:

  • "Docker 部署數據庫有性能損耗"
  • "PostgreSQL 比 MySQL 快"
  • "Unix socket 比 TCP 快"

為了搞清楚真相,我在阿里雲 ECS 上進行了一系列對照實驗。

測試環境:

  • 服務器:阿里雲 ECS 2核2G
  • 系統:Alibaba Cloud Linux 8 (kernel 5.10.134)
  • MySQL:8.0.27 / 8.0.44
  • PostgreSQL:13.22
  • 測試工具:sysbench 1.0.20 / pgbench

一、Docker 橋接網絡:性能殺手

初始測試

第一次測試時,我用最簡單的方式啓動 Docker MySQL:

docker run -d -p 3307:3306 mysql:8.0

結果讓我大吃一驚:

併發數 裸機(Unix socket) Docker(橋接網絡) 差距
50 625 QPS 63 QPS 10倍
100 667 QPS 64 QPS 10倍
500+ 正常 崩潰 -

問題分析

這個對比極不公平:

  • 裸機用 Unix socket,Docker 用 TCP
  • Docker 使用橋接網絡 + NAT 端口轉發
  • Docker 默認 max_connections=151

橋接網絡的 NAT 轉發是性能殺手,不是 Docker 本身。

二、Unix Socket vs TCP:23% 的差距

同一台裸機 MySQL,測試不同連接方式:

# Unix socket
sysbench --mysql-socket=/var/lib/mysql/mysql.sock ...

# TCP
sysbench --mysql-host=127.0.0.1 --mysql-port=3306 ...
連接方式 QPS 差異
Unix Socket 3,476 基準
TCP 127.0.0.1 2,662 -23%

Unix socket 直接通過內核通信,省去 TCP 協議棧開銷。

三、Docker vs 裸機:幾乎無差異

公平測試條件

  • 同版本:MySQL 8.0.44
  • 同數據:Docker 掛載裸機數據目錄
  • 同連接:都用 Unix socket
  • 清緩存:echo 3 > /proc/sys/vm/drop_caches
docker run -d \
  -v /var/lib/mysql:/var/lib/mysql \
  -v /root/mysql-docker/socket:/var/run/mysqld \
  mysql:8.0.44

測試結果

線程數 Docker QPS 裸機 QPS 差異
50 3,567 3,454 +3%
100 3,347 3,362 -0.4%

結論:同等條件下,Docker 和裸機性能幾乎完全一致!

四、MySQL 版本:新版不一定更快

版本 50線程 TPS
8.0.27 5,366
8.0.44 5,016

8.0.27 比 8.0.44 快約 7%,升級需謹慎。

五、MySQL vs PostgreSQL:MySQL 更快

這是最有爭議的話題。為保證公平:

  • 相同數據量:10 萬行
  • 相同測試類型:單點查詢(point select)
  • 相同併發數

注意 TPS vs QPS

  • pgbench -S:每事務 = 1 個 SELECT → TPS = QPS
  • sysbench oltp_point_select:每事務 = 1 個 SELECT → TPS = QPS
  • sysbench oltp_read_only:每事務 = 16 個查詢 → QPS = TPS × 16

測試結果

線程 MySQL TPS PostgreSQL TPS MySQL 優勢
10 6,410 5,373 +19%
50 6,502 5,267 +23%
100 6,590 4,753 +39%

關鍵發現

  1. MySQL 吞吐量更高:各併發級別都領先 20-40%
  2. MySQL 高併發更穩定:併發增加,性能略有提升
  3. PostgreSQL 高併發下降:100 線程比 10 線程降了 12%

六、踩坑記錄:sysbench table-size 參數

現象

早期測試看到 5000+ QPS 的"好成績",後來發現是假象。

原因

table-size 參數告訴 sysbench 表有多少行,但實際數據可能不匹配:

table-size 參數 實際行數 空查詢比例 QPS
10,000 10,000 0% 3,550
31,898 10,000 68% 5,016
500,000 10,000 98% 5,008

空查詢返回更快,造成虛假高性能。

正確做法

# 先檢查實際行數
mysql -e "SELECT COUNT(*) FROM sxsz_db.sbtest1;"

# table-size 必須與實際行數一致
sysbench --table-size=10000 ...

七、性能影響因素排序

因素 性能影響 説明
橋接網絡 vs Host/Socket ~10倍 NAT 轉發開銷巨大
MySQL vs PostgreSQL ~20-40% MySQL 單點查詢更快
Unix socket vs TCP ~23% 內核直接通信更快
MySQL 版本 ~7% 新版不一定更快
Docker 容器開銷 <5% 幾乎可忽略

八、最佳實踐

Docker MySQL 高性能配置

docker run -d \
  --name mysql \
  --network=host \
  -v /data/mysql:/var/lib/mysql \
  mysql:8.0 \
  --max_connections=2000

或使用 Unix socket 掛載:

docker run -d \
  --name mysql \
  -v /data/mysql:/var/lib/mysql \
  -v /var/run/mysqld:/var/run/mysqld \
  mysql:8.0

應用連接字符串

// Unix socket(最快)
dsn := "user:pass@unix(/var/run/mysqld/mysqld.sock)/dbname"

// TCP(稍慢,但更通用)
dsn := "user:pass@tcp(127.0.0.1:3306)/dbname"

MySQL vs PostgreSQL 選型建議

場景 推薦
高併發簡單查詢 MySQL
複雜查詢/分析 PostgreSQL
需要高級特性(JSON、全文搜索) 各有千秋,需具體評估

總結

  1. Docker 本身開銷可忽略(<5%),橋接網絡才是性能殺手
  2. Unix socket 比 TCP 快 23%,優先使用
  3. MySQL 單點查詢比 PostgreSQL 快 20-40%,高併發下差距更大
  4. 測試方法很重要,參數錯誤會得出錯誤結論

測試日期:2025年12月
測試環境:阿里雲 ECS 2核2G,Alibaba Cloud Linux 8
測試工具:sysbench 1.0.20,pgbench (PostgreSQL 13.22)

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.