redisによる分散ロック
4165 ワード
通常、導入されるサービスは複数のサーバにあり、1台だけではありません.分散環境では、共有リソースの問題に直面します.例えば、一人で1つの記録しか持っていないので、今度入ってくると修正するしかなく、これ以上追加するのではありません.1台のサーバしかない場合は、マルチスレッドでの単一のモードで制御できますが、分散では管理されません.
3つの方法があります.1つはデータベースの楽観的なロック、2つはredisのロック、3つはzookeeperが提供するロックです.ここでreidsについて説明します.このサイトを参照してください.https://www.cnblogs.com/linjiqin/p/8003838.html
以下は他人のブログを参考に整理したコードです.
以下は呼び出しコード
redisツールクラスのロックコード
redisツールクラスのロック解除コード
実はjedisが提供する方法を使って、myRedisClusterForHessianはクラスタの下でjedisを取得する方法をカプセル化したにすぎない.コアメソッドは以下の通りである:jedis.set(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime); 呼び出しの最下位実装
キー、ロックされたキー(名前)requestId、ロックされたクライアントid nxxx NX|XX、NX–設定キーが存在しなければ、存在しない;XX–keyが存在する場合のみ設定、存在しない場合expx EX|PX、EX-失効時間単位秒、PX-失効時間単位ミリ秒time失効時間長戻りOK表示成功
uuidを通じて同じkeyにロックをかけ、異なるサーバ、uuidは異なり、誰がロックしたのか、誰がロックを解除するしかない.またはタイムアウト時間に達すると自動的にロックが解除されます.
3つの方法があります.1つはデータベースの楽観的なロック、2つはredisのロック、3つはzookeeperが提供するロックです.ここでreidsについて説明します.このサイトを参照してください.https://www.cnblogs.com/linjiqin/p/8003838.html
以下は他人のブログを参考に整理したコードです.
以下は呼び出しコード
String lockKey=“xxxxkey”;
String requestId=UUID.randomUUID().toString();
String lockResult=RedisUtil.lockWithSecond(lockKey,requestId,30);
if(!RedisConstants.LOCK_SUCCESS.equals(lockResult)){
, 。。。
}
try{
。。。。
}catch(Exceptionee){
}finally{
RedisUtil.unLock(lockKey,requestId);
}
redisツールクラスのロックコード
/** * * @param lockKey, key( ) * @param requestId, id * @param expireTime * OK */
public static String lockWithSecond(String lockKey,String requestId,int expireTime){
String result=myRedisClusterForHessian.getJedisCluster().set(
lockKey,
requestId,
"NX",
"EX",
expireTime);
return result;
}
redisツールクラスのロック解除コード
/** * ,0- ,1- * @return */
public static Long unLock(String lockKey,String requestId){
if (requestId.equals(myRedisClusterForHessian.getJedisCluster().get(lockKey))) {
return myRedisClusterForHessian.getJedisCluster().del(lockKey);
}else{
return 0L;
}
}
実はjedisが提供する方法を使って、myRedisClusterForHessianはクラスタの下でjedisを取得する方法をカプセル化したにすぎない.コアメソッドは以下の通りである:jedis.set(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime); 呼び出しの最下位実装
/** * Set the string value as value of the key. The string can't be longer than 1073741824 bytes (1 * GB). * @param key * @param value * @param nxxx NX|XX, NX -- Only set the key if it does not already exist. XX -- Only set the key * if it already exist. * @param expx EX|PX, expire time units: EX = seconds; PX = milliseconds * @param time expire time in the units of expx
* @return Status code reply */
public String set(final String key, final String value, final String nxxx, final String expx,
final long time) {
checkIsInMultiOrPipeline();
client.set(key, value, nxxx, expx, time);
return client.getStatusCodeReply();
}
キー、ロックされたキー(名前)requestId、ロックされたクライアントid nxxx NX|XX、NX–設定キーが存在しなければ、存在しない;XX–keyが存在する場合のみ設定、存在しない場合expx EX|PX、EX-失効時間単位秒、PX-失効時間単位ミリ秒time失効時間長戻りOK表示成功
uuidを通じて同じkeyにロックをかけ、異なるサーバ、uuidは異なり、誰がロックしたのか、誰がロックを解除するしかない.またはタイムアウト時間に達すると自動的にロックが解除されます.