Redis+Luaスクリプトによる自己増分プライマリ・キーの生成
3812 ワード
一.概要
redisの2.6バージョンからluaスクリプトのサポートが追加されました.現在使用可能なライブラリは以下のとおりです.
redisのluaスクリプトでosを実行するように.time()はエラーを報告し、osクラスライブラリはサポートされていません.
二.自己増分プライマリ・キーの生成
1.luaスクリプト
2.redisのevalsha呼び出しluaスクリプトによる自己増加プライマリ・キーの生成
evalshaは、luaスクリプトをメモリに事前にロードし、実行効率を向上させるためにshaの列を生成する必要があります.
luaスクリプトをメモリにロードし、大きな文字列を生成し、scriptLoadメソッドで生成された大きな文字列をロードし、shaの列を生成します.luaスクリプトをロードする方法は、apacheのcommons-ioを使用する方法と、Googleのguavaツールクラスを使用する方法の2つです.コードは次のとおりです.
redisは単一スレッドであるためidの自己増加を良好に保証でき,luaスクリプトでの計算,付与,読み出し操作にも原子性がある.
redisの2.6バージョンからluaスクリプトのサポートが追加されました.現在使用可能なライブラリは以下のとおりです.
base
lib table
lib string
lib math
lib struct
lib cjson
lib cmsgpack
lib bitop
lib redis.sha1hex
function redisのluaスクリプトでosを実行するように.time()はエラーを報告し、osクラスライブラリはサポートされていません.
二.自己増分プライマリ・キーの生成
1.luaスクリプト
local temp = 0
local key = KEYS[1]
local inc = ARGV[1]
local exp = ARGV[2]
if inc == nil then
inc = 1
end
if redis.call('EXISTS',key) == 1 then
temp = redis.call('GET',key) + inc
redis.call('SETEX',key,exp,temp)
return temp
else
temp = temp + inc
redis.call('SETEX',key,exp,temp)
return temp
end
2.redisのevalsha呼び出しluaスクリプトによる自己増加プライマリ・キーの生成
package com.icheetor.jedis;
import java.util.Arrays;
import java.util.List;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.util.Pool;
public class CreateId {
private static Pool pool = null;
private static String create_id_sha = null;
static{
pool = new JedisPool("127.0.0.1", 6379);
initCreateIdSha();
}
private static void initCreateIdSha() {
Jedis jedis = pool.getResource();
create_id_sha = jedis.scriptLoad(LoadLuaScriptUtil.loadLuaScript("/createId.lua"));
jedis.close();
}
/**
* 1 id
* @param sha1
* @param key
* @return
*/
private static String getId(String sha1,String key){
List keyList = Arrays.asList(key);
List valueList = Arrays.asList("1","5");
Jedis jedis = null;
try {
jedis = pool.getResource();
String res = jedis.evalsha(sha1, keyList, valueList).toString();
return res;
} catch (Exception e) {
e.printStackTrace();
} finally {
if(jedis != null){
jedis.close();
}
}
return "0";
}
public static String getCreateId(String key) {
if(create_id_sha == null) {
Jedis jedis = pool.getResource();
create_id_sha = jedis.scriptLoad(LoadLuaScriptUtil.loadLuaScript("/createId.lua"));
jedis.close();
}
return getId(create_id_sha, key);
}
public static void main(String[] args) {
System.out.println(getCreateId("tbl_test"));
}
}
evalshaは、luaスクリプトをメモリに事前にロードし、実行効率を向上させるためにshaの列を生成する必要があります.
luaスクリプトをメモリにロードし、大きな文字列を生成し、scriptLoadメソッドで生成された大きな文字列をロードし、shaの列を生成します.luaスクリプトをロードする方法は、apacheのcommons-ioを使用する方法と、Googleのguavaツールクラスを使用する方法の2つです.コードは次のとおりです.
package com.icheetor.jedis;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import com.google.common.io.CharStreams;
/**
* lua ,
* @author iCheetor
*
*/
public class LoadLuaScriptUtil {
/**
* apache commons-io
* @param path
* @return
*/
public static String loadLuaScript(String path){
String luaStr = null;
InputStream in = LoadLuaScriptUtil.class.getResourceAsStream(path);
Reader r = new InputStreamReader(in);
try {
luaStr = org.apache.commons.io.IOUtils.toString(r);
} catch (IOException e) {
e.printStackTrace();
}
return luaStr;
}
/**
* guava
* @param path
* @return
*/
public static String loadLuaScriptByGuava(String path){
String luaStr = null;
InputStream in = LoadLuaScriptUtil.class.getResourceAsStream(path);
Reader r = new InputStreamReader(in);
try {
luaStr = CharStreams.toString(r);
} catch (IOException e) {
e.printStackTrace();
}
return luaStr;
}
}
redisは単一スレッドであるためidの自己増加を良好に保証でき,luaスクリプトでの計算,付与,読み出し操作にも原子性がある.