Redis Learning--jediscluster Source code interpretation

Source: Internet
Author: User
Tags data structures int size redis redis cluster
JedisclusterJediscluster is a Java client for Rediscluster that encapsulates various operations for Java access to Redis clusters, including initialization connections, request redirection, and so on. The concrete internal realization principle has the following two aspects mainly:
1.1. Jediscluster initialization, all cluster connection information is encapsulated in the Jedisclusterinfocache category.
The 1.2. Jedisclusterinfocache class has two very important map data structures, respectively
/**
  **nodes Store cluster IP address information and Jedispool. Where string is ip:port information, how many nodes are in the cluster, and how many ip:port there are.
  **/
 map<string, jedispool> nodes = new hashmap<string, jedispool> ();
 The
 storage key-value in the/** **slots is the number and Jedispool instance of the data slots in the cluster. That is, there are 16,384 key-value pairs in the slots.
 **/
 Map<integer, jedispool> slots = new Hashmap<integer, jedispool> ();
Jediscluster class Diagram


1. As you can see from the diagram, Jediscluster is primarily a Binaryjediscluster class that inherits the binary, and the various operations in this class are based on byte arrays. and 3 of the 4 interfaces implemented by the Binaryjediscluster class are based on byte array operations.
2. Jediscluster implements the Jediscommands,multikeyjedisclustercommands,jedisclusterscriptingcommands interface. These three interfaces provide an operation based on string type, that is, key is a string type.
3. Basiccommands is about the basic operation of the Redis service itself, such as Save,ping,bgsave.
4. Multikeybinaryjedisclustercommands and Multikeyjedisclustercommands interfaces A bulk operation of a byte array, and one is the bulk operation of a string. Jedisclustercommand in the Jediscluster client, Jedisclustercommand is a very important class, designed using the template method, The operation of the operation Redis cluster is highly encapsulated. An abstract Execute method is provided for various storage operations in the cluster. Jediscluster a variety of specific operations Redis cluster methods, only through anonymous internal classes, the flexibility to extend the Execute method. An instance of Jedis is encapsulated internally through Jedisclusterconnectionhandler. Jedisclustercommand Source Analysis:

