州公 發表於 2025-12-8 19:59:00

数据库性能实测:Docker 开销、连接方式、MySQL vs PostgreSQL 全面对比

<blockquote>
<p>本文通过多组对照实验,测试 Docker 容器化开销、网络连接方式、数据库版本、MySQL 与 PostgreSQL 性能差异,揭示影响数据库性能的真正因素。</p>
</blockquote>
<h2>测试背景</h2>
<p>网上关于数据库性能的说法众说纷纭:</p>
<ul>
<li>"Docker 部署数据库有性能损耗"</li>
<li>"PostgreSQL 比 MySQL 快"</li>
<li>"Unix socket 比 TCP 快"</li>
</ul>
<p>为了搞清楚真相,我在阿里云 ECS 上进行了一系列对照实验。</p>
<p><strong>测试环境:</strong></p>
<ul>
<li>服务器:阿里云 ECS 2核2G</li>
<li>系统:Alibaba Cloud Linux 8 (kernel 5.10.134)</li>
<li>MySQL:8.0.27 / 8.0.44</li>
<li>PostgreSQL:13.22</li>
<li>测试工具:sysbench 1.0.20 / pgbench</li>
</ul>
<h2>一、Docker 桥接网络:性能杀手</h2>
<h3>初始测试</h3>
<p>第一次测试时,我用最简单的方式启动 Docker MySQL:</p>
<pre><code class="language-bash">docker run -d -p 3307:3306 mysql:8.0
</code></pre>
<p>结果让我大吃一惊:</p>
<table>
<thead>
<tr><th>并发数</th><th>裸机(Unix socket)</th><th>Docker(桥接网络)</th><th>差距</th></tr>
</thead>
<tbody>
<tr>
<td>50</td>
<td>625 QPS</td>
<td>63 QPS</td>
<td><strong>10倍</strong></td>
</tr>
<tr>
<td>100</td>
<td>667 QPS</td>
<td>64 QPS</td>
<td><strong>10倍</strong></td>
</tr>
<tr>
<td>500+</td>
<td>正常</td>
<td><strong>崩溃</strong></td>
<td>-</td>
</tr>
</tbody>
</table>
<h3>问题分析</h3>
<p>这个对比极不公平:</p>
<ul>
<li>裸机用 Unix socket,Docker 用 TCP</li>
<li>Docker 使用桥接网络 + NAT 端口转发</li>
<li>Docker 默认 max_connections=151</li>
</ul>
<p><strong>桥接网络的 NAT 转发是性能杀手,不是 Docker 本身。</strong></p>
<h2>二、Unix Socket vs TCP:23% 的差距</h2>
<p>同一台裸机 MySQL,测试不同连接方式:</p>
<pre><code class="language-bash"># Unix socket
sysbench --mysql-socket=/var/lib/mysql/mysql.sock ...

