最近股票做的不错,实在闲,就想着把日志分析这一块再深入一下。

顺便自己写了几个版本的异步Syslog服务器,用了几种模型,往往是弄完以后呢,看网上评测有更佳实现,或者有更好玩的东西,所以两个语言的多个版本就全弄出来了。

但是异步这事我以前用的比较少,对性能没有太大概念,今天做了个不太严谨的对比测试。

几套程序的流程完全一致,接收日志(udp,rfc3164),然后分解为对应的字段,最后写入mysql库(其实是mariadb)

但是结果与我预期的完全不同,甚至可以说跌掉下巴。

 

环境呢,本机,13代i5,32G内存,几个m2没做阵列,几个ssd的sata做了阵列但没用到,数据收发都在本机

系统 win10专业版

python 3.11.7

.net framework 4.5 / 4.5.2 / 4.8

.net 8.0

 

框架mysql连接方式完成数量内存占用
gevent直连全部30M
gevent连接池99.8%以上29 - 450 - 75M
asyncio直连全部23M
asyncio连接池40xxx (80%)23M
.net framework直连1500+63M
.net framework连接池10063M

 

测试是python脚本异步方式直接丢50000个日志记录过来。目测呢,大概每秒钟接近2000个记录。这个频率应该比超大型网站也不差了。

 

其中.net分别测试了.net framework 4.5/4.5.2/4.8,结果都一样

gevent+连接池因为内存占用太过于夸张,当然工作完成后会回落到70多M,但是一旦遇到突发事件,这个内存占用情况还是挺凶的的,所以感觉不太好。

cpu的使用率没有记录,因为我这关掉e核以后呢,从cpu使用来看,这几个都会占满一个核心,asyncio的使用会少一些,占不满一个核心。

所以最终我打算选择asyncio + 单连接的形式。因为不论压力有多大,内存和cpu使用情况都很稳定,内存从没有超过24M的情况,而且数据一条没丢,这个挺6的。

而.net这个,远超想象,连接池我反复调整都没用,一旦达到官方控件的极限就崩了,而官方还特意讲明应该让系统自己调节连接池,可就是这么个结果……还不如他自己明确禁止的单连接形式。测试了很多轮,最多处理1500多条,有点开玩笑。

而且很奇怪啊,这几个都是用的mysql官方控件,池的上限也曾经调到最大了,但结果是一样的。感觉python和.net的官方mysql控件全都挺差的,只要用连接池,就要么崩掉,要么大量丢数据。也难怪有那么几个比较大的python项目都不推荐用官方控件……

 

总之,个人认为,gevent和asyncio没太大区别,可能在某些特定情况是不同的,但在我的应用场景来说,几M的内存不是事。

然后呢,mysql官方出的连接控件是很烂的,.net平台和python都是。如果要用官方控件,则直连形式是最好的,连接池模式要显式关闭,否则莫名其妙丢数据就会很难调试,因为我这各个平台都没有任何报错。

 

大家可以做个参考吧,从我这里的情况来看,用gevent和asyncio都是很好的,资源使用很少,效率高,且数据一条不丢,gevent编程还很方便。至于.net,那就算了吧。

===============

之所以说跌掉下巴,是测试之前按常理推测,我估计.net能完爆python,因为一个是编译,一个是脚本;一个是多线程,一个是单线程。真是没想到是这么个结果……

================

后续

隔了几天想想不服气,又用queue试了一下,.net 8.0+vs2022,依然掉渣。用官方提供的异步udp服务器代码,收到数据以后异步塞到一个queue里面,不做其他处理,依然只能完成70%左右,而且接收速度明显比python版本的慢一些。

.net真是开玩笑,彻底放弃了。

作者 听涛

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注