redis-lua脚本

        redis支持lua脚本,lua脚本的详细语法和简绍不在这篇文章的总结范围。这里只说一下redis和lua的结合。

        原子性

        redis执行lua脚本是原子性的,因此可以作为事务的解决方案。

        脚本缓存

        为了加快速度,redis在load脚本的时候会生成一个sha加密的token,使用evalsha命令可以传入token执行缓存中的脚本。

        evalsha命令

        参数分别为sha token,键的数量,键名和参数。在jedis中则有多个重载的方法

        对应到lua中,参数则是table类型的变量,键名可以通过KEY[n](n从1开始)取值。参数则通过ARGV[n](n从1开始)取值

        清除缓存

        调用script flush命令


        示例

        

/**
	 * 
	 * 执行lua脚本
	 * 
	 * @param scriptName
	 * @param script
	 * @param keyCount
	 * @param params
	 * @return
	 */
	public static Object evalScript(String scriptName,String script,int keyCount,String ... params) {
		logger.info("JedisUtil.evalScript.start,scriptName="+scriptName+",\n script=["+script+"]");
		Jedis jedis = new Jedis(HOST, PORT);
		jedis.auth(PASSWORD);
		String sha = jedis.get("script-sha-"+scriptName);
		logger.info("JedisUtil.evalScript.start,scriptName="+scriptName+",sha="+sha);
		if(sha==null || "".equals(sha) || !jedis.scriptExists(sha)) {
			sha = jedis.scriptLoad(script);
			jedis.set("script-sha-"+scriptName, sha);
			logger.info("JedisUtil.evalScript.start,new sha="+sha);
		}
		logger.info("JedisUtil.evalScript.start,scriptName="+scriptName+",script="+script);
		Object retValue = jedis.evalsha(sha, keyCount, params);
		logger.info("JedisUtil.evalScript.end,retValue="+retValue);
		return retValue;
	}

/**
	 * 
	 * 清除lua脚本缓存
	 * 
	 * @return
	 */
	public static boolean flushScript() {
		logger.info("JedisUtil.flushScript.start");
		Jedis jedis = new Jedis(HOST, PORT);
		jedis.auth(PASSWORD);
		String retValue = jedis.scriptFlush();
		logger.info("JedisUtil.flushScript.end,retValue="+retValue);
		if("OK".equals(retValue.toUpperCase())) {
			return true;
		} else {
			return false;
		}
	}

private final static String GET_JSON_SCRIPT = "redis.log(redis.LOG_NOTICE, \"get json start\") " +
												  "if redis.call(\"EXISTS\", KEYS[1]) == 1 then " +
												  "    redis.log(redis.LOG_NOTICE, \"get json,key:\" .. KEYS[1]) " +
												  "	   local payload = redis.call(\"GET\", KEYS[1]) " +
												  "	   redis.log(redis.LOG_NOTICE, \"get json,payload:\" .. payload) " +
												  "    local value = cjson.decode(payload)[ARGV[1]] " +
												  "	   redis.log(redis.LOG_NOTICE, \"get json,value:\" .. value) " +
												  "	   return value " +
												  "else " +
												  "    redis.log(redis.LOG_NOTICE, \"get json,not found key,key:\" .. KEYS[1]) " +
												  "	   return nil " +
												  "end";
	
	private final static String GET_JSON_SCRIPT_NAME = "GET_JSON_SCRIPT";

/**
	 * 
	 * 获得json格式数据的值
	 * 
	 * @param key
	 * @param jsonKey
	 * @return
	 */
	public static Object getJson(String key, String jsonKey) {
		logger.info("JedisUtil.getJson.start,key="+key+",jsonKey="+jsonKey);
		Jedis jedis = new Jedis(HOST, PORT);
		jedis.auth(PASSWORD);
		Object retValue = evalScript(GET_JSON_SCRIPT_NAME,GET_JSON_SCRIPT,1,key,jsonKey);
		logger.info("JedisUtil.getJson.end,retValue="+retValue);
		return retValue;
	}

public static void main(String[] args) {
		try {
 
			JedisUtil.set("test", "{\"a\":\"s\",\"b\":\"t\"}");
			//JedisUtil.flushScript();
			Object retValue = JedisUtil.getJson("test", "b");
			
			System.out.println("----------------"+retValue+"----------------");
 
		} catch (Exception e) {
			e.printStackTrace();
		}
	}


你可能感兴趣的:(redis,java,web)