本文介紹訪問雲資料庫 Tair(相容 Redis)時的常見報錯與解決方案。
報錯概覽
分類 | 報錯項 |
Redis通用異常 | |
redis-cli | |
Proxy(代理模式)通用異常 | |
Lua指令碼與事務(Transaction) | |
Jedis用戶端 | |
Lettuce用戶端 | |
Redisson用戶端 | |
Spring Data Redis用戶端 | |
StackExchange.Redis用戶端 | |
Predis用戶端 | |
phpredis用戶端 | |
Go-redis用戶端 | |
node-redis用戶端 |
Redis通用異常
ERR illegal address
可能原因:未將用戶端的IP地址添加至Tair執行個體的白名單中。
解決方案:將用戶端的IP地址添加入至Tair執行個體的白名單中,具體操作請參見串連診斷。
ERR sentinel compatibility mode is disabled
可能原因:未開啟Tair執行個體的Sentinel相容。
解決方案:在控制台開啟Sentinel相容,具體操作請參見開啟Sentinel相容。
ERR max number of clients reached
可能原因:用戶端的串連數超過了Tair執行個體的最大串連數。
NOAUTH Authentication required
可能原因:Tair執行個體設定了密碼鑒權,但用戶端沒有提供密碼或提供了錯誤的密碼。
解決方案:請使用正確的帳號密碼進行訪問,更多資訊請參見執行個體的登入方式。
若您使用Lettuce 6.4.0.RELEASE至6.4.1.RELEASE版本的用戶端,即使提供了正確密碼,仍可能會出現該報錯。該問題是由於Lettuce在支援Client setinfo時引入的,並已在6.4.2.RELEASE版本中修複,詳情請參見redis/lettuce#3035。
如遇到該問題,您可以選擇手動切換RESP協議為RESP2,或者將用戶端升級至Lettuce 6.4.2.RELEASE版本及以上,如果您仍在使用Spring Data Redis用戶端,建議使用Spring Data Redis 3.4.2及以上版本。
WRONGPASS invalid username-password pair
可能原因:密碼錯誤。
解決方案:請使用正確的帳號密碼進行訪問,更多資訊請參見執行個體的登入方式。
若執行個體使用Sentinel模式訪問,請參見使用Sentinel相容模式串連執行個體。
ERR invalid password
可能原因:密碼錯誤。
解決方案:請使用正確的帳號密碼進行訪問,更多資訊請參見執行個體的登入方式。
若在DMS中產生該報錯,則有可能是DMS儲存了之前登入的帳號密碼,而此時密碼發生了修改。您可以在DMS資料庫執行個體列表中,按右鍵目標執行個體,選擇編輯執行個體,在資料庫密碼文字框中輸入新的密碼進行重試。
Connection reset by peer
可能原因:用戶端串連被關閉,通常是由於用戶端緩衝區異常而關閉用戶端串連。
解決方案:檢查應用側代碼或調整用戶端Buffer的大小,更多資訊請參見Unexpected end of stream章節。
UnknownHostException
或failed to connect: xxx.redis.rds.aliyuncs.com could not be resolved。
可能原因:用戶端無法正常解析Tair執行個體的網域名稱地址。
解決方案:請設定正確的DNS伺服器位址,更多資訊請參見解決因網域名稱解析失敗導致的串連問題。
OOM command not allowed when used memory > 'maxmemory'
可能原因:Tair執行個體已使用的記憶體超過該執行個體的最大配置(maxmemory)。
如果是Tair叢集執行個體,可能是其中一個節點已使用的記憶體已超過該節點的最大配置。
WRONGTYPE Operation against a key holding the wrong kind of value
可能原因:命令使用錯誤,例如對String資料類型執行HASH命令。
解決方案:修改錯誤碼或命令,更多資訊請參Redis Commands。
ERR unknown command 'xxx'
可能原因:當前的執行個體不支援此命令。
如出現:ERR unknown command 'WAIT',是由於雲上叢集架構代理模式不支援WAIT命令,需要用直連模式。
解決方案:檢查當前執行個體版本的命令支援情況,更多資訊請參見Tair(企業版)命令支援與限制、Redis開源版命令支援與限制及叢集架構與讀寫分離執行個體的命令限制。
最新小版本將提供更豐富的功能與穩定的服務,建議將執行個體的小版本升級到最新,具體操作請參見升級小版本與代理版本。
ERR command 'xxx' not support for your account
可能原因:阿里雲禁止使用者執行某些Tair命令,或您手動在#no_loose_disabled-commands參數中配置了禁止執行的命令。更多資訊請參見Redis開源版命令支援和禁用高風險命令。
解決方案:若需執行您禁用的命令,您可以在#no_loose_disabled-commands參數中刪除對應命令。
NOPERM this user has no permissions to run the 'xxx'
可能原因:阿里雲禁止使用者執行某些Tair命令,或您手動在#no_loose_disabled-commands參數中配置了禁止執行的命令。更多資訊請參見Redis開源版命令支援和禁用高風險命令。
解決方案:若需執行您禁用的命令,您可以在#no_loose_disabled-commands參數中刪除對應命令。
ERR FLUSHDB is not allowed in migrating mode
可能原因:Tair雲原生版叢集架構執行個體在執行增加或減少資料節點時,禁止使用FLUSHDB或FLUSHALL命令。
解決方案:等待Tair雲原生版叢集架構執行個體執行增加或減少資料節點結束,更多資訊請參見調整叢集分區數。
CROSSSLOT Keys in request don't hash to the same slot
可能原因:Tair叢集架構直連模式不支援跨Slot執行涉及多Key的命令,例如DEL、MSET、MGET等。
解決方案:
在執行操作命令前增加確認Key Slot的邏輯(例如通過CLUSTER KEYSLOT命令),確保單個命令執行的所有Key在一個Slot中。
通過改造Key名稱,增加Hash tags使其保證在同一個Slot,該方案在使用過程中需避免資料扭曲。
改造執行個體為叢集架構代理(Proxy)模式,Proxy模式支援跨Slot執行DEL、MGET、MSET等涉及多Key的命令,更多資訊請參見Tair Proxy特性說明。
ERR READONLY you can't write against a read only instance
可能原因:Tair執行個體在主備切換、升降配或小版本升級時,將出現秒級的串連閃斷和30秒以內的唯讀狀態。
解決方案:屬於正常現象,執行個體會自動回復,您無需進行任何操作。請提前為您的應用設計重連機制和異常處理的能力,更多資訊請參見升級執行個體配置。
Filed to connect to any host resolved for DNS name
可能原因:未正確配置白名單。
解決方案:將用戶端的IP地址添加至執行個體的白名單中,具體操作請參見設定IP白名單。
如果是公網訪問請在白名單中添加出口IP(訪問https://cip.cc/擷取)。
redis-cli異常
Connection reset by peer
可能原因:標準架構,開啟了TLS(SSL)加密串連,未帶認證訪問。
解決方案:
攜帶認證訪問,參考TLS(SSL)加密串連執行個體。
若無需使用TLS(SSL)加密,請關閉TLS加密後重試。
ERR must use ssl connection in ssl port
可能原因:叢集架構,開啟了TLS(SSL)加密串連,未帶認證訪問。
解決方案:
攜帶認證訪問,參考TLS(SSL)加密串連執行個體。
若無需使用TLS(SSL)加密,請關閉TLS加密後重試。
Proxy(代理模式)通用異常
ERR client ip is not in whitelist
可能原因:未將用戶端的IP地址添加至Tair執行個體的白名單中。
解決方案:將用戶端的IP地址添加入至Tair執行個體的白名單中,具體操作請參見串連診斷。
NOWRITE You can't write against a non-write redis
或NOREAD You can't read against a non-read redis。
可能原因:執行個體處於欠費或到期狀態,執行個體狀態顯示為已經鎖定。
解決方案:對帳號進行儲值,或對到期的執行個體進行續約,更多資訊請參見到期與欠費。
ERR syntax error
可能原因:命令語法錯誤,例如需要傳入4個參數,實際僅傳入3個參數。
解決方案:檢查命令格式是否正確,更多資訊請參Redis Commands。
ERR no such db node
可能原因:使用阿里雲自研的Tair命令時,傳入的db node錯誤。
解決方案:傳入正確的db node,db node需小於分區數量,更多資訊請參見阿里雲自研的Proxy命令。
ERR 'xxx' command keys must in same slot
可能原因:在Tair叢集架構執行個體執行的事務或指令碼中,存在跨Slot的Key。
解決方案:改造事務或指令碼,您可以通過CLUSTER KEYSLOT命令擷取目標Key的Hash Slot。
Tair叢集架構執行個體會根據CRC演算法將Key均勻的寫入不同Slot中。若您希望將多個Key寫入到一個Slot中,您可以使用Hash Tags,但該方法若使用不當容易造成資料扭曲,請謹慎使用。
ERR for redis cluster, eval/evalsha number of keys can't be negative or zero
可能原因:執行EVAL和EVALSHA命令未傳入Key或numkeys參數的值未大於0。
解決方案:執行EVAL和EVALSHA命令時,至少需要傳入一個Key且numkeys參數的值大於0,更多資訊請參見Lua指令碼基本文法。
ERR request refused, too many pending request, now count xxx, beyond threshold xxx
可能原因:由於用戶端使用了不合理的Pipeline,Tair後端堆積了過多未處理的Request,新請求被拒絕。
解決方案:減少Pipeline的請求數量。
ERR redis temporary failure
可能原因:部分Tair子執行個體訪問逾時,可能是網路抖動、串連數到達上限導致斷鏈、執行個體進行中主備切換或執行慢查詢等導致。
解決方案:屬於正常現象,執行個體會自動回復,您無需進行任何操作。請提前為您的應用設計重連機制和異常處理的能力。
ERR redis temporary failure (ErrorCode 7002)
可能原因:部分Tair子執行個體訪問逾時,可能是執行個體正在變更配置或進行中主備切換導致。
解決方案:屬於正常現象,執行個體會自動回復,您無需進行任何操作。請提前為您的應用設計重連機制和異常處理的能力。
Lua指令碼與事務(Transaction)
NOSCRIPT No matching script. Please use EVAL.
可能原因:使用EVALSHA命令時,若SHA1值對應的指令碼未緩衝至Tair中。
解決方案:通過EVAL命令或SCRIPT LOAD命令將目標指令碼緩衝至Tair中後進行重試,更多資訊請參見NOSCRIPT錯誤。
BUSY Redis is busy running a script. You can only call SCRIPT KILL or SHUTDOWN NOSAVE.
可能原因:處理Lua指令碼逾時。
解決方案:通過SCRIPT KILL命令終止Lua指令碼或等待Lua指令碼執行結束,更多資訊請參見Lua指令碼逾時錯誤。
ERR command eval not support for normal user
可能原因:無法執行EVAL的相關命令。
解決方案:請將執行個體的小版本升級至最新,具體操作請參見升級小版本與代理版本。
ERR eval/evalsha command keys must be in same slot
解決方案:改造Lua指令碼,您可以通過CLUSTER KEYSLOT命令擷取目標Key的Hash Slot,更多資訊請參見叢集架構特殊限制。
ERR bad lua script for redis cluster, all the keys that the script uses should be passed using the KEYS array
可能原因:Proxy(代理)節點的Lua指令碼限制。
解決方案:所有Key都應該由KEYS數組來傳遞,例如EVAL "return redis.call('mget', KEYS[1], KEYS[2])" 2 foo {foo}bar,不能使用Lua變數替換KEYS,更多資訊請參見叢集架構特殊限制。
EXECABORT Transaction discarded because of previous errors
可能原因:事務中的命令執行失敗,可能是命令語法錯誤或運行錯誤等。
解決方案:檢查代碼邏輯,修複錯誤命令。
UNKILLABLE Sorry the script already executed write commands against the dataset.
可能原因:當前Lua指令碼已執行寫命令,此時SCRIPT KILL命令無法生效。
解決方案:在控制台的執行個體列表頁面,找到對應執行個體,單擊操作列的重啟,更多資訊請參見重啟執行個體。
UNKILLABLE The busy script was sent by a master instance in the context of replication and cannot be killed.
可能原因:當前Lua指令碼已經被Master節點發給自己的replica節點,此時SCRIPT KILL命令無法生效。
解決方案:在控制台的執行個體列表頁面,找到對應執行個體,單擊操作列的重啟,更多資訊請參見重啟執行個體。
NOTBUSY No scripts in execution right now.
可能原因:當前沒有正在運行Lua指令碼。
解決方案:無需處理,不要調用SCRIPT KILL命令。
Jedis用戶端
Could not get a resource from the pool
可能原因:無法從串連池擷取到Jedis串連。
當blockWhenExhausted參數為true(預設)時,若串連池沒有可用的Jedis串連,用戶端通常會等待一段時間(等待時間由maxWaitMillis參數決定,單位為毫秒),若長時間沒有擷取到可用的Jedis串連,會出現如下異常:
redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool … Caused by: java.util.NoSuchElementException: Timeout waiting for idle object at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:449)當blockWhenExhausted參數為false時,若串連池沒有可用的Jedis串連,則會立即出現如下異常:
redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool … Caused by: java.util.NoSuchElementException: Timeout waiting for idle object at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:449)
解決方案:您可以從如下幾個方面進行排查。
串連泄露
JedisPool預設maxTotal值為8,從如下代碼得知,從JedisPool中擷取了8個Jedis資源,但沒有歸還資源。因此,在第9次嘗試擷取Jedis資源時,無法調用
jedisPool.getResource().ping()。GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig(); JedisPool jedisPool = new JedisPool(poolConfig, "127.0.0.1", 6379); // 向JedisPool借用8次串連,但是沒有執行歸還操作。 for (int i = 0; i < 8; i++) { Jedis jedis = null; try { jedis = jedisPool.getResource(); jedis.ping(); } catch (Exception e) { logger.error(e.getMessage(), e); } } jedisPool.getResource().ping();推薦使用如下規範代碼。
Jedis jedis = null; try { jedis = jedisPool.getResource(); // 具體的命令。 jedis.executeCommand() } catch (Exception e) { // 如果命令有Key,建議在錯誤記錄檔中把Key列印出來,對於叢集架構來說,可通過Key定位到具體節點。 logger.error(e.getMessage(), e); } finally { // 注意:這裡不是關閉串連,在JedisPool模式下,Jedis會被歸還給資源集區。 if (jedis != null) jedis.close(); }maxTotal值設定得過小
當業務並發量大時,可能會由於maxTotal值設定的過小導致異常。例如,一次命令已耗用時間的平均耗時約為1ms(
Borrow|Return resource+ Jedis執行命令 + 網路時間),一個串連的QPS大約為1000,業務期望的QPS為50000,則理論上需要的maxTotal值為50000 / 1000 = 50。在該情況下,您可以在用戶端所在的機器上執行下述命令,該命令返回的結果為串連用戶端的串連數,您可以根據該數值對maxTotal值進行調整。
netstat -an | grep 6379 | grep EST | wc -lJedis串連阻塞
當Tair執行個體發生阻塞時(例如慢查詢等原因),所有串連會在逾時時間範圍內等待,當並發量較大時,會造成串連池資源不足,更多資訊請參見connect timed out。
Jedis串連被拒絕
從JedisPool中擷取串連時,由於沒有空閑串連,需要重建一個Jedis串連,但是串連被拒絕,異常樣本如下:
redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool at redis.clients.util.Pool.getResource(Pool.java:50) at redis.clients.jedis.JedisPool.getResource(JedisPool.java:99) at TestAdmin.main(TestAdmin.java:14) Caused by: redis.clients.jedis.exceptions.JedisConnectionException: java.net.ConnectException: Connection refused at redis.clients.jedis.Connection.connect(Connection.java:164) at redis.clients.jedis.BinaryClient.connect(BinaryClient.java:80) at redis.clients.jedis.BinaryJedis.connect(BinaryJedis.java:1676) at redis.clients.jedis.JedisFactory.makeObject(JedisFactory.java:87) at org.apache.commons.pool2.impl.GenericObjectPool.create(GenericObjectPool.java:861) at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:435) at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:363) at redis.clients.util.Pool.getResource(Pool.java:48) ... 2 more Caused by: java.net.ConnectException: Connection refused at java.net.PlainSocketImpl.socketConnect(Native Method) at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:339) at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:200) at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:182) at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) at java.net.Socket.connect(Socket.java:579) at redis.clients.jedis.Connection.connect(Connection.java:158) ... 9 more可以從
at redis.clients.jedis.Connection.connect(Connection.java:158)中看出,實際是在建立一個Socket串連,並調用connect函數,但是被拒絕串連,如下為Jedis源碼。socket.setSoLinger(true, 0); 158: socket.connect(new InetSocketAddress(host, port), connectionTimeout);通常情況下,該問題需要排查Tair的網域名稱配置是否正確、該段時間網路是否正常。
java.net.SocketTimeoutException: connect timed out
可能原因:用戶端串連Tair執行個體逾時。
解決方案:更多資訊請參見串連問題排查流程。
java.net.SocketTimeoutException: Read timed out
可能原因:網路不穩定、讀寫逾時時間過短、存在慢查詢或發生阻塞等原因造成Jedis API調用逾時。
解決方案:適當增大逾時時間,或進行執行個體診斷,查看執行個體在對應時間點是否存在效能問題或異常。
若在DMS中產生該報錯,則有可能是執行個體專用網路的串連地址或連接埠被修改了。您可以在DMS資料庫執行個體列表中,按右鍵目標執行個體,選擇編輯執行個體,然後選擇錄入方式為串連串地址,將修改後的執行個體串連地址填寫到串連串地址文字框中進行重試。
No reachable node in cluster
可能原因:JedisCluster地址無法訪問。
解決方案:若是首次訪問Tair執行個體,請檢查是否將用戶端的IP地址添加至Tair白名單中或用戶端的網路情況;若不是首次訪問Tair執行個體,可以進行執行個體診斷,進行問題定位。
Caused by: java.lang.NumberFormatException: For input string: "6379@13028"
可能原因:Jedis 2.8.0及以下版本引入了ClusterNodeInformationParser來解析cluster slots傳回值,但Redis後續更改了此命令傳回值類型,所以報錯NumberFormatException。
解決方案:將Jedis升級至2.9.0及以上版本。
No more cluster attempts left
可能原因:JedisCluster在API逾時之後會預設重試5次(MaxAttempts,預設為5),並且在均失敗之後拋出此錯誤。
解決方案:適當增大逾時時間或進行執行個體診斷。
Unexpected end of stream
可能原因:Jedis緩衝區異常,您可以從如下幾個方面進行排查。
多個線程使用一個Jedis串連
通常情況下,一個線程使用一個Jedis串連。例如下面代碼就是兩個線程共用了一個Jedis串連:
new Thread(new Runnable() { public void run() { for (int i = 0; i < 100; i++) { jedis.get("hello"); } } }).start(); new Thread(new Runnable() { public void run() { for (int i = 0; i < 100; i++) { jedis.hget("haskey", "f"); } } }).start();為避免出現這種情況,您可以使用JedisPool管理Jedis串連,實現安全執行緒。
長時間閑置串連
長時間閑置串連會被服務端主動斷開,請查詢執行個體的timeout參數配置、Jedis串連池配置,確定是否需要進行空閑逾時檢測。
說明預設設定下,即使某個用戶端已經空閑了很長時間,Tair也不會主動斷開與該用戶端的串連,若您調整過timeout參數,則可能會遇到該問題。更多資訊請參見設定用戶端串連的空閑時間。
解決方案:檢查是否有多線程共用Jedis代碼或由於長時間閑置串連造成服務端中斷連線。
java.lang.Long cannot be cast to java.util.List
可能原因:若多個線程操作同一個Jedis串連就會返回該報錯,Jedis本身存線上程安全問題。
解決方案:Jedis的正確使用方法是一個線程操作一個Jedis。您可以使用JedisPool(非Jedis)避免該問題。
Broken pipe (Write failed)
可能原因:在Jedis單串連模式(未使用JedisPool)下逾時後,用戶端關閉了Socket,此時若您繼續調用讀寫介面寫入資料,會返回該報錯。
解決方案:Jedis的正確使用方法是一個線程操作一個Jedis。您可以使用JedisPool(非Jedis)避免該問題。
No way to dispatch this command to Redis Cluster because keys have different slots
可能原因:JedisCluster操作的Key不在同一個Slot(槽)中。
解決方案:通過Hash tags對Key進行改造。
您也可以使用Proxy(代理)模式屏蔽叢集的限制。
Lettuce用戶端
Connection to xxx not allowed. This Partition is not known in the cluster view.
可能原因:Lettuce用戶端在預設情況下,配置為refreshOption = null , validateClusterNodeMembership = true,表示開啟validateClusterNodeMembership檢測。在Tair執行個體地址發生路由變化後,由於沒有開啟refreshOption,即不會更新路由表,此時validateClusterNodeMembership檢測就會返回該報錯。
解決方案:配置refreshOption選項,並且設定validateClusterNodeMembership為false,更多資訊請參見Lettuce。
io.lettuce.core.RedisConnectionException: Unable to connect xxx
可能原因:用戶端串連Tair執行個體逾時。
解決方案:更多資訊請參見串連問題排查流程。
java.nio.channels.UnresolvedAddressException
可能原因:大機率是Netty版本衝突。
解決方案:檢查Netty依賴,建議選擇較高的版本,更多資訊請參見spring-projects/spring-boot#14307。
ERR Unknown sentinel subcommand 'master'
可能原因:Lettuce在master-replica Sentinel模式下會向Redis執行個體發送Sentinel master/slave命令,而Tair執行個體在Sentinel相容模式下僅支援Sentinel get-master-addr-by-name命令,故產生該報錯。
解決方案:修改代碼為普通模式(非Sentinel),Tair採用自研的高可用服務HA組件,無需Sentinel。
部分執行個體版本不支援RESP3協議,報錯unknown command
可能原因:Redis 6.0及以上版本支援了RESP3協議,可通過HELLO命令切換RESP協議。但部分低版本執行個體不支援HELLO命令,可能會存在相容性問題。
解決方案:您可以直接在程式中指定以RESP2協議訪問Tair執行個體,樣本如下:
client.setOptions(ClientOptions.builder()
.protocolVersion(ProtocolVersion.RESP2)
.build());若使用Spring-data-redis with Lettuce,樣本如下:
LettuceClientConfiguration lettuceClientConfiguration = LettuceClientConfiguration.builder().
clientOptions(ClientOptions.builder().protocolVersion(ProtocolVersion.RESP2).build()).build();
return new LettuceConnectionFactory(redisClusterConfiguration, lettuceClientConfiguration);Redisson用戶端
org.redisson.client.RedisConnectionException: Unable to connect to Redis server xxx
可能原因:用戶端串連Tair執行個體逾時。
解決方案:更多資訊請參見串連問題排查流程。
No enum constant org.redisson.cluster.ClusterNodeInfo.Flag.NOFAILOVER
可能原因:Redisson低版本Bug,更多資訊請參見redisson/redisson#2399。
解決方案:將Redisson升級至3.11.6及以上版本。
Spring Data Redis用戶端
NOPERM this user has no permissions to run the 'config|get' command
可能原因:在執行個體資訊頁確認您的執行個體版本為Redis 7.0。雲資料庫 Tair(相容 Redis)的7.0版本禁用CONFIG命令。
應用啟動時,Spring Data Redis會執行CONFIG SET命令動態設定notify-keyspace-events參數來啟用KeyspaceEventMessageListener功能。因為CONFIG GET/SET命令被禁用,導致啟動時報錯。
解決方案:設定keyspaceNotificationsConfigParameter為空白,繞過該問題,完整代碼見SpringRedisTest.zip,更多資訊請參見Spring Data Redis。
@EnableRedisRepositories(enableKeyspaceEvents = RedisKeyValueAdapter.EnableKeyspaceEvents.ON_STARTUP, keyspaceNotificationsConfigParameter = "")同時,如果監聽了KeyExpirationListener,需要在建構函式中設定 keyspaceNotificationsConfigParameter 為空白。
public RedisKeyExpirationListener(RedisMessageListenerContainer redisMessageListenerContainer) {
super(redisMessageListenerContainer);
setKeyspaceNotificationsConfigParameter(""); // 重要
}StackExchange.Redis用戶端
Multiple databases are not supported on this server; cannot switch to database
可能原因:叢集架構不支援執行SELECT命令。
解決方案:將cluster_compat_enable參數設定為0(即關閉原生Redis Cluster文法相容),具體操作請參見設定參數,然後重啟用戶端應用後重試。
Predis用戶端
Error while reading line from the server.
可能原因:讀取逾時,您可能正在執行一個慢查詢。
解決方案:適當增大逾時時間或將用戶端的read_write_timeout參數改為0或-1,更多資訊請參見Predis questions。
phpredis用戶端
Cannot assign requested address
可能原因:用戶端通過短串連訪問Tair執行個體時,產生該報錯。
解決方案:使用pconnect替換connect的串連方式,或修改用戶端所在ECS執行個體的tcp_max_tw_buckets核心參數,更多資訊請參見Cannot assign requested address報錯。
redis protocol error, got ' ' as reply type byte
可能原因:phpredis低版本Bug,更多資訊請參見phpredis/phpredis#1585。
解決方案:將phpredis升級至最新版。
php_network_getaddresses: getaddrinfo failed: Temporary failure in name resolution
解決方案:請設定正確的DNS伺服器位址,更多資訊請參見解決因網域名稱解析失敗導致的串連問題。
可能原因:用戶端無法正常解析Tair執行個體的網域名稱地址。
Go-redis用戶端
panic: got 4 elements in cluster info address, expected 2 or 3
可能原因:您的Redis版本為7.0及以上,但未使用相容的Go-redis用戶端版本導致,更多資訊請參見redis/go-redis#2085。
解決方案:升級、使用Go-redis用戶端9.0及以上版本。
node-redis用戶端
SCAN命令死迴圈或者返回資料為空白
可能原因:SCAN命令返回的Cursor值可能超過了JavaScript最大可精確表達的數值Number.MAX_SAFE_INTEGER,導致Cursor不準確,引發死迴圈,更多資訊請參見redis/node-redis#2561。
解決方案:將node-redis用戶端升級至5.0.0及以上版本。