# TCP
sysbench --mysql-host=127.0.0.1 --mysql-port=3306 ...
</code></pre>
<table>
<thead>
<tr><th>连接方式</th><th>QPS</th><th>差异</th></tr>
</thead>
<tbody>
<tr>
<td>Unix Socket</td>
<td>3,476</td>
<td>基准</td>
</tr>
<tr>
<td>TCP 127.0.0.1</td>
<td>2,662</td>
<td><strong>-23%</strong></td>
</tr>
</tbody>
</table>
<p><strong>Unix socket 直接通过内核通信,省去 TCP 协议栈开销。</strong></p>
<h2>三、Docker vs 裸机:几乎无差异</h2>
<h3>公平测试条件</h3>
<ul>
<li>同版本:MySQL 8.0.44</li>
<li>同数据:Docker 挂载裸机数据目录</li>
<li>同连接:都用 Unix socket</li>
<li>清缓存:<code>echo 3 &gt; /proc/sys/vm/drop_caches</code></li>
</ul>
<pre><code class="language-bash">docker run -d \
-v /var/lib/mysql:/var/lib/mysql \
-v /root/mysql-docker/socket:/var/run/mysqld \
mysql:8.0.44
</code></pre>
<h3>测试结果</h3>
<table>
<thead>
<tr><th>线程数</th><th>Docker QPS</th><th>裸机 QPS</th><th>差异</th></tr>
</thead>
<tbody>
<tr>
<td>50</td>
<td>3,567</td>
<td>3,454</td>
<td>+3%</td>
</tr>
<tr>
<td>100</td>
<td>3,347</td>
<td>3,362</td>
<td><strong>-0.4%</strong></td>
</tr>
</tbody>
</table>
<p><strong>结论:同等条件下,Docker 和裸机性能几乎完全一致!</strong></p>
<h2>四、MySQL 版本:新版不一定更快</h2>
<table>
<thead>
<tr><th>版本</th><th>50线程 TPS</th></tr>
</thead>
<tbody>
<tr>
<td>8.0.27</td>
<td>5,366</td>
</tr>
<tr>
<td>8.0.44</td>
<td>5,016</td>
</tr>
</tbody>
</table>
<p><strong>8.0.27 比 8.0.44 快约 7%</strong>,升级需谨慎。</p>
<h2>五、MySQL vs PostgreSQL:MySQL 更快</h2>
<p>这是最有争议的话题。为保证公平:</p>
<ul>
<li>相同数据量:10 万行</li>
<li>相同测试类型:单点查询(point select)</li>
<li>相同并发数</li>
</ul>
<p><strong>注意 TPS vs QPS</strong>:</p>
<ul>
<li><code>pgbench -S</code>:每事务 = 1 个 SELECT → TPS = QPS</li>
<li><code>sysbench oltp_point_select</code>:每事务 = 1 个 SELECT → TPS = QPS</li>
<li><code>sysbench oltp_read_only</code>:每事务 = 16 个查询 → QPS = TPS × 16</li>
</ul>
<h3>测试结果</h3>
<table>
<thead>
<tr><th>线程</th><th>MySQL TPS</th><th>PostgreSQL TPS</th><th>MySQL 优势</th></tr>
</thead>
<tbody>
<tr>
<td>10</td>
<td>6,410</td>
<td>5,373</td>
<td><strong>+19%</strong></td>
</tr>
<tr>
<td>50</td>
<td>6,502</td>
<td>5,267</td>
<td><strong>+23%</strong></td>
</tr>
<tr>
<td>100</td>
<td>6,590</td>
<td>4,753</td>
<td><strong>+39%</strong></td>
</tr>
</tbody>
</table>
<h3>关键发现</h3>
<ol>
<li><strong>MySQL 吞吐量更高</strong>:各并发级别都领先 20-40%</li>
<li><strong>MySQL 高并发更稳定</strong>:并发增加,性能略有提升</li>
<li><strong>PostgreSQL 高并发下降</strong>:100 线程比 10 线程降了 12%</li>
</ol>
<h2>六、踩坑记录:sysbench table-size 参数</h2>
<h3>现象</h3>
<p>早期测试看到 5000+ QPS 的"好成绩",后来发现是假象。</p>
<h3>原因</h3>
<p><code>table-size</code> 参数告诉 sysbench 表有多少行,但实际数据可能不匹配:</p>
<table>
<thead>
<tr><th>table-size 参数</th><th>实际行数</th><th>空查询比例</th><th>QPS</th></tr>
</thead>
<tbody>
<tr>
<td>10,000</td>
<td>10,000</td>
<td>0%</td>
<td>3,550</td>
</tr>
<tr>
<td>31,898</td>
<td>10,000</td>
<td>68%</td>
<td>5,016</td>
</tr>
<tr>
<td>500,000</td>
<td>10,000</td>
<td>98%</td>
<td>5,008</td>
</tr>
</tbody>
</table>
<p>空查询返回更快,造成虚假高性能。</p>
<h3>正确做法</h3>
<pre><code class="language-bash"># 先检查实际行数
mysql -e "SELECT COUNT(*) FROM sxsz_db.sbtest1;"