/** * * This class is mainly composed of two key points: the use of template method design, specific access operations have subclass implementation * * In the cluster operation, in order to ensure high availability, the use of recursive algorithm to try to occur moved,ask, data migration operations.  **/public abstract class Jedisclustercommand<t> {//Jediscluster connection really holds class private Jedisclusterconnectionhandler
  Connectionhandler;
  Number of attempts, the default is 5 private int maxattempts;

  Private threadlocal<jedis> askconnection = new threadlocal<jedis> ();
    Public Jedisclustercommand (Jedisclusterconnectionhandler connectionhandler, int maxattempts) {
    This.connectionhandler = Connectionhandler;
  this.maxattempts = maxattempts;
  //Redis abstract method for various operations, Jediscluster is an anonymous inner class implementation.
 Public abstract T Execute (Jedis connection); Public T Run (String key) {if (key = = null) {throw new Jedisclusterexception ("No way to dispatch this COM

    Mand to Redis Cluster. ");}
  Return Runwithretries (Safeencoder.encode (key), This.maxattempts, False, false);
  /*** * * * This method uses recursion to ensure that when accessing data to the cluster, moved,asking occurs and problems are encountered during data migration, which is also a way to achieve high availability.
  This method calls the Execute method, which is specifically implemented by subclasses. /privAte T runwithretries (byte[] key, int attempts, Boolean tryrandomnode, Boolean asking) {if (attempts <= 0) {
    throw new Jedisclustermaxredirectionsexception ("Too many Cluster redirections?");
    } Jedis connection = null; try {/** * First executes the method, asking to false. Asking is set to true only if jedisaskdataexception * exception occurs **/if (asking) {connection = Askconnection.ge
        T ();

        Connection.asking ();
      If asking success, reset asking flag asking = false;
        else {///Tryrandomnode is false the first time it is executed.
        if (tryrandomnode) {connection = Connectionhandler.getconnection (); else {/** obtains the allocated noise based on the key, and then obtains an instance of Jedis from the Jedisclusterinfocache based on the data slot **/connection = Connectionh
        Andler.getconnectionfromslot (Jedisclustercrc16.getslot (key));
     /*** * * Invokes the concrete implementation of the subclass method.

    **/return execute (connection); catch (Jedisnoreachableclusternodeexception Jnrcne) {throw jnrcne;
      catch (Jedisconnectionexception JCE) {//Free existing connection releaseconnection (connection);
       connection = null; /*** * * * Just rebuild the key value on the Slot-jedis cache.
        There's no more redirection left.
        The maximum number of maxredirection has been reached, and an exception can be thrown.
        /if (attempts <= 1) {This.connectionHandler.renewSlotCache ();
      Throw JCE;
    ///Recursive Call this method return Runwithretries (Key, Attempts-1, Tryrandomnode, asking); \ catch (Jedisredirectionexception JRE) {//If moved redirection occurred, if (JRE instanceof Jedismoveddatae
        Xception) {//movedexception is required to rebuild the cache of key value pairs Slot-jedis.
      This.connectionHandler.renewSlotCache (connection);
      }//Release current connection before recursion or renewing releaseconnection (connection);

      connection = null;
     if (JRE instanceof jedisaskdataexception) {asking = true;   The exception indicates that the data is still in the current data slot, but is queried again. Askconnection.set (this.connectionHandler.geTconnectionfromnode (Jre.gettargetnode ()));
      else if (JRE instanceof jedismoveddataexception) {} else {throw new jedisclusterexception (JRE);
      }//Recursive call.
    Return Runwithretries (Key, Attempts-1, false, asking);
    Finally {releaseconnection (connection);
    } private void Releaseconnection (Jedis connection) {if (connection!= null) {connection.close ();
 }
  }

}
JedisclusterinfocacheThis caching class basically completes the following functions:
1.1. Cache key value pair Ip:port-->jedispool, cache key value pair Slot-->jedispool. The Jedis instance corresponding to each data slot in the Rediscluster is added to the cache beforehand, and the connection information of each data node is cached locally. The most important method of this class is Discoverclusternodesandslots (Jedis), the source code is as follows:
public void Discoverclusternodesandslots (Jedis Jedis) {w.lock ();
      try {reset (); /** obtains the Master,slave node information in the cluster according to the current Redis instance. Includes data that is allocated on each master node. Slots results are as follows: ****[10923, 16383, [[B@924fda2, 9000], [[B@5B879B5E, 9001]]]] * * * [[5461, 10922, [[b@3681fe9a, 7001] , [[B@10724C6B, 8000]], * * * [0, 5460, [[B@3FF70D3C, 7000], [[B@7485fef2, 8001]], ***/list<object&gt ;
      Slots = Jedis.clusterslots ();
        Iterate through the collection in the list, a total of 3 master node information for (Object slotinfoobj:slots) {//Slotinfo refers to a master,slave, the number of allocated slots information
        List<object> Slotinfo = (list<object>) slotinfoobj;
        if (Slotinfo.size () <= master_node_index) {continue;
        //Gets the number of data slots allocated to each master node list<integer> slotnums = Getassignedslotarray (Slotinfo);
        The size of the/**slotinfo is 4, where the first two are the minimum and maximum values for the number of slots.  The latter two are Master,slave instance information ***[10923, 16383, [[B@924fda2, 9000], [[B@5B879B5E, 9001]]] ***/int size = SlotInfo.size (); for (int i = Master_node_index i < size; i++) {//Hostinfos is the [B@924fda2, 9000] collection.
          On two elements list<object> Hostinfos = (list<object>) slotinfo.get (i);
          if (hostinfos.size () <= 0) {continue;
          Hostandport instance Hostandport TargetNode = Generatehostandport (Hostinfos) built on Ip,port; /** the key value of Ip:port according to Hostandport, * * then query the corresponding Jedispool instance from the cache according to the key.
          If there is no jedispool instance, * * Creates the Jedispool instance and finally puts it in the cache.
          * * Key value is the value of Ip:port,value is Jedispool **/setupnodeifnotexist (TargetNode);
            if (i = = Master_node_index) {//Jedispool the corresponding cache for each data slot.
            The value of the key is: the subscript of the data slot, and value is Jedispool.
          The slots cache has a total of 16384 Key-value key values for Assignslotstonode (Slotnums, TargetNode);
    finally {W.unlock ()}}}; }
  }
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.