某限時特賣 B2C 業務:峰值 5000 條特賣信息、頻繁更新、純數值類型、單行 <100 字節、拒絕引入 Redis/Memcached、拒絕自研內存組件。MySQL MEMORY 引擎 + 觸發器同步持久化 成為極致性價比方案。本文解析 MEMORY 特性、觸發器機制、業務建模、壓測驗證、生產避坑全鏈路。
| 特性 | 支援情況 | 備註 |
|---|---|---|
| 事務 | ❌ 不支援 | 無回滾,觸發器同步需考慮一致性 |
| 鎖粒度 | 表級鎖 | 高併發寫入易衝突,需主鍵精準定位 |
| 索引類型 | HASH(預設)、BTREE | 等值查詢用 HASH,範圍排序用 BTREE |
| 數據持久化 | ❌ 僅存儲 .frm 定義文件 | 重啟數據全丟,必須外部同步 |
| 字段類型 | 除 BLOB/TEXT 外全支援 | VARCHAR 實際按 CHAR 固定長度存儲 |
| 最大表大小 | 受 max_heap_table_size 限制 | 預設 16MB,需按業務調大 |
| 刪除行空間回收 | 需 ALTER TABLE ... ENGINE=MEMORY 或 TRUNCATE | 單純 DELETE 僅標記,不釋放內存 |
CREATE TRIGGER tri_memory_update
AFTER UPDATE ON t_memory FOR EACH ROW
BEGIN
UPDATE t_innodb SET username=NEW.username WHERE username=OLD.username;
END;
關鍵限制:
OLD.col 唯讀,NEW.col 可修改(SET NEW.col=val)。-- 內存表:承載線上高頻 UPDATE
CREATE TABLE t_memory (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
username VARCHAR(40) NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY idx_username (username)
) ENGINE=MEMORY DEFAULT CHARSET=utf8;
-- 持久表:InnoDB 保證數據安全
CREATE TABLE t_innodb (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
username VARCHAR(40) NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY idx_username (username)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- 初始化:持久表 → 內存表
INSERT INTO t_memory SELECT * FROM t_innodb;
t_memory 執行高併發 UPDATE ... WHERE id=?(主鍵定位,表鎖衝突最小)。t_innodb,數據強一致。KILL -9 mysqld 強制重啟:t_memory 清空,t_innodb 保留最新數據。INSERT INTO t_memory SELECT * FROM t_innodb 熱載,秒級恢復服務。結果:單機 5000 條記錄、純數值更新、QPS 萬級、延遲亞毫秒,滿足業務 SLA。
ALTER TABLE ... ENGINE=MEMORY 回收刪除空間:防內存洩漏。WHERE id=? 避免全表掃描鎖表。innodb_buffer_pool_size 足夠大時)。max_heap_table_size 留 20% 冗餘:防 OOM 導致實例崩潰。| 維度 | 適用 | 不適用 |
|---|---|---|
| 數據規模 | ≤ 5000 行 / <100MB | 大數據量、大字段 |
| 訪問模式 | 高頻主鍵點查/更新 | 複雜關聯、範圍掃描、全文搜尋 |
| 持久化要求 | 最終一致性可接受(觸發器同步) | 強一致性、分佈式事務 |
| 運維能力 | 無 Redis 運維經驗、追求極簡架構 | 已有成熟 Redis 體系 |
MEMORY + 觸發器不是銀彈,但對「小數據、高頻更新、純數值、極簡運維」的特定場景,它以零新增組件、零代碼改造、原生 SQL 體驗 實現了萬級 QPS、亞毫秒延遲、秒級災難恢復。關鍵在於:認清引擎邊界、嚴守八條鐵律、建立熱載恢復 SOP。當業務突破邊界時,平滑遷移至 Redis/InnoDB 才是架構演進的正道。