所有栏目 | 云社区 美国云服务器[国内云主机商]
你的位置:首页 > 云社区 » 正文

一个系统在用户多,高并发的情况下,数据库该如何设计?

发布时间:2020-04-15 16:13:55

资讯分类:并发  数据库  用户  设计  缓存  并发  数据库
一个系统在用户多,高并发的情况下,数据库该如何设计?

当一个系统的用户量大,并发请求特别高的情况下,如果我们想要撑住这样的并发量,我们要考虑的可不能单单是数据库如何设计,我们还是需要从整个系统的角度来进行考虑。

首先,磁盘IO才是出现系统性能瓶颈的罪魁祸首

我们现在使用的关系型数据库中,为了保证数据的完整性,都会有锁的机制。也就是因为锁的存在,让数据的高并发的情况下,效率有所下降。当然,更重要的是,数据库中的数据是通过文件的形式存放在磁盘中,磁盘的读写速度是非常有限的,因此,高并发的情况下,数据库非常容易成为系统性能的瓶颈所在。

如何让系统的能够支持高并发的场景,不让数据库成为瓶颈呢?

既然系统的瓶颈来源于数据库的IO,那么减少数据库的IO自然就能够有效的提高系统的性能,能适应高并发的场景,最有效的方式就是缓存。

一般缓存我们有两种方式:本地缓存和分布式缓存。

本地缓存其实消耗的是应用服务器的资源,如果系统规模很小的话,这种方式比较适用。但是对于高并发的系统来说,本地缓存会导致应用程序可用的内存下降,这无疑会导致应用程序的服务器更容易出现瓶颈,并不符合我们提高系统性能的目的。所以,我们更愿意选择分布式缓存。

分布式缓存常用的中间件有Redis和Memecachee,我们将读取比较频繁,但是变化不是特别频繁的数据放在缓存之中,不让这部分读的请求穿透到数据库中,就能够有效地减少数据库读的IO次数。而缓存其实是会被常驻在内存之中,读取缓存并不会导致磁盘额IO,并发能力是非常高的。使用缓存,我们系统的并发能力也就能够得到非常可观的提升。

当然,缓存并不能解决所有的问题,因为数据库的IO瓶颈并不一定全部都是读,写也一样会产生IO。而缓存只能解决读IO所产生的问题,让用户去读缓存,但是写的情况一样会穿透到数据库中。

如果解决写的高并发呢?

写的高并发分成了很多种情况,一种是写的总请求数量其实并不高,但是主要集中在某一个时段,所以会导致这个时间的资源占用瞬间提高,但是服务器资源的整体利用率却并不高。例如:秒杀场景。

还有一种情况是些的总请求数量特别高,让数据库的服务器资源占用情况非常高,导致系统的效率下降。例如:双11当天下单。

如果是特定时段的写请求高并发,最好的解决方案是使用队列(例如:RabbitMQ)。我们把写的请求放到队列里面,返回给用户一个成功但需等待的消息,然后让队列慢慢的处理。这样,我们的数据库压力其实是被队列中间件分担了,数据库我们可以根据资源的情况,多线程的对队列里的消息进行消费,这样写的请求就被控制在了一个安全线内。

如果我们的写请求一直都很高,那么队列其实并不能解决数据库的问题,反而会导致队列中效率的堆积,影响系统效率。那么我们就必须换一个方式,那么分库分表就是一个解决写瓶颈的有效方式了。

将数据平均的插入到两个不同的数据库中,让单个数据库的写IO降低一半,这样,我们的数据库效率就能够有效的被提高了。当然,数据库分库以后会存在很多的排序分页的问题,这个又是一个新的问题,我这里就不多说了。

最后在说一下一个架构理念吧

我们在做架构设计的时候,尽量要考虑请求的过滤,不要把所有的请求全部都最终落到数据库上,这样我们的数据库就非常容易发生问题,导致整个系统崩溃。我们可以在前端、接口都考虑一下请求的过滤问题,减轻数据库的负担。也就是说,我们的请求最终会形成一个漏斗。

例如:前端需要考虑用户如果重复多次的点击一个按钮,我们不要次次都回到接口中甚至回到数据库中,尽量使用前端的通过有效的方式能够过滤一部分情况。

而在接口中也是一样,能够查询缓存的数据,就不要去查数据库了,效率也高,系统也高。

当然,对于高并发来说,还有太多太多可以谈的,这些都只是一些相对基础的知识。也欢迎大家更多的提出自己的经验,大家相互学习。

一个系统在用户多,高并发的情况下,数据库该如何设计?

高并发的情况下,对于系统各个方面都有一定的要求,单从数据库层面主要有以下几点:

1、读写分离

高并发的场景读写分离是第一要做的。一般的系统都是读的频率要远远大于写的频率。所以我们将读写分开,从库读,主库写,一主多从,根据qps和iops大小再进行扩容调整。

2、分库分表

分库分表的目的在于降低单个表的数据量,提升查询效率。主要有横向拆分和纵向拆分。横向就是把一张表的数据分到不同的库或表,每张表的数据结构一样。纵向就是把一张宽表拆分成小表。例如,一张表有50个字段,可以将常用的字段放到一张表,不常用的放到另一张表。

3、索引

索引是必须要的。针对查询条的不同,建立相关索引,可以极大的提升查询效率。

最后,我们加入缓存、优化sql、优化业务逻辑,目的就是尽可能的减少操作数据库的次数,降低iops。

一个系统在用户多,高并发的情况下,数据库该如何设计?

数据库建立多表关联,关键业务数据字段和查询字段建立索引,对唯一性建立好,同时多任务并发时程序设计时注意数据的合理性检验和用户处理数据有问题时的友好提示见面,建立好的结构文档说明,同时对关键字段的关系型作好记录,有效地设计多表的结构安排,尽量减少数据的冗余,同时又要避免对历史数据的影响,保持良好的数据管理

一个系统在用户多,高并发的情况下,数据库该如何设计?

在多用户,高并发的业务场景下,传统关系型数据库i/o往往成为系统瓶颈,如上面几位的回答,这种情况下首先应该考虑减少对数据库的直接访问,常见的方法有使用缓存(包括客户端缓存,前端缓存以及服务器缓存,和CDN等),使用消息队列异步化数据库读写进行削峰等。其次我们应该优化对数据库的访问,使数据库能承受更高的qps,主要方法有优化重写查询语句,数据库读写分离,分表分库,以及对非事务型访问考虑使用nosql等。

留言与评论(共有 0 条评论)
   
验证码:
Top