Jedis源碼理解
以下是我看完Jedis源碼后的個(gè)人理解,用問答的形式,比較隨意。
1. Redis是什么?
一個(gè)緩存,基于內(nèi)存進(jìn)行操作。
2. Jedis是什么?
Redis的Java客戶端,用于操作Redis。
3. Jedis如何與Redis交互?
遵循Redis協(xié)議,使用socket連接操作Redis
如果是單行回復(fù),那么***個(gè)字節(jié)是[+]
如果回復(fù)的內(nèi)容是錯(cuò)誤信息,那么***個(gè)字節(jié)是[_]
如果回復(fù)的內(nèi)容是一個(gè)整型數(shù)字,那么***個(gè)字節(jié)是[:]
如果是bulk回復(fù),那么***個(gè)字節(jié)是[$]
如果是multi-bulk回復(fù),那么***個(gè)字節(jié)是[*]
4. Jedis的連接池是怎么回事?
通過實(shí)現(xiàn)common包中的GenericObjectPool創(chuàng)建連接池,通過實(shí)現(xiàn)BasePoolableObjectFactory生產(chǎn)連接,從而達(dá)到創(chuàng)建連接池的效果。
5. Jedis如何操作?
set:Jedis將傳入的key、value和command封裝,通過socket創(chuàng)建連接,用outputStream將命令打出,用inputStream獲取返回的標(biāo)記。
get:同set。
6. shardJedis是怎么回事?
所謂的分布式Redis,是Jedis客戶端實(shí)現(xiàn)的一種模式。啟動(dòng)n臺(tái)Redis,他們就在那提供服務(wù),不會(huì)自己做集群。
6.1 那Jedis是如何實(shí)現(xiàn)的呢?
創(chuàng)建shardJedisPool的時(shí)候,客戶端將傳進(jìn)來的n臺(tái)機(jī)器,用每個(gè)機(jī)器的機(jī)器名做了一致性hash,并給每個(gè)機(jī)器創(chuàng)建160*weight個(gè)虛擬節(jié)點(diǎn),虛擬節(jié)點(diǎn)也是將名字+i做hash。然后將這些hash值作為key存到一個(gè)TreeMap中,即nodes,TreeMap是有序的。
6.2 為什么做虛擬節(jié)點(diǎn)?
因?yàn)椴蛔摂M節(jié)點(diǎn)時(shí),可能會(huì)出現(xiàn)集群中的某一個(gè)節(jié)點(diǎn)頻繁被***,而其他節(jié)點(diǎn)則沒有工作量,造成數(shù)據(jù)不均衡,增加了虛擬節(jié)點(diǎn),數(shù)據(jù)會(huì)均衡很多。這就是Jedis的均衡性。
6.3 TreeMap每個(gè)key的value存什么呢?
存放的是對(duì)應(yīng)的機(jī)器的信息bean,即JedisShardInfo,這樣不難看出,如果以權(quán)重weight為1為例,那么每個(gè)機(jī)器會(huì)創(chuàng)建160個(gè)節(jié)點(diǎn)(真實(shí)+虛擬),這樣如果有4個(gè)實(shí)體機(jī)安裝了Redis,那么在nodes中就有160*4條記錄,其中每160條對(duì)應(yīng)一個(gè)相同的JedisShardInfo。
Jedis同時(shí)又維護(hù)了一個(gè)Map<ShardInfo<R>,R>即resources,這個(gè)map的key存放JedisShardInfo實(shí)體,value存放的是通過這個(gè)實(shí)體JedisShardInfo中的ip:port創(chuàng)建的Jedis,所以,以上面的例子為例,resources中信息的條數(shù)就是4。
這樣,當(dāng)客戶端用set(key,value)時(shí),Jedis將客戶端的key同樣用一致性hash取hash值,然后到nodes中獲取比key一致性hash出來的值大的值,取***個(gè),即所謂的向右移,這樣會(huì)獲取一個(gè)JedisShardInfo,通過JedisShardInfo到resources中獲取Jedis返回,這樣客戶端就可以通過這個(gè)Jedis做增刪改查的操作了。
7. 一致性hash是怎么回事?
一致性hash是一個(gè)算法,簡(jiǎn)單來說就是將你所需要的值(如key:lilei)取hash值,然后與2^23取余數(shù),得到的值。如lilei取hash是37184759,那么37184759%2^23=376,這個(gè)376就是一致性hash取出來的值。這個(gè)2^23是什么意思呢?它的值為255*255*255*255,不難發(fā)現(xiàn),這個(gè)值是網(wǎng)絡(luò)中***的ip數(shù),即一個(gè)網(wǎng)絡(luò)中最多的機(jī)器數(shù)。之所以取這個(gè)數(shù),是為了當(dāng)需要添加或刪除機(jī)器的時(shí)候,不至于讓其他節(jié)點(diǎn)失效,這就是一致性。
可能文章中會(huì)有一些錯(cuò)誤,希望童鞋們指正,我希望可以在博客的路上與大家多多交流,共同進(jìn)步。
【本文為51CTO專欄作者“王森豐”的原創(chuàng)稿件,轉(zhuǎn)載請(qǐng)注明出處】