首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

MySQL 當 NoSQL 用:HandlerSocket 實現 75 萬 QPS 實戰解析

     編輯:MySQL 綜合教學

MySQL 當 NoSQL 用:HandlerSocket 實現 75 萬 QPS 實戰解析

來源:Using MySQL as a NoSQL - A story for exceeding 750,000 qps on a commodity server

DeNA 團隊為何放棄 Memcached+MySQL 架構,轉而單靠 MySQL 達到 75 萬 QPS?本文深度剖析 SQL 層開銷、HandlerSocket 原理、安裝部署、基準測試與生產落地經驗。

一、為什麼傳統 MySQL 跑不滿 CPU?

基準測試環境:Dell PowerEdge R710,Nehalem 8 核 2.53GHz,32GB 內存,MySQL 5.1.50 InnoDB,全內存數據。

方案QPS%us%sy瓶頸分析
MySQL via SQL105,00060%28%SQL 解析、優化器、表鎖、互斥鎖
Memcached420,0008%88%網絡 I/O、系統調用
MySQL via HandlerSocket750,000+45%53%網絡驅動、InnoDB 核心邏輯

OProfile 火焰圖顯示:MYSQLparse()、JOIN::optimize()、my_pthread_fastmutex_lock() 佔據大量 CPU。MySQL 每次 PK 查詢都要經歷 解析 → 開表/鎖表 → 優化器 → 解鎖/關表,且全局互斥鎖(LOCK_open、LOCK_thread_count)導致嚴重併發爭搶。

二、HandlerSocket 核心優勢

  • 繞過 SQL 層:以 MySQL Daemon Plugin 形式運行,直接調用 InnoDB 存儲引擎 API。
  • 連線複用 & 表緩存:Worker 線程池 + epoll,連線輕量;已打開表緩存,避免重複 open/close 產生的互斥爭搶。
  • 協議精簡:基於文本、Tab 分隔,類似 Memcached 協議,網絡封包更小。
  • 請求批次處理:Worker 聚合併發請求一次性執行,犧牲微小延換取高吞吐,減少 fsync()、複製延遲。
  • 零重複緩存:數據僅駐留 InnoDB Buffer Pool,無 Memcached+InnoDB 雙份拷貝。
  • 崩潰安全:後端仍是 InnoDB,innodb_flush_log_at_trx_commit=1 保證 <1s 數據零丟失。
  • 無縫 SQL 互通:同一實例仍可跑複雜報表 SQL,運維監控(SHOW GLOBAL STATUS、SHOW ENGINE INNODB STATUS)完全復用。

三、安裝與部署

# 1. 下載源碼
git clone https://github.com/ahiguti/HandlerSocket-Plugin-for-MySQL.git
cd HandlerSocket-Plugin-for-MySQL

# 2. 編譯(需 MySQL 源碼與安裝路徑)
./configure --with-mysql-source=/path/to/mysql-source --with-mysql-bindir=/path/to/mysql/bin
make && make install

# 3. 安裝插件
mysql> INSTALL PLUGIN handlersocket SONAME 'handlersocket.so';

# 4. 配置 my.cnf [mysqld] 區段
loose_handlersocket_port = 9998      # 讀寫端口
loose_handlersocket_port_wr = 9999   # 僅寫端口(可選)
loose_handlersocket_threads = 16     # Worker 線程數,建議 CPU 核心數 x 2
loose_handlersocket_threads_wr = 8

四、客戶端開發範例

Perl 範例

use Net::HandlerSocket;
my $hs = Net::HandlerSocket->new({ host => '127.0.0.1', port => 9998 });
# open_index(index_id, db, table, index_name, columns)
$hs->open_index(0, 'test', 'user', 'PRIMARY', 'user_name,user_email,created');
# execute_single(index_id, op, values, limit, offset)
my $res = $hs->execute_single(0, '=', ['101'], 1, 0);
die $hs->get_error() if $res->[0] != 0;
shift @$res;
print "$res->[0]\t$res->[1]\t$res->[2]\n";  # user_name, email, created
$hs->close();

Telnet 手工測試

$ telnet 127.0.0.1 9998
P 0 test user PRIMARY user_name,user_email,created
0 1 0 = 1 101
0 3 Yukari Takeba   yukari.takeba@dena.jp   2010-02-03 11:22:33

綠色行為請求封包,字段以 Tab 分隔。

五、支援的查詢模式

  • 主鍵/唯一索引精確查詢(=)
  • 非唯一索引範圍掃描(>, >=, <, <=)
  • LIMIT / OFFSET
  • INSERT / UPDATE / DELETE(單行)
  • multi_get:單次網絡往返獲取多鍵值(類似 IN (1,2,3))

不支援:無索引全表掃描、JOIN、聚合、子查詢、事務(自動提交模式)。

六、生產落地經驗

  • DeNA 生產環境已替換大量 Memcached + 從庫,整體網絡流量下降 30%+。
  • 監控指標:Innodb_rows_read 直接反映 HandlerSocket 吞吐,SHOW GLOBAL STATUS 即可觀測。
  • 適用場景:用戶資料、Session、計數器、排行榜等高頻單鍵訪問。
  • 不適用場景:磁盤 I/O 瓶頸(HDD)、複雜關聯查詢、需 ACID 事務的業務。

七、已知限制與避坑

限制應對
無內建認證/授權防火牆限制來源 IP;應用層做租戶隔離
Worker 線程數固定根據 CPU 核心數設定,避免過多線程上下文切換
不支援事務單行寫入自動提交;多行一致性需應用層補償
DDL 期間表會關閉低峰期變更結構,或使用 pt-online-schema-change

八、總結

HandlerSocket 證明:MySQL 存儲引擎層極其高效,瓶頸在 SQL 層。通過 Plugin 形式直連 InnoDB,無需遷移數據、修改內核、引入新組件,即可獲得媲美甚至超越專業 NoSQL 的極致性能。對於「核心業務用 InnoDB,熱點讀寫用 HandlerSocket」的混合架構,是極具性價比的演進路徑。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved