以下是我看完Jedis源码后的个人理解,用问答的形式,比较随意。
1. Redis是什么?
一个缓存,基于内存进行操作。
2. Jedis是什么?
Redis的Java客户端,用于操作Redis。
3. Jedis如何与Redis交互?
遵循Redis协议,使用socket连接操作Redis
如果是单行回复,那么***个字节是[+]
如果回复的内容是错误信息,那么***个字节是[_]
如果回复的内容是一个整型数字,那么***个字节是[:]
如果是bulk回复,那么***个字节是[$]
如果是multi-bulk回复,那么***个字节是[*]
4. Jedis的连接池是怎么回事?
通过实现common包中的GenericObjectPool创建连接池,通过实现BasePoolableObjectFactory生产连接,从而达到创建连接池的效果。
5. Jedis如何操作?
set:Jedis将传入的key、value和command封装,通过socket创建连接,用outputStream将命令打出,用inputStream获取返回的标记。
get:同set。
6. shardJedis是怎么回事?
所谓的分布式Redis,是Jedis客户端实现的一种模式。启动n台Redis,他们就在那提供服务,不会自己做集群。
6.1 那Jedis是如何实现的呢?
创建shardJedisPool的时候,客户端将传进来的n台机器,用每个机器的机器名做了一致性hash,并给每个机器创建160*weight个虚拟节点,虚拟节点也是将名字+i做hash。然后将这些hash值作为key存到一个TreeMap中,即nodes,TreeMap是有序的。
6.2 为什么做虚拟节点?
因为不坐虚拟节点时,可能会出现集群中的某一个节点频繁被***,而其他节点则没有工作量,造成数据不均衡,增加了虚拟节点,数据会均衡很多。这就是Jedis的均衡性。
6.3 TreeMap每个key的value存什么呢?
存放的是对应的机器的信息bean,即JedisShardInfo,这样不难看出,如果以权重weight为1为例,那么每个机器会创建160个节点(真实+虚拟),这样如果有4个实体机安装了Redis,那么在nodes中就有160*4条记录,其中每160条对应一个相同的JedisShardInfo。
Jedis同时又维护了一个Map<ShardInfo<R>,R>即resources,这个map的key存放JedisShardInfo实体,value存放的是通过这个实体JedisShardInfo中的ip:port创建的Jedis,所以,以上面的例子为例,resources中信息的条数就是4。
这样,当客户端用set(key,value)时,Jedis将客户端的key同样用一致性hash取hash值,然后到nodes中获取比key一致性hash出来的值大的值,取***个,即所谓的向右移,这样会获取一个JedisShardInfo,通过JedisShardInfo到resources中获取Jedis返回,这样客户端就可以通过这个Jedis做增删改查的操作了。
7. 一致性hash是怎么回事?
一致性hash是一个算法,简单来说就是将你所需要的值(如key:lilei)取hash值,然后与2^23取余数,得到的值。如lilei取hash是37184759,那么37184759%2^23=376,这个376就是一致性hash取出来的值。这个2^23是什么意思呢?它的值为255*255*255*255,不难发现,这个值是网络中***的ip数,即一个网络中最多的机器数。之所以取这个数,是为了当需要添加或删除机器的时候,不至于让其他节点失效,这就是一致性。
可能文章中会有一些错误,希望童鞋们指正,我希望可以在博客的路上与大家多多交流,共同进步。
【本文为51CTO专栏作者“王森丰”的原创稿件,转载请注明出处】