zoukankan      html  css  js  c++  java
  • c#中用lua脚本执行redis命令

    直接贴出代码,实现执行lua脚本的方法,用到的第三方类库是 StackExchange.Redis(nuget上有)
    注:下面的代码是简化后的,实际使用要修改,
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Threading.Tasks;
    using StackExchange.Redis;
    
    
    namespace TL.Cloud.KV
    {
        public class Kv:IKv
        {
           
           
            private  ConfigurationOptions _redisConfig;// = new ConfigurationOptions
            private  IDatabaseAsync _db;//=Connection.GetDatabase();
            private  IServer _server;// = GetServer();
            private  string _keyPrefix;// 区分前缀
    
            /// <summary>
            /// 每个微服务一个kv云实例,或共享云实例中(无独立前缀,服务间Key取名需要自行防止冲突)
            /// </summary>
            /// <param name="hostServiceName">宿主微服务</param>
            public Kv(PublicCloudKvConfig config)
            {
                Init(config);
            }
    
            private void Init(PublicCloudKvConfig config)
            {
                //独特的区分dev/100前缀,online可以没有
                _keyPrefix = string.IsNullOrWhiteSpace(config.KeyPrefix)
                    ?null
                    :config.KeyPrefix.Trim().ToLower()+':';//小写带冒号分割
                //ali kv
                var kvUrl = config.KvUrl;
    
    
                _redisConfig = ConfigurationOptions.Parse(kvUrl);
               
                _redisConfig.Password = config.KvPassword;
                _redisConfig.SetDefaultPorts(); //自动填充默认端口
                var connection = ConnectionMultiplexer.Connect(_redisConfig);
                _db = connection.GetDatabase();
                _server = GetServer();
                
            }
    
            private  IServer GetServer()
            {
                var config = new ConfigurationOptions
                {
                    KeepAlive = 0,
                    EndPoints = { _redisConfig.EndPoints[0]},
                    AbortOnConnectFail = false,
                    AllowAdmin = true
                };
                var conn = ConnectionMultiplexer.Connect(config);
                return conn.GetServer(config.EndPoints[0]);
            }
    
            public Task<RedisResult> EvalLua(string lua, IList<RedisKey> keys, IList<RedisValue> values)
            {
                if (_keyPrefix != null)
                    keys = keys.Select(p => p.Prepend(_keyPrefix)).ToList();//加上前缀
                return _db.ScriptEvaluateAsync(lua, keys.ToArray(), values.ToArray());
            }
            
    
            public async Task<RedisResult> EvalLua(byte[] luaSha1, IList<RedisKey> keys, IList<RedisValue> values)
            {
                if (_keyPrefix != null)
                    keys = keys.Select(p => p.Prepend(_keyPrefix)).ToList();//加上前缀
                return await _db.ScriptEvaluateAsync(luaSha1, keys.ToArray(), values.ToArray());
            }
            
          
    
            public async Task<byte[]> LoadLuaToServerAsync(string lua)
            {
                var sha1 = lua.CalcLuaSha1();//本地计算
                if(!await _server.ScriptExistsAsync(sha1))//服务器上不存在
                     sha1 = await _server.ScriptLoadAsync(lua);//应该和计算的相同
                    
                return sha1;
            }
        }
    }

    下面是测试代码段

    //下面是测试代码
            [Test]
            public async Task LoadLuaToServerAsync()
            {
                var key = "TestEvalLua10010";
                var fieldContent = "testlua10011";
                const string lua =
                    "redis.call('SET', KEYS[1], ARGV[1])
    " +
                    "return redis.call('GET', KEYS[1])
    ";
    
                var sha2 = lua.CalcLuaSha1();
                var sha1 = await _kv.LoadLuaToServerAsync(lua);
                Assert.AreEqual(20, sha1.Length);
                for (var i = 0; i < 20; i++)
                    Assert.AreEqual(sha1[i],sha2[i]);
                
                var keys = new List<RedisKey> { key };
                var values = new List<RedisValue> { fieldContent };
                var result = await _kv.EvalLua(sha1, keys, values);
                Assert.AreEqual(fieldContent, (string)result);
            }

    计算sha1用到的方法

    //计算lua的sha1结果,作为执行lua的参数
            public  static byte[] CalcLuaSha1(this string lua)
            {
                SHA1 sha1 = new SHA1CryptoServiceProvider();
                var bytesSha1In = Encoding.Default.GetBytes(lua);
                return sha1.ComputeHash(bytesSha1In);
            }
  • 相关阅读:
    一些有用的正则
    UNION ALL合表查询
    远程桌面连接:出现身份验证错误,要求的函数不受支持,可能是由于CredSSP加密Oracle修正的解决方法
    Ubuntu20.04安装、配置openvas
    awvs13破解安装、批量扫描脚本
    剑指05题
    时间复杂度o(1), o(n), o(logn), o(nlogn)
    Intellij IDEA 注释模板
    Explain详解
    Hibernate中get()和load()的区别
  • 原文地址:https://www.cnblogs.com/hnsongbiao/p/8250068.html
Copyright © 2011-2022 走看看