Comments (22)
每秒并发数100,链接池500
如果一秒内完成不了操作,确实会超时
redis服务时本地还是远程,本地不太会这样
from csredis.
是本地的。其实50个并发也很快就满了。我的 redis 操作 主要是用的是 pub/sub .存储的数据是 base64 字符串,大小大概 5、6 K 左右。50并发不大,有什么解决方案吗
from csredis.
原来如此啊,Subscribe 不能回收链接的,多少都会满,尽可能重用 Subscribe
如:
Subscribe(
("chan1", msg => Console.WriteLine(msg.Body)),
("chan2", msg => Console.WriteLine(msg.Body))
)
如果是一次性订阅,RedisHelper.Subscribe 暂时还不支持
from csredis.
Task.Run(() => {
try {
subscr.Client.PSubscribe(chans);
} catch (Exception ex) {
var bgcolor = Console.BackgroundColor;
Console.BackgroundColor = ConsoleColor.Yellow;
Console.WriteLine($"模糊订阅出错(channel:{string.Join(",", chans)}:{ex.Message},5秒后重连。。。");
Console.BackgroundColor = bgcolor;
Thread.CurrentThread.Join(1000 * 5);
PSubscribe(channelPatterns, pmessage);
}
});
RedisHelper.Subscribe 与 RedisHelper.PSubscribe 都是一根筋的设计,错误或断线重新订阅,不适合做一次性订阅,除非用完销毁这个redisClient实例,因为它已经有了对应的订阅事件,属性。。。这不符合连接池管理原则
redis-server本来是没有这种问题的
仍然推荐尽可能重用 Subscribe,不然只能自行现实了,参考文档:https://github.com/ctstone/csredis/blob/master/README.md
from csredis.
我的场景不是一次性订阅的。程序有一个单例的类,在程序启动的时候就执行一次订阅(RedisHelper.Subcribe)。 每次用户提交请求时就 Push。下面是订阅的部分代码:
from csredis.
public partial class BaseController : Controller {
public override void OnActionExecuting(ActionExecutingContext context) {
RedisHelper.Publish("test", DateTime.Now.ToString("g"));
}
}
//在 Startup.cs
RedisHelper.Subscribe(("test", msg => {
Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(msg));
}
));
运行结果,手工访问每个 BaseController 接口都有收到订阅消息
redisHelper 连接池数据,正常
正在下载 apache ab,等会发压力测试结果
from csredis.
Server Software: Kestrel
Server Hostname: localhost
Server Port: 5000
Document Path: /Tag/
Document Length: 4061 bytes
Concurrency Level: 50
Time taken for tests: 3.516 seconds
Complete requests: 5000
Failed requests: 0
Total transferred: 22575000 bytes
HTML transferred: 20305000 bytes
Requests per second: 1422.24 [#/sec] (mean)
Time per request: 35.156 [ms] (mean)
Time per request: 0.703 [ms] (mean, across all concurrent requests)
Transfer rate: 6270.93 [Kbytes/sec] received
from csredis.
CSRedis.ConnectionPool.GetConnection 连接池获取超时(10秒)的可能原因:
1、多次订阅,订阅长期占用连接,不会归还连接池,如上图 freeConnections: 49,allConnections: 50
2、借走连接池 redis 操作较耗时,未能及时完成(默认完成会自动归还)
连接池空的期间,若有借的需求,则 await 10秒,等待归还则马上激活(不用干等10秒),若10秒都无资源归还则抛出上述异常。
from csredis.
我的程序也是这样的实现的,有差别的地方是,我存到 redis 的内容是 png 图片的 base64 字符 ,字符的 size 大概 6K 左右。我想应该是操作比较耗时导致。可以试着把你的测试例子 Push 一个 base64 图片字符串看看
from csredis.
正常的,复制这段代码,可以查看连接池状态
[HttpGet(@"connection/redis")]
public object GetRedisConnectionPool() {
var ret = new Hashtable();
foreach(var pool in RedisHelper.ClusterNodes) {
List<Hashtable> list = new List<Hashtable>();
foreach (var conn in pool.Value.AllConnections) {
list.Add(new Hashtable() {
{ "最后活动", conn.LastActive },
{ "获取次数", conn.UseSum }
});
}
ret.Add(pool.Key, new {
FreeConnections = pool.Value.FreeConnections.Count,
AllConnections = pool.Value.AllConnections.Count,
GetConnectionQueue = pool.Value.GetConnectionQueue.Count,
GetConnectionAsyncQueue = pool.Value.GetConnectionAsyncQueue.Count,
List = list
});
}
return ret;
}
from csredis.
我在 redis-cli
用命令 info
查看过,确实是满的。 我想跟我的代码有关系,在 push
函数,我有用 async task 而 redis push 用的 RedisHelper.Push
from csredis.
push ? 还是 publish?我上面一直讲的是 Publish + Subscribe
push 是操作列表的
都是一个道理,使用方从连接池借走,操作耗时会归还不及时,导致阻塞后面的使用者,这个取决于连接池大小。
注: redis-server 是单线程的,多个连接不会提高效率,连接池的设计是借用其他库的**,避免重复 open close 连接的开销。
from csredis.
是 Publish
,表达有误。这个是我在 Startup.cs
的代码
我的代码跟你的测试用例基本一致了。连接数还是会一直飙上去。
netcore 单例注入 Processor,在 startup.cs 的 processor.run()
就是 执行 Subscribe
,所以在controller 里,我拿到实例应该是同一个,用这个实例 processor.push
from csredis.
_processor.Push 代码发出来看看
[HttpGet(@"connection/redis")]
public object GetRedisConnectionPool() {
var ret = new Hashtable();
foreach(var pool in RedisHelper.ClusterNodes) {
List<Hashtable> list = new List<Hashtable>();
foreach (var conn in pool.Value.AllConnections) {
list.Add(new Hashtable() {
{ "最后活动", conn.LastActive },
{ "获取次数", conn.UseSum }
});
}
ret.Add(pool.Key, new {
FreeConnections = pool.Value.FreeConnections.Count,
AllConnections = pool.Value.AllConnections.Count,
GetConnectionQueue = pool.Value.GetConnectionQueue.Count,
GetConnectionAsyncQueue = pool.Value.GetConnectionAsyncQueue.Count,
List = list
});
}
return ret;
}
把这段代码放进你的项目,请求截图发出来
from csredis.
_processor.Push
的代码在上面回复中已贴了。下面是 Run 的代码
这是服务器的服务运行后 redis info 出来的信息。
这是服务器的服务停止后 redis info 出来的信息
代码统计的图
from csredis.
_processor.Push 的代码在上面回复中已贴了
Run 的发了, _processor.Push 的没有发
from csredis.
from csredis.
压力测试报错的时候,看 [HttpGet(@"connection/redis")] 接口的返回结果
from csredis.
我测试时,都把 async Task 去掉后没发现 10秒超时的报错了,但在redis-cli 看连接数还是满的。
from csredis.
异步可以增加吞吐量,async 可以,因为.net线程池大小没超过500,所以连接池500个用不完
from csredis.
如何在高并发的情况下,防止:
CSRedis.ConnectionPool.GetConnection 连接池获取超时(10秒)
设置poolSize大小多少为合适?
from csredis.
如何在高并发的情况下,防止:
CSRedis.ConnectionPool.GetConnection 连接池获取超时(10秒)
设置poolSize大小多少为合适?
异步方法,没有这个限制。
真实场景极少会这么大访问量,poolsize可以设置成同时刻访问次数/10,比如同时同时同时1000个操作,poolsize=100,具体还要看网络传输速度,如果redis-server是远程的,处理会稍慢。
poolsize好比道路的宽度,设大了浪费,设小了又堵车。所以先确定有多少台车,车速多少来决定。
from csredis.
Related Issues (20)
- 我想知道我的redis连接状态,是否有提供判断的属性 HOT 3
- 请问一下有没有支持ReidisJson的计划 HOT 1
- 建议将Json依赖抽离 HOT 2
- 为什么没有异步锁?在异步代码中使用RedisHelper.Lock导致线程线程饥饿该怎么处理 HOT 7
- xread,xrevrange bug HOT 1
- 同步方法与异步方法的重试机制存在差异 HOT 4
- 请教下大佬,集群模式下,hash结构怎么保证过期时间和值写入同时执行? HOT 2
- RedisHelper.Lock 中获取锁的间隔时间能增加一个参数(sleep)吗
- 状态不可用,等待后台检查程序恢复方可使用 HOT 26
- 执行ZRangeByScoreAsync方法后应用内存增加700MB HOT 3
- 高流量下经常连接超时,但redis监控正常 HOT 3
- GetClient().SubscribeListBroadcast 会每隔一段时间接收一个msg为null的空消息。这个是健康检查吗?造成了困扰。 HOT 1
- 阿里云redis正式环境经常报错Unexpected response type: Status (expecting Int),重启之后过段时间又会报错
- 使用XPending方法报错 HOT 5
- IPv6带端口 哨兵模式 报错 HOT 1
- centos 下重启应用报 订阅出错【r-xxxx:6389/8】:redis-server 连接已断开,3秒后重连。。。 HOT 2
- 订阅出错【r-xxxx:6389/8】:redis-server 连接已断开,3秒后重连。。。
- 连接redis 时redis未就绪,等redis启动完成后,执行xreadgroup报错:Unable to read data from the transport connection: Connection timed out HOT 14
- 可以让pub/sub直接发送或者接受byte[]参数吗? HOT 9
- Connection String Malformed when we using user and password HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from csredis.