代码改变世界

Redis高并发超时问题

2024-10-25 18:31  若藜520  阅读(7)  评论(0编辑  收藏  举报

 

StackExchange.Redis 驱动有个超时问题,并发比较高的时候就会出现类似以下错误,比如开3000个线程:

 StackExchange.Redis.RedisConnectionException: It was not possible to connect to the redis server(s). Error connecting right now. To allow this multiplexer to continue retrying until it's able to connect, use abortConnect=false in your connection string or AbortOnConnectFail=false; in your code. 

 

可以通过在每次开启线程前先开启连接的方式解决,可以在应用启动的时候开启连接

 

public class RedisHelper
{
    private static ConnectionMultiplexer redis;
    private static readonly object Locker = new object();
    static RedisHelper()
    {
        if (redis == null || !redis.IsConnected)
        {
            lock (Locker)
            {
                if (redis == null || !redis.IsConnected)
                {
                    // 创建连接到Redis服务器的连接Multiplexer
                    redis = ConnectionMultiplexer.Connect("bj-crs-lcc2fhzg.sql.tencentcdb.com:26042,password = mango2024@");
                }

            }
        }
    }

    public static void Set(string key, string val, double time)
    {
        // 存储数据
        IDatabase db = redis.GetDatabase();
        TimeSpan? expiry = TimeSpan.FromMinutes(time); // 设置过期时间
        db.StringSet(key, val, expiry);
    }
}
View Code

如上redis帮助类在控制台程序开启线程前new一个实例就会开启连接,就不会出现超时错误,如果把new实例注释掉,就会出现超时。虽然不先实例化有静态构造函数理论上也只执行一次,但是在线程并发的情况下并未得到预期的效果,还是会报错

    internal class Program
    {
        static void Main(string[] args)
        {
            
            List<Task> tasks = new List<Task>();
            ConcurrentQueue<string> cons = new ConcurrentQueue<string>();
            int j = 0;
            //RedisHelper redisHelper = new RedisHelper();//开启线程前需要先实例化一下,否则会出现超时问题,这句注释掉则会超时,不注释则不超时,可以很快的查数据,Web可以在Global,Application_Start方法先初始化
            for (int i = 0; i < 60000; i++)
            {
                
                    var t =Task.Run(( ) =>
                    {
                        j++;
                        Console.WriteLine(j);
                        try
                        {
                            RedisHelper.Set("str1", "str1", 2880);
                        }
                        catch (Exception e)
                        {

                            Console.WriteLine(e);
                        }
                    }
);
                tasks.Add(t);



            }

            Task.WaitAll(tasks.ToArray());

            Console.ReadLine();
        }
    }
View Code