官方 Memcached 插件讓 InnoDB 直接對外提供 Memcached 協議(11211 埠),省去獨立 Cache 集群、解決雙寫一致性、借助主從複制實現 Cache 高可用。本文從安裝到生產落地全流程解析。
cmake -DWITH_INNODB_MEMCACHED=ON ... make && make install # 初始化資料庫後 mysql> INSTALL PLUGIN daemon_memcached SONAME 'libmemcached.so'; # 驗證 echo "stats" | nc localhost 11211
預設埠 11211,支援二進制/文本協議。
安裝腳本建立 innodb_memcache 庫三張表:
cache_policies:innodb_only / cache_only / caching(預設)。config_options:separator(預設 |)、table_map_delimiter(預設 .)。containers:映射 Memcached Key → InnoDB 表欄位。INSERT INTO innodb_memcache.containers
(name, db_schema, db_table, key_columns, value_columns, flags, cas_column, expire_time_column, unique_idx_name_on_key)
VALUES
('default', 'test', 'users', 'username', 'password|email', 'flags', 'cas_column', 'expire_time_column', 'username');
欄位要求:
key_columns:CHAR/VARCHAR ≤ 250 字元,必須有唯一索引。value_columns:CHAR/VARCHAR/BLOB,多欄位用 separator 連接。flags、cas_column (BIGINT)、expire_time_column (INT) 必須存在,無業務含義也要建立。-- 建表
CREATE TABLE users (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(15) NOT NULL UNIQUE,
password VARCHAR(32) NOT NULL,
email VARCHAR(50) NOT NULL,
flags INT UNSIGNED DEFAULT 0,
cas_column BIGINT UNSIGNED DEFAULT 0,
expire_time_column INT UNSIGNED DEFAULT 0
) ENGINE=InnoDB;
-- 配置 container(如上)
-- 插入測試資料
INSERT INTO users(username,password,email) VALUES
('foo','ffff...','foo@domain.com'),
('bar','bbbb...','bar@domain.com');
-- Memcached 協議查詢
echo "get foo bar" | nc localhost 11211
# VALUE foo 0 47 ffff...|foo@domain.com
# VALUE bar 0 47 bbbb...|bar@domain.com
| 限制 | 影響 | 對策 |
|---|---|---|
| key_columns 必須 CHAR/VARCHAR ≤250 | 長 Key/二進位 Key 無法直接用 | 應用層 Hash 後存儲 |
| 需建立 flags/cas/expire 三欄 | 侵入業務表結構 | 建立專用 Cache 表,觸發器同步 |
| separator 衝突 | value 含 | 導致解析錯誤 | 改用罕見分隔符(如 |||)並重啟插件 |
| 寫入支援有限 | set/add/replace 可用,但複雜事務不支援 | 寫入走 SQL,讀取走 Memcached |
| 無原生集群/複製 | 依賴 MySQL 主從複制同步 .ibd | 配合 GTID 半同步確保一致性 |
InnoDB Memcached 插件適合「讀多寫少、Key-Value 存取、強一致性要求、不想維護獨立 Cache 集群」的場景。生產建議:業務表與 Cache 表分離、寫入走 SQL、讀取走 Memcached、監控 daemon_memcached_* 狀態變數。