Implement distributed locks using Redis scripts

Source: Internet
Author: User
Tags redis cluster install redis

Implement distributed locks using Redis scripts

Redis is widely used in distributed environments. It is a problem immediately to solve the locks in distributed environments. For example, in our current mobile game project, servers are divided by business modules, including application servers and combat servers. However, both VMS may change the player attributes at the same time, if it is under the same vm, it is easy to lock, but it is not so easy in a distributed environment. Of course, there are also solutions to use the existing functions of redis, for example, redis script.

Redis Versions later than 2.6 have added the Lua Script Function. You can run the Lua script directly in the RedisServer environment using the eval command and call the Redis command in the Lua script.
Advantages of using scripts:
1. reduce network overhead: some features to be processed in batches can be sent to a script for execution, reducing the number of interactions between the client and redis.
2. atomic operation: This is the main feature we use here to ensure data Atomicity in a distributed environment.
3. Reuse: scripts sent by the client are permanently stored in redis. This means that other clients can reuse the script without using code to complete the same logic.

Next, let's take a look at a lua script:
Local food = redis. call ('hget', KEYS [1], 'food ');
Food = food + ARGV [1];
Redis. call ('hset', KEYS [1], 'food', food );
Local diamond = redis. call ('hget', KEYS [1], 'Diamond ');
Diamond = diamond + ARGV [2];
Redis. call ('hset', KEYS [1], 'Diamond ', diamond );
Note: redis. call is the redis command we call in the script. The KEYS and ARGV2 arrays are KEYS and parameters respectively, and the subscript starts from 1, not 0.
The function of this script is to take out the food and diamond (JADE) players specified by KEYS, modify them, and save them in redis. The script is executed, guarantees the atomicity of the entire operation.

Next we will use java code to look at the specific implementation process

Jedis jedis = new Jedis ("192.168.128.128", 6379 );
// 1. The initial gamer data is sent to redis
GamePlayer player = new GamePlayer ();
Player. setId (1001 );
Player. setName ("ksfzhaohui ");
Player. setFood (100 );
Player. setDiamond (100 );
 
Map <String, String> beanMap = BeanUtil. warp (player); // converts an object to a map
String beanKey = getRedisBeanKey (player. getClass (), player. getId ());
System. out. println ("key:" + beanKey );
Jedis. hmset (beanKey, beanMap); // save player data to redis
 
First, a player is simulated to save the player information in redis. The Id here is written at will. Normally, an id is generated through the redis command incr.
Result:


 
String script = "local food = redis. call ('hget', KEYS [1], 'food ');"
+ "Food = food + ARGV [1];"
+ "Redis. call ('hset', KEYS [1], 'food', food );"
+ "Local diamond = redis. call ('hget', KEYS [1], 'Diamond ');"
+ "Diamond = diamond + ARGV [2];"
+ "Redis. call ('hset', KEYS [1], 'Diamond ', diamond );";
List <String> keys = new ArrayList <String> ();
Keys. add (beanKey );
List <String> args = new ArrayList <String> ();
Args. add ("100 ");
Args. add ("100 ");
// 3. Execute the script
Jedis. eval (script, keys, args );

Specify the key and reference, and execute the script. Result:

BeanUtil code:

Public class BeanUtil {
Private static Logger logger = Logger. getLogger (BeanUtil. class );
Private static final String CLASS = "class ";
 
/**
* Encapsulate the specified object data into a map
*
* @ Param bean
* Object Data
* @ Return
*/
@ SuppressWarnings ("all ")
Public static Map <String, String> warp (Object bean ){
Map <String, String> propertyMap = new HashMap <String, String> ();
Try {
PropertyDescriptor [] ps = Introspector. getBeanInfo (bean. getClass ())
. GetPropertyDescriptors ();
For (PropertyDescriptor propertyDescriptor: ps ){
String propertyName = propertyDescriptor. getName ();
If (propertyName! = Null &&! PropertyName. equals (CLASS )){
Method getter = propertyDescriptor. getReadMethod ();
If (getter! = Null ){
PropertyMap. put (propertyName,
String. valueOf (getter. invoke (bean, null )));
}
}
}
} Catch (Exception e ){
Logger. error (e );
}
Return propertyMap;
}
 
}
 
Of course, there are other methods on the Internet, such as using SETNX to implement distributed locks.
Refer:

Install and test Redis in Ubuntu 14.04

Redis cluster details

Install Redis in Ubuntu 12.10 (graphic explanation) + Jedis to connect to Redis

Redis series-installation, deployment, and maintenance

Install Redis in CentOS 6.3

Learning notes on Redis installation and deployment

Redis. conf

Redis details: click here
Redis: click here

This article permanently updates the link address:

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.