# table-size 必须与实际行数一致
sysbench --table-size=10000 ...
</code></pre>
<h2>七、性能影响因素排序</h2>
<table>
<thead>
<tr><th>因素</th><th>性能影响</th><th>说明</th></tr>
</thead>
<tbody>
<tr>
<td>桥接网络 vs Host/Socket</td>
<td><strong>~10倍</strong></td>
<td>NAT 转发开销巨大</td>
</tr>
<tr>
<td>MySQL vs PostgreSQL</td>
<td><strong>~20-40%</strong></td>
<td>MySQL 单点查询更快</td>
</tr>
<tr>
<td>Unix socket vs TCP</td>
<td><strong>~23%</strong></td>
<td>内核直接通信更快</td>
</tr>
<tr>
<td>MySQL 版本</td>
<td><strong>~7%</strong></td>
<td>新版不一定更快</td>
</tr>
<tr>
<td>Docker 容器开销</td>
<td><strong>&lt;5%</strong></td>
<td>几乎可忽略</td>
</tr>
</tbody>
</table>
<h2>八、最佳实践</h2>
<h3>Docker MySQL 高性能配置</h3>
<pre><code class="language-bash">docker run -d \
--name mysql \
--network=host \
-v /data/mysql:/var/lib/mysql \
mysql:8.0 \
--max_connections=2000
</code></pre>
<p>或使用 Unix socket 挂载:</p>
<pre><code class="language-bash">docker run -d \
--name mysql \
-v /data/mysql:/var/lib/mysql \
-v /var/run/mysqld:/var/run/mysqld \
mysql:8.0
</code></pre>
<h3>应用连接字符串</h3>
<pre><code class="language-go">// Unix socket(最快)
dsn := "user:pass@unix(/var/run/mysqld/mysqld.sock)/dbname"

// TCP(稍慢,但更通用)
dsn := "user:pass@tcp(127.0.0.1:3306)/dbname"
</code></pre>
<h3>MySQL vs PostgreSQL 选型建议</h3>
<table>
<thead>
<tr><th>场景</th><th>推荐</th></tr>
</thead>
<tbody>
<tr>
<td>高并发简单查询</td>
<td>MySQL</td>
</tr>
<tr>
<td>复杂查询/分析</td>
<td>PostgreSQL</td>
</tr>
<tr>
<td>需要高级特性(JSON、全文搜索)</td>
<td>各有千秋,需具体评估</td>
</tr>
</tbody>
</table>
<h2>总结</h2>
<ol>
<li><strong>Docker 本身开销可忽略</strong>(&lt;5%),桥接网络才是性能杀手</li>
<li><strong>Unix socket 比 TCP 快 23%</strong>,优先使用</li>
<li><strong>MySQL 单点查询比 PostgreSQL 快 20-40%</strong>,高并发下差距更大</li>
<li><strong>测试方法很重要</strong>,参数错误会得出错误结论</li>
</ol><hr>
<p><strong>测试日期</strong>:2025年12月<br>
<strong>测试环境</strong>:阿里云 ECS 2核2G,Alibaba Cloud Linux 8<br>
<strong>测试工具</strong>:sysbench 1.0.20,pgbench (PostgreSQL 13.22)</p>

</div>
<div id="MySignature" role="contentinfo">
    <p>欢迎关注我的微信公众号「猫哥学前班」</p>
<div><img src="https://images2015.cnblogs.com/blog/520689/201511/520689-20151129183429141-22383570.png" width="140" height="140"></div><br><br>
来源:https://www.cnblogs.com/kaiye/p/19323468
頁: [1]
查看完整版本: 数据库性能实测:Docker 开销、连接方式、MySQL vs PostgreSQL 全面对比