redis整個db都是一個哈希字典表(不支持范圍查找), 那這樣的話keys命令需要遍歷db里所有的key嗎??渣浪多年前就熱衷於用xxx_yyy_zzz_*的方式去匹配key了,為什么他們熱衷於這樣做, 是不是redis有特殊的優化技巧呢? 帶着這些疑問下載了最新版Redis代碼。
目標:
1. 定位keys的實現方式, 是否真的低性能。--done
2. 定位redis-cluster里主機不分發keys給集群里其它主機的原因。 --done
keys命令確實需要遍歷整個數據庫,詳情 見db.c::keysCommand
1. 服務器啟動階段,server.c::initServerConfig()調用populateCommandTable加載命令列表;
redis所支持的命令列表是下面硬編碼 , 可以看到keys命令處理函數(keysCommand)的邏輯是, 遍歷數據庫的所有key.
struct redisCommand redisCommandTable[] = { {"module",moduleCommand,-2,"as",0,NULL,0,0,0,0,0}, {"get",getCommand,2,"rF",0,NULL,1,1,1,0,0}, {"set",setCommand,-3,"wm",0,NULL,1,1,1,0,0}, //... {"keys",keysCommand,2,"rS",0,NULL,0,0,0,0,0}, //... };
keys命令不帶key,且redis沒有定義匯總各節點查詢結果的邏輯,所以不路由keys命令。詳情見server.c::processCommand()
看了上述代碼,對渣浪的行為產生了深深疑惑。
小結
1. keys命令是通過遍歷全部db下key再過濾實現的。
2. keys命令不會被cluster路由給其它集群節點,更不會返回集群各節點keys結果的匯總結果。