1. 程式人生 > >RedisTemplate執行lua指令碼,叢集模式下報錯解決

RedisTemplate執行lua指令碼,叢集模式下報錯解決

redis叢集配置:

在使用spring的RedisTemplate執行lua指令碼時,報錯EvalSha is not supported in cluster environment,不支援cluster。

程式碼:

    @Test
    public void test4() throws Exception {
        DefaultRedisScript script = new DefaultRedisScript();
        script.setScriptSource(new StaticScriptSource("redis.call('SET', KEYS[1], ARGV[1]); return ARGV[1]"));
        script.setResultType(String.class);
        Object result = redisTemplate.execute(script, Arrays.asList("test_key1"), Arrays.asList("hello,key1"));
        System.out.println(result);
    }

報錯資訊:

org.springframework.dao.InvalidDataAccessApiUsageException: EvalSha is not supported in cluster environment.

	at org.springframework.data.redis.connection.jedis.JedisClusterConnection.evalSha(JedisClusterConnection.java:3561)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.springframework.data.redis.core.CloseSuppressingInvocationHandler.invoke(CloseSuppressingInvocationHandler.java:57)
	at com.sun.proxy.$Proxy136.evalSha(Unknown Source)
	at org.springframework.data.redis.core.script.DefaultScriptExecutor.eval(DefaultScriptExecutor.java:81)
	at org.springframework.data.redis.core.script.DefaultScriptExecutor$1.doInRedis(DefaultScriptExecutor.java:71)
	at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:207)
	at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:169)
	at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:157)
	at org.springframework.data.redis.core.script.DefaultScriptExecutor.execute(DefaultScriptExecutor.java:60)
	at org.springframework.data.redis.core.script.DefaultScriptExecutor.execute(DefaultScriptExecutor.java:54)
	at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:300)
	at com.wwwarehouse.xdw.contractcenter.zzz.RedisTest.test4(RedisTest.java:70)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
	at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
	at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
	at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
	at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
	at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51)
	at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
	at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

但是redis是支援lua指令碼的,只要拿到原redis的connection物件,通過connection去執行即可:

    @Test
    public void test5() throws Exception {
        List<String> keys = new ArrayList<String>();
        keys.add("test_key1");
        List<String> args = new ArrayList<String>();
        args.add("hello,key1");
        String LUA = "redis.call('SET', KEYS[1], ARGV[1]); return ARGV[1]";
        //spring自帶的執行指令碼方法中,叢集模式直接丟擲不支援執行指令碼異常,此處拿到原redis的connection執行指令碼
        String result = (String)redisTemplate.execute(new RedisCallback<String>() {
            public String doInRedis(RedisConnection connection) throws DataAccessException {
                Object nativeConnection = connection.getNativeConnection();
                // 叢集模式和單點模式雖然執行指令碼的方法一樣,但是沒有共同的介面,所以只能分開執行
                // 叢集
                if (nativeConnection instanceof JedisCluster) {
                    return (String) ((JedisCluster) nativeConnection).eval(LUA, keys, args);
                }

                // 單點
                else if (nativeConnection instanceof Jedis) {
                    return (String) ((Jedis) nativeConnection).eval(LUA, keys, args);
                }
                return null;
            }
        });
        System.out.println(result);
    }

輸出: hello,key1

相關推薦

RedisTemplate執行lua指令碼叢集模式解決

redis叢集配置: 在使用spring的RedisTemplate執行lua指令碼時,報錯EvalSha is not supported in cluster environment,不支援cluster。 程式碼: @Test public

處理VS2010+qt4.8.6編譯不錯誤而Linux:error: 'nullptr' was not declared in this scope

今天處理一個同事在VS2010+qt4.8.6下編寫的程式(能夠正確編譯並執行) 我需要將這個程式移植到arm板上,於是在Linux下對此程式進行交叉編譯 於是,問題來了 這個錯誤提示是:nullptr在當前作用域沒有被宣告。 稍作分析,這個nullptr並不是程式定義的,

解決vue專案執行過程中npm run dev 問題

ERR! code ELIFECYCLEnpm ERR! errno 1npm ERR! [email protected] dev: `node build/dev-server.js`npm ERR! Exit status 1npm ERR!npm ERR!

jenkins 執行sh指令碼 沒攜帶環境變數,command not founds問題

有個問題困擾很久:    使用jenkins 執行某sh指令碼或者 直接Execute shell編寫指令碼時, 指令碼中很多命令無法執行, 例如 用npm安裝軟體,  yarn 編寫web工程  都會報錯command not found 這是因為沒有帶上系統的環境變數。

vim模式E37: No write since last change (add ! to override)

故障現象: 使用vim修改檔案報錯,系統提示如下: E37: No write since last change (add ! to override) 故障原因: 檔案為只讀檔案,無法修改。 解決辦法: 使用命令:w!強制存檔即可,在vim模式下,鍵入

