Hand Tour service End frame of use Redis to achieve the cross-clothing ranking

Source: Internet
Author: User
Tags redis redis cluster
the general method to realize the cross-service ranking

In order to stimulate the players in the game of comparison psychology, often have a variety of rankings. The list can also be divided into the list of this service and cross-service rankings.

To put it simply, the record on this list comes from the players in this suit, and the record on the cross-service list is from all the top N players on the server. Usually, the cross-service list is more gold and the rewards are richer. Technically, it's also more cumbersome to achieve.

Typically, there are several ways to achieve a cross-service ranking.

Take one of the servers as a central service to collect the data and broadcast the list of each service; Use standalone processes, such as web backgrounds, to pull the leaderboard data to each service; By using Redis's SortedSet, Redis's own order is achieved.

This article describes in detail how to use Redis to realize the simple usage of cross-service ranking Redis cluster

Redis is a key-value cache database. There is not much to be introduced here. To improve IO efficiency, the latest Redis support cluster services. The official Redis does not support the Windows environment, so the development environment for this article is on Linux Ubuntu. The Redis Java client implementation is Jedis. The following simple encapsulation of the rediscluster, including various data operations on the Redis.

public enum Rediscluster {INSTANCE;

	Private Jediscluster cluster;
		public void init () {String url = ' 127.0.0.1:8001 ';
		hashset 
Technical Essentials of Redis to realize cross-service ranking 

With the Redis SortedSet, the sequential mapping of role ID and score can be realized easily. And for the specific ranking records, you can use the Redis HASHMAP data structure for storage.

Because the score type of the Redis SortedSet is double, only 52-bit integer precision is available. And the list of business often needs multi-level ranking. For example, the player ranking needs to achieve a high level of players in the front, when the player level is the same, the first to reach a high level of need to row ahead.

In order to achieve multi-level ranking, we need to map multidimensional factors to one dimension factor. In 52-bit precision, we can put the low 32-bit to represent record creation time, high 20-bit to represent the rank value. The 20-bit maximum is more than 1 million, and if you exceed this value, you should reconsider the number of digits or the ranking factor. In order to be easy to expand, a method that generates one-dimensional fractions must allow subclasses to modify them.

Code implementation of cross-service rankings

The parent Interface Crossrank.java code list abstract, including the first rank index, the two rank index, the generation time, constructs the Redis data key and so on abstract method.

Public interface Crossrank {
	
	int getranktype ();

	/**
	 * Local server ID
	 * @return
	/int Getserverid ();

	Long Getcreatetime ();
	
	Long Getplayerid ();

	/** 
	 * A  rank score
	 * @return
	/int getscore ();

	/** 
	 *  Second level rank score
	 * @return
	/int getaid ();

	/** redis Rank Type key *
	/String Buildrankkey ();
	
	/** Redis rank Record key *
	/String Buildresultkey ();

	/** Redis rank score
	/long Buildrankscore ();

}
Abstractcrossrank is a skeleton implementation of the Crossrank, providing as much of the default implementation of methods as possible
Second Level rank score * * @Protobuf private int aid; 

	/** 32-bit timestamp/protected long time_max_value = 0xFFFFFFFFL;
		Public Abstractcrossrank (long playerID, int score, int aid) {This.playerid = playerID;
		This.score = score;
		This.aid = aid;
		This.serverid = Serverconfig.getinstance (). Getserverid ();
	This.createtime = System.currenttimemillis ();
	Abstractcrossrank (long playerID, int score) {This (playerID, score, 0);
	Public Abstractcrossrank () {} public int Getserverid () {return serverid;
	Public long Getplayerid () {return this.playerid;
	Public long Getcreatetime () {return createtime;
	public int Getscore () {return score;
	public int Getaid () {return aid;
	@Override public String Buildrankkey () {return "CROSSRANK_" + getranktype ();
	@Override public String Buildresultkey () {return getclass (). Getsimplename ();    @Override public Double Buildrankscore () {//default rank score//score  | Createtime//20bits 32bits long Timepart = (Time_max_value-getcreatetime ()/1000) & Time_max_value
		; Long result = (long) score << 32 |
Timepart; System.err.println ((long) score << 32) + "|" +timepart+ "|"
		+result);
	return result; @Override public String toString () {return "Abstractcrossrank [serverid=" + ServerID + ", createtime=" + CRE
	Atetime + ", playerid=" + playerID + ", score=" + score + ", aid=" + aid + "]; }

}

Crosslevelrank is an example implementation that represents player level data

/**
 *  Cross Server level rank 
 * @author Kingston * * */Public
class Crosslevelrank extends Abstractcrossrank {
	
	//Just for JPROTOBUF public
	Crosslevelrank () {
		
	} public

	Crosslevelrank (long playerID, int score) {
		super (playerID, score);
	}
	
	public int Getranktype () {
		return  crossrankkinds.level
	}}

}
Crossrankservice is the list logic Operation tool, provides the list data update and the inquiry
public class Crossrankservice {private static crossrankservice instance;

	Private Rediscluster cluster = rediscluster.instance; Private Map<integer, class<?

	Extends abstractcrossrank>> rank2class = new hashmap<> ();
		public static Crossrankservice getinstance () {if (instance!= null) {return instance;
				} synchronized (Crossrankservice.class) {if (instance = null) {instance = new Crossrankservice ();
			Instance.init ();
	} return instance;
	private void Init () {rank2class.put (crossrankkinds.fighting, Crosslevelrank.class);
		public void Addrank (Crossrank rank) {String key = Rank.buildrankkey ();
		String member = Buildrankmember (Rank.getplayerid ());
		Double score = Rank.buildrankscore (); 

		Cluster.zincrby (key, score, member);
		Add challenge result data.
		String data = rediscodechelper.serialize (rank);
	Cluster.hset (Rank.buildresultkey (), member, data); Private String Buildrankmember (long playerID) {return String.valueof (playerID); list<crossrank> queryrank (int ranktype, int start, int end) {list<crossrank> ranks = new Arrayl
		Ist<> ();
		
		Set<tuple> TupleSet = cluster.zrevrangewithscores ("crossrank_" + ranktype, start, end); class<?
		Extends abstractcrossrank> Rankclazz = Rank2class.get (Ranktype);
				for (Tuple record:tupleset) {try{String element = Record.getelement ();
				Abstractcrossrank Rankproto = Rankclazz.newinstance ();
				String Resultkey = Rankproto.buildresultkey ();
				String data = Cluster.hget (Resultkey, Element);
				Crossrank rank = unserialize (data, rankclazz);
			Ranks.add (rank);
			}catch (Exception e) {e.printstacktrace ();
	} return ranks; <t extends crossrank> T unserialize (String rankdata, class<t> clazz) {return REDISCODECHELPER.D
	Eserialize (Rankdata, clazz); }

}
Test code, open redis Cluster service, execute Redisranktest class unit test
public class Redisranktest {
	
	@Test public
	void Test () {
		rediscluster cluster = rediscluster.instance;
		Cluster.init ();
		Cluster.clearalldata ();
		Crossrankservice Rankservice = Crossrankservice.getinstance ();
		
		Final int n_record =  ten;
		for (int i=1;i<n_record*2;i++) {
			Rankservice.addrank (new Crosslevelrank (I, 100+i));
		}
		
		List<crossrank> ranks = Rankservice.queryrank (crossrankkinds.fighting, 1, n_record);
		for (Crossrank rank:ranks) {
			System.err.println (rank);
		}
		Asserttrue (ranks.size () = = N_record);
		Asserttrue (Ranks.get (0). Getscore () >= ranks.get (1). Getscore ());
		
	}
	


Hand Tour Service End Open source Framework series complete code please go to GitHub->> Jforgame





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.