关于大学选课系统高并发问题的简单思考
大学选课系统,设计存在大量问题
在高并发的时候,必然导致选课困难
故优化如下
1.节省网络带宽
2.节省磁盘IO
3.提高CPU利用率
如何节省网络带宽
现有代码,每次http请求返回的都是完整的html报文,非常占用网络带宽
修改为前后端分离,每次返回增量的json报文,可以大幅提升带宽利用率
举个例子,原来是每次交互都要返回20k的html报文,现在只需要返回2K的json,提升了10倍的容量
第二步,通过cloudflare提供的ngx_brotli_module对数据压缩传输,进一步提升带宽利用率
假设学校使用的是6类网线+千兆交换机
那么上行带宽按1000Mbps计算
每次请求占用了2kb流量,那么理论上足以抗住5万的并发
学校学生按15万人算,基本满足需求了【超过15万人学生的大学,就应该拆分!】
如何节省磁盘IO
首先对于热点数据,用redis做缓存,数据都从内存走,而不是直接访问数据库
redis的数据应该保存 【key = 课程的id,value = 还剩多少名额】,服务每次从redis读取和更新名额数据,而不是数据库。
另外,课程id和课程名字,导师名字,学分,等不会改变的数据,应该在服务启动的时候,内存里建好结构化,数据直接在内存里读取,而不是从数据库读取
这样,可以大幅降低对数据库的IO消耗
简单讲,如果是固定的数据,就内存里存好。如果是会变动的数据,就用redis存。尽量减少对数据库的磁盘IO。
第二步,用update代替insert
正常选课代码,应该是学生选好课程以后,往数据库执行insert操作,让数据库记录学生选了什么课程
因为高并发的情况下,insert太多,磁盘io消耗非常大
所以用更省io的update
具体如下
在选课开始前几天,就批量往数据库insert好所有学生的选课记录,不过都是空记录
在选课的时候,只要执行update就可以了!
这可以高效提升数据库的IO,有3倍提升的效果!
最后是对数据库分库分表
我建议,5万的并发下去update数据库压力还是太大了
建议用两个数据库服务器
每个数据库服务器负责2个学年的学生
比如数据库A服务 2020/2019两个年级,
数据库B负责2018/2017 两个学年的学生
这样,每个数据库只需要负责2.5万的并发请求【如果还是扛不住,就一个学年一个数据库,分4个】
如何提高CPU利用率
前后端分离,所以数据都是json
为了提升json的处理效率,使用simdjson
可以在json的处理上,提升10倍的速度
先想到这么多
想到其他的继续优化
在高并发的时候,必然导致选课困难
故优化如下
1.节省网络带宽
2.节省磁盘IO
3.提高CPU利用率
如何节省网络带宽
现有代码,每次http请求返回的都是完整的html报文,非常占用网络带宽
修改为前后端分离,每次返回增量的json报文,可以大幅提升带宽利用率
举个例子,原来是每次交互都要返回20k的html报文,现在只需要返回2K的json,提升了10倍的容量
第二步,通过cloudflare提供的ngx_brotli_module对数据压缩传输,进一步提升带宽利用率
假设学校使用的是6类网线+千兆交换机
那么上行带宽按1000Mbps计算
每次请求占用了2kb流量,那么理论上足以抗住5万的并发
学校学生按15万人算,基本满足需求了【超过15万人学生的大学,就应该拆分!】
如何节省磁盘IO
首先对于热点数据,用redis做缓存,数据都从内存走,而不是直接访问数据库
redis的数据应该保存 【key = 课程的id,value = 还剩多少名额】,服务每次从redis读取和更新名额数据,而不是数据库。
另外,课程id和课程名字,导师名字,学分,等不会改变的数据,应该在服务启动的时候,内存里建好结构化,数据直接在内存里读取,而不是从数据库读取
这样,可以大幅降低对数据库的IO消耗
简单讲,如果是固定的数据,就内存里存好。如果是会变动的数据,就用redis存。尽量减少对数据库的磁盘IO。
第二步,用update代替insert
正常选课代码,应该是学生选好课程以后,往数据库执行insert操作,让数据库记录学生选了什么课程
因为高并发的情况下,insert太多,磁盘io消耗非常大
所以用更省io的update
具体如下
在选课开始前几天,就批量往数据库insert好所有学生的选课记录,不过都是空记录
在选课的时候,只要执行update就可以了!
这可以高效提升数据库的IO,有3倍提升的效果!
最后是对数据库分库分表
我建议,5万的并发下去update数据库压力还是太大了
建议用两个数据库服务器
每个数据库服务器负责2个学年的学生
比如数据库A服务 2020/2019两个年级,
数据库B负责2018/2017 两个学年的学生
这样,每个数据库只需要负责2.5万的并发请求【如果还是扛不住,就一个学年一个数据库,分4个】
如何提高CPU利用率
前后端分离,所以数据都是json
为了提升json的处理效率,使用simdjson
可以在json的处理上,提升10倍的速度
先想到这么多
想到其他的继续优化
7 个评论
如果单个服务无法承担5万的高并发
我建议用nginx做一个负载均衡
开多个服务来做
为了节省内存,不使用Java这类语言编写服务
改用Go语言来写【省内存,适合高并发】
一般来想,必修课和选修课,人员选课有固定性,可以在数据库层优化掉
也就是路由规则里增加学年判定
只有一些4个年级的公共选修课比较复杂
比如珠宝鉴赏,这样的课程,需要做统一处理
我建议用nginx做一个负载均衡
开多个服务来做
为了节省内存,不使用Java这类语言编写服务
改用Go语言来写【省内存,适合高并发】
一般来想,必修课和选修课,人员选课有固定性,可以在数据库层优化掉
也就是路由规则里增加学年判定
只有一些4个年级的公共选修课比较复杂
比如珠宝鉴赏,这样的课程,需要做统一处理
我們大學的時候,學校發現解決不了,改為提前一兩個月預選,然後抽籤。不同類別課程,分批公布抽籤結果,抽籤公布後沒抽到的再選有空位的課程,就不會擁堵了。
我們大學的時候,學校發現解決不了,改為提前一兩個月預選,然後抽籤。不同類別課程,分批公布抽籤結果,抽...
中国,大陆每年应届毕业870万人口。。。
明显是大学人口太多,造成了选课困难的问题
如果大学只招250万人口,那么大学选课就不会有高并发的问题了
主要还是共产党的大学扩招造成的!
共产党为什么要大学扩招,不是为了提高人民的知识文化水平
仅仅是因为人口太多了,需要缓解就业压力,把人往学校里挤
人口太多,也是共产党当年为了侵略全世界,朝鲜战争那段时间拼命生造成的
现在计划生育,是为了当年的人口问题
中国,大陆每年应届毕业870万人口。。。明显是大学人口太多,造成了选课困难的问题如果大学只招250万...
併發數目高是管理問題,和招生人數無關。公選課開100門,大家想選的也就其中10門課,剩下的不是沒意思就是不好過,肯定擠死人。
当年我校更新系统的时候,几个学生技术社团提出免费做这件事情,不要再找些草台团队来做事。然而众所周知,大学的网站属于toG(Government)项目,大学对网站专门立项,就有拨款,于是中间就有吃拿卡要的空间,至于小舅子找来的草台团队写出的草台网站用户体验如何并不在考虑的范围之内。
你学生想要给学校免费写网站?那不就没有立项拨款了吗?断人财路如杀人父母好不好。
你学生想要给学校免费写网站?那不就没有立项拨款了吗?断人财路如杀人父母好不好。
翻译:你以为我不知道?你来当领导?找人干活你出钱吗?
选课系统,随便找几个学生写写就行了
哪个大学没有计算机学院?没几个实验室?
写个选课系统,基本1个月就好了
学生都是不要钱的。。。
伯克利写了spark,也没有给学生钱啊