建立的maven專案pom.xml檔案解決方法

eclipse建立的maven專案,pom.xml檔案報錯解決方法 【錯誤原因一:】maven 編譯級別過低 【解決辦法:】 使用 maven-compiler-plugin 將 maven 編譯級別改為 jdk1.6 以上: <!-- java編譯外掛

Project xxx is missing required source folder: 'src/main/resources' 問題maven管理工程解決辦法

問題描述: Project xxx is missing required source folder: 'src/main/resources'   原因 : 開發環境中,eclipse.project檔案可能存在對缺失資料夾的引用,但是project中已經沒有了該資料

關於Celery4.x以上在Win10解決辦法

報錯提示: ValueError: not enough values to unpack (expected 3, got 0) 順著程式碼路徑去找原始檔,發現是缺少了一個引數,可是摸索半天不知道該傳什麼。。。 於是把思維轉向面向google和麵向segmentfault解決問題,

java junit測試註解引入service解決辦法

作為程式設計師,搞後端開發,當然離不開單元測試了。舉個例子,測試下mapper介面,service介面等等。當用到spring容器的時候,在測試類直接寫 如下程式碼: @Autowired private AccountService accountServiceIm

AFNetworking升級至3.1.0後原有的方法解決辦法。

為了配合蘋果官方的ipv6的事,有很多開發人員都把AFNetworking升級了(網路請求自己公司做封裝的除外),但是升級後報錯一堆。怎麼辦?我的笨辦法是:一個一個修改。 1.首先:沒有了AFHTTPRequestOperationManager這個類,被AF

從富文字編輯器獲取html內容組裝json特殊字元引起解決辦法。

最近專案需要,需要從富文字編輯器獲取html內容組裝json,然後還要 把組裝後的json物件利用json2轉成json字串,資料放入編輯器提交,由於相容ie8以上瀏覽器。所以搞了好久的特殊字元轉義,

php 用swoole 實現定時器 執行linux指令碼檢查程序掛了重啟操作

利用swoole的定時器,每兩秒檢查一下 class Grep  {          const PORT = 9999;     public function port()  &n

踩坑錄·Redis執行Lua指令碼

Redis環境執行Lua指令碼因未能正確設定全域性變數(global variable)而丟擲錯誤,導致程式終止。 遇到情況 在ZeroBrane Studio工具中使用Redis環境執行如下Lua指令碼: --下面指令碼的意圖是 --分別在Redis中設定鍵t1、t2的值為

redis學習(十五) 使用jedis執行lua指令碼(實現一個對IP的限流)

使用jedis執行lua指令碼(實現一個對IP的限流) 上一篇學習了怎麼安裝lua,這一篇學習編寫一個lua指令碼用jedis執行,實現對一個IP的限流 LUA指令碼如下,第一次使用incr對KEY(某個IP作為KEY)加一,如果是第一次訪問,使用e

使用redistemplate呼叫lua指令碼的簡單應用場景

最近學習了下lua,主要想在redis或者nginx做一些拓展,redis的資料型別很多,能幫助我們處理業務中的很多場景,從 Redis 2.6.0 版本開始,通過內建的 Lua 直譯器,可以使用 EVAL 命令對 Lua 指令碼進行求值。 redis對lua指令碼的呼叫是原子性的,所以一些

QT編譯生成的exe無法執行缺少msvcr120d.dllmsvcr120p.dll,或者0xc000007b問題

最近在除錯QT的程式時,生成的exe檔案總是報錯說報錯缺少msvcr120d.dll,msvcr120p.dll,無法執行 (圖片來源於網路) 在網上亂七八糟搜了一大堆,嘗試下載了對應的msvc*120d.dll,放入C:\Windows\System32,再

C#呼叫命令列執行python指令碼這個辦法可以呼叫python第三方模組和對本地檔案進行操作

string pythonScriptPath = Server.MapPath(@"~\pythonScript");//python指令碼所在的目錄 ProcessStartInfo start = new Pro

shell 指令碼執行python指令碼連線hive提交資料寫入表

使用說明 1.cd /opt/zy 在這個目錄下以root使用者許可權執行命令 2. 在SAP查詢的時候 Tcode:ZMMR0005 Purchase Org * PO Creating:2017/3/1 (開始日期) 2017/

jedis 叢集模式連線redis原理

1.ShardedJedis內部實現 首先我們來看一下ShardedJedis的一個繼承關係 看完了圖,那麼我們一步一步跟著我們的程式碼呼叫來看,以我們最簡單的 ShardedJedis.get(key)方法為例: public String get(St

redis-cluster官方叢集模式使用pipeline批量操作

         redis從3.0版本後引入了令人興奮的cluster叢集模式,相信很多人都嘗試過了,在高興之餘卻發現redis官方的cluster對於java客戶端的jedis支援卻不是很好,至少目前的版本cluster是不支援直接使用pipeline操作,找了好久