A. redis集群角色切換java調用異常
redis集群角色切換java調用異常
一、Redis狀態檢查
唯一標記一個redis實例的是ip和埠,前端是用tcp方式來訪問redis的,我們提供給應用訪問的是一個ip+63379(一般使用63379) 埠。因此我們執行如下命令檢查redis狀態:
上面的role這個值一定是master的,只要保證vip在master上我們的Padis cache服務就是沒有問題的,如果不通或者role的角色是slave,那就得繼續查看是什麼問題.
二、兩個redis的角色都是slave的問題
當兩個主機都掛了或者我們自己不小心將兩個redis停了,並且我們用下面的命令檢查
/wls/wls81/redis/bin/redis-cli -h {ip} -p {port} -a {password} info replication
發現無論是vip還是另外的兩個ip都是role:slave 的角色,這個時候需要對vip所在的主機執行slaveof no one 的操作,將vip 所在的redis變成master,如:
/wls/wls81/redis/bin/redis-cli -h {vip} -p {port} -a {password} slaveof no one
三、sentinel的配置參數
我們的sentinel 配置文件裡面有兩個重要的配置
sentinel monitor pds_jks-core-prd 10.33.94.65 63379 1 -----------配置的ip和埠任何時候都需要是master的ip埠,切換的時候程序自動會改 。另外,紅色所示部分pds_jks-core-prd為redis對外提供的主機名,一般Jedis在調用redis時會用到此名稱。如果配置多個哨兵則一般要求此名稱唯一標識
sentinel down-after-milliseconds pds_jks-core-prd 15000 ----------這個是sentinel連接master的超時時間,超過這個時間就認為master掛了,實現自動切換。這個默認是30秒,這個時間得調節好,大了會在真正出現故障的時候切換時間會長,小了有時候master由於持久化數據,繁忙不響應,會導致自動切換,實際只是瞬間不可用,現在認為設置為15秒為宜.
四、AOF日誌
這個日誌記錄了每一個寫入命令或者刪除命令的,這個對於我們審計功能是有用的,由於佔用很多磁碟,默認我們是關閉的
如果開啟會生成一個.aof的文件在data文件中. 如: /wls/apache/servers/pds_jks-core-prd/data
在redis運行中中開啟:
/wls/wls81/redis-icore/bin/redis-cli -h {ip} -p {port} -a {password} config set appendonly yes
開啟了可以查看日誌,記錄每一個命令,如有必要可以開啟查完問題後關閉. 同時說明一下
/wls/wls81/redis-icore/bin/redis-cli -h {ip} -p {port} -a {password} config set 可以在redis運行的時候設置多個它的參數
五、空閑連接的timeout
redis服務端不會自動斷開客戶端來的連接,redis服務端有設置客戶端空閑連接超時時間,可用命令
/wls/wls81/redis-icore/bin/redis-cli -h {ip} -p {port} -a {password} config get timeout
查看當前timeout時間,默認是0,就是不斷開空閑的連接,如果不斷開空閑的連接,就會造成redis連接過多
所以一般情況下可以設置為3600秒:
/wls/wls81/redis-icore/bin/redis-cli -h {ip} -p {port} -a {password} config set timeout 3600
也就是3600秒後將空閑的連接關閉掉. 可以用下面的命令查看某個連接空閑了多久:
/wls/wls81/redis-icore/bin/redis-cli -h {ip} -p {port} -a {password} client list
六、監控redis執行的命令
/wls/wls81/redis-icore/bin/redis-cli -h {ip} -p {port} -a {password} monitor
上述這個monitor命令可以查看redis執行了什麼命令,有時候查問題很有必要用到,我們可以知道那段時間redis執行了什麼,從而進行我們的問題診斷。
七、key的查找與執行
/wls/wls81/redis-icore/bin/redis-cli -h {ip} -p {port} -a {password} keys "*"
keys這個命令查找所有的key,但是最好慎用,因為它很耗redis的性能,每個key都遍歷一遍. 也可以進行模糊匹配如: keys "send*"
千萬記住在生產環境上不能隨便亂用,因為它會將redis性能耗盡,導致其他連接獲取不到響應.
/wls/wls81/redis/bin/redis-cli -h {ip} -p {port} -a {password} dbsize
dbsize 這個命令可以看到整一個redis裡面有多少個key,當然和keys "*" | wc -l結果是一樣的。
當我們需要批量刪除key值時可以用如下命令即可:
/wls/wls81/redis/bin/redis-cli -h {ip} -p {port} -a {password} keys "send*" | xargs /wls/wls81/redis/bin/redis-cli -h {ip} -p {port} -a {password} del
我們需要將整個db都flush掉可以用:
/wls/wls81/redis/bin/redis-cli -h {ip} -p {port} -a {password} -a MamcCorePrd flushdb
/wls/wls81/redis/bin/redis-cli -h {ip} -p {port} -a {password} -a flushall
八、由於連接redis的客戶端使用jedisPool
如果設置了
redis.pool.testOnBorrow.REL=true
redis.pool.testOnReturn.REL=true
這兩個參數是說在或者pool中的連接和返回連接給pool的時候都需要檢查一下連接的有用性,也就是ping一下這個redis是不是好的,
這樣在高並發的時候,由於並發線程太多,ping操作相對線程啟動來說很慢,因此,應用會堵在類似如下線程mp的地方
"[ACTIVE] ExecuteThread: '19' for queue: 'weblogic.kernel.Default (self-tuning)'" id=33 idx=0x9c tid=273669 prio=5 alive, native_blocked, daemon
at jrockit/net/SocketNativeIO.readBytesPinned(Ljava/io/FileDescriptor;[BIII)I(Native Method)
at jrockit/net/SocketNativeIO.socketRead(SocketNativeIO.java:32)
at java/net/SocketInputStream.socketRead0(Ljava/io/FileDescriptor;[BIII)I(SocketInputStream.java)
at java/net/SocketInputStream.read(SocketInputStream.java:129)
at java/net/SocketInputStream.read(SocketInputStream.java:90)
at redis/clients/util/RedisInputStream.fill(RedisInputStream.java:109)
at redis/clients/util/RedisInputStream.readByte(RedisInputStream.java:45)
at redis/clients/jedis/Protocol.process(Protocol.java:64)
at redis/clients/jedis/Protocol.read(Protocol.java:131)
at redis/clients/jedis/Jedis.ping(Jedis.java:35)
at redis/clients/jedis/JedisPool$JedisFactory.validateObject(JedisPool.java:104)
at org/apache/commons/pool/impl/GenericObjectPool.addObjectToPool(GenericObjectPool.java:922)
at org/apache/commons/pool/impl/GenericObjectPool.returnObject(GenericObjectPool.java:917)
^-- Holding lock: org/apache/commons/pool/impl/GenericObjectPool@0xb8513338[fat lock]
at redis/clients/util/Pool.returnResourceObject(Pool.java:29)
at redis/clients/util/Pool.returnResource(Pool.java:41)
at com/paic/icore/mams/common/jedis/util/RedisPoolCacheTools.release(RedisPoolCacheTools.java:43)
雖然後面會自動恢復,不過導致應用響應緩慢.解決方法是將該兩個參數設置為false,並且定期檢查:
testOnBorrow.REL=false
testOnReturn.REL=false
timeBetweenEvictionRunsMillis=60000 -------每隔60秒定期檢查空閑連接
minEvictableIdleTimeMillis=120000 ---------連接在池中保持空閑而不被空閑連接回收器線程回收的最小時間值,單位毫秒
numTestsPerEvictionRun=-1 ----------空閑連接掃描時,每次最多掃描的連接數,一般設置為-1,全部掃描
設置成這樣之後就不用每次都測試了,這樣就提高了應用的性能
有時候由於持久化導致master變得緩慢,所以建議關閉master的持久化,讓slave持久化
關閉持久化 /wls/wls81/redis/bin/redis-cli -h {ip} -p {port} -a {password} config set save ""
開通持久化 /wls/wls81/redis/bin/redis-cli -h {ip} -p {port} -a {password} config set save "900 1 300 10 60 10000"
關閉持久化後如果發生主備切換了,請將master的持久化關閉,slave的持久化開啟
九、查詢每秒執行的命令個數
十、單位時間內Redis執行的命令次數
B. Java工程師是如何使用Redis的
redis算是用的最多的key-value型緩存組件了!
因為使用了key-value型,所以存取效率極好,簡單來說就類似JAVA中的hashMap,不過是用整個伺服器內存來當做map,但是redis的數據可以通過配置指令保存到硬碟(同步保存save,非同步保存bgsave)!
當然,redis在使用過程中會存在持久化失敗,緩存擊穿,擴容困難等問題,不過無論如何,redis都是一款最值得用的緩存工具!
使用過程中有任何問題,歡迎大家一起交流,redis還有什麼遺漏功能,也請大家補充,謝謝!
C. Redis怎麼做集群
為什麼集群?
通常,為了提高網站響應速度,總是把熱點數據保存在內存中而不是直接從後端資料庫中讀取。Redis是一個很好的Cache工具。大型網站應用,熱點數據量往往巨大,幾十G上百G是很正常的事兒,在這種情況下,如何正確架構Redis呢?
首先,無論我們是使用自己的物理主機,還是使用雲服務主機,內存資源往往是有限制的,scale up不是一個好辦法,我們需要scale out橫向可伸縮擴展,這需要由多台主機協同提供服務,即分布式多個Redis實例協同運行。
其次,目前硬體資源成本降低,多核CPU,幾十G內存的主機很普遍,對於主進程是單線程工作的Redis,只運行一個實例就顯得有些浪費。同時,管理一個巨大內存不如管理相對較小的內存高效。因此,實際使用中,通常一台機器上同時跑多個Redis實例。
方案
1.Redis官方集群方案 Redis Cluster
Redis Cluster是一種伺服器Sharding技術,3.0版本開始正式提供。
Redis Cluster中,Sharding採用slot(槽)的概念,一共分成16384個槽,這有點兒類pre sharding思路。對於每個進入Redis的鍵值對,根據key進行散列,分配到這16384個slot中的某一個中。使用的hash演算法也比較簡單,就是CRC16後16384取模。
Redis集群中的每個node(節點)負責分攤這16384個slot中的一部分,也就是說,每個slot都對應一個node負責處理。當動態添加或減少node節點時,需要將16384個槽做個再分配,槽中的鍵值也要遷移。當然,這一過程,在目前實現中,還處於半自動狀態,需要人工介入。
Redis集群,要保證16384個槽對應的node都正常工作,如果某個node發生故障,那它負責的slots也就失效,整個集群將不能工作。
為了增加集群的可訪問性,官方推薦的方案是將node配置成主從結構,即一個master主節點,掛n個slave從節點。這時,如果主節點失效,Redis Cluster會根據選舉演算法從slave節點中選擇一個上升為主節點,整個集群繼續對外提供服務。這非常類似前篇文章提到的Redis Sharding場景下伺服器節點通過Sentinel監控架構成主從結構,只是Redis Cluster本身提供了故障轉移容錯的能力。
Redis Cluster的新節點識別能力、故障判斷及故障轉移能力是通過集群中的每個node都在和其它nodes進行通信,這被稱為集群匯流排(cluster bus)。它們使用特殊的埠號,即對外服務埠號加10000。例如如果某個node的埠號是6379,那麼它與其它nodes通信的埠號是16379。nodes之間的通信採用特殊的二進制協議。
對客戶端來說,整個cluster被看做是一個整體,客戶端可以連接任意一個node進行操作,就像操作單一Redis實例一樣,當客戶端操作的key沒有分配到該node上時,Redis會返回轉向指令,指向正確的node,這有點兒像瀏覽器頁面的302 redirect跳轉。
Redis Cluster是Redis 3.0以後才正式推出,時間較晚,目前能證明在大規模生產環境下成功的案例還不是很多,需要時間檢驗。
2.Redis Sharding集群
Redis 3正式推出了官方集群技術,解決了多Redis實例協同服務問題。Redis Cluster可以說是服務端Sharding分片技術的體現,即將鍵值按照一定演算法合理分配到各個實例分片上,同時各個實例節點協調溝通,共同對外承擔一致服務。
多Redis實例服務,比單Redis實例要復雜的多,這涉及到定位、協同、容錯、擴容等技術難題。這里,我們介紹一種輕量級的客戶端Redis Sharding技術。
Redis Sharding可以說是Redis Cluster出來之前,業界普遍使用的多Redis實例集群方法。其主要思想是採用哈希演算法將Redis數據的key進行散列,通過hash函數,特定的key會映射到特定的Redis節點上。這樣,客戶端就知道該向哪個Redis節點操作數據。
慶幸的是,java redis客戶端驅動jedis,已支持Redis Sharding功能,即ShardedJedis以及結合緩存池的ShardedJedisPool。
Jedis的Redis Sharding實現具有如下特點:
1. 採用一致性哈希演算法(consistent hashing),將key和節點name同時hashing,然後進行映射匹配,採用的演算法是MURMUR_HASH。採用一致性哈希而不是採用簡單類似哈希求模映射的主要原因是當增加或減少節點時,不會產生由於重新匹配造成的rehashing。一致性哈希隻影響相鄰節點key分配,影響量小。
2.為了避免一致性哈希隻影響相鄰節點造成節點分配壓力,ShardedJedis會對每個Redis節點根據名字(沒有,Jedis會賦予預設名字)會虛擬化出160個虛擬節點進行散列。根據權重weight,也可虛擬化出160倍數的虛擬節點。用虛擬節點做映射匹配,可以在增加或減少Redis節點時,key在各Redis節點移動再分配更均勻,而不是只有相鄰節點受影響。
3.ShardedJedis支持keyTagPattern模式,即抽取key的一部分keyTag做sharding,這樣通過合理命名key,可以將一組相關聯的key放入同一個Redis節點,這在避免跨節點訪問相關數據時很重要。
D. redis主從集群 主掛掉 java怎樣調用從
從機的redis命令行輸入slaveofnoone轉換為主機,然後要麼修改主機ip要麼修改java程序中的主機ip地址。
另外建議看下redis sentinel 主從切換(failover)解決方案
E. java操作redis集群問題CLUSTERDOWN The cluster is down. Use CLUSTER INFO for more information
java操作redis集群問題CLUSTERDOWN The cluster is down. Use CLUSTER INFO for more information,配置沒有配置好的問題。