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); } }
如上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(